[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.lisp

How to handle external memory in CL - RAII?

Malice

6/12/2016 12:07:00 AM

I have a little C++ background. There's a really nice thing in C++ that's called RAII: http://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initializ...

Essentially, you can create a class, and at the end of the scope each instance of the class is destructed in strictly specified order. This means that you can define class that wraps something that you need to clean up, and it will clean it up by itself when it's no longer needed.

Now I'm playing with SDL in Common Lisp. There's a macro, called with-window. This macro makes sure that window will be cleaned up by special function that does this. Is there some way to ensure that some "destructor" will be called when the variable goes out of the scope?

My motivation is that I want to make sure, that some things are used as they should be. I could use macro, but is there other way of achieving that, since user could bypass macro and use things on his own(or simply don't notice the macro)?
11 Answers

Paul Rubin

6/12/2016 12:16:00 AM

0

Malice <gwmaniak@gmail.com> writes:
> I have a little C++ background. There's a really nice thing in C++
> that's called RAII...

The Lisp equivalent to that is called unwind-protect.

Malice

6/12/2016 12:41:00 PM

0

On Sunday, 12 June 2016 02:15:35 UTC+2, Paul Rubin wrote:
> The Lisp equivalent to that is called unwind-protect.


I am aware of unwind-protect. The thing is, you need to call it explicitly, or make a macro that will use it - otherwise you still lose. In C++, if you use RAII, then destructor takes care of memory and there's no way to prevent that from happening.

What you're suggesting resembles try...catch approach.

Pascal J. Bourguignon

6/12/2016 1:21:00 PM

0

Malice <gwmaniak@gmail.com> writes:

> On Sunday, 12 June 2016 02:15:35 UTC+2, Paul Rubin wrote:
>> The Lisp equivalent to that is called unwind-protect.
>
>
> I am aware of unwind-protect. The thing is, you need to call it
> explicitly, or make a macro that will use it - otherwise you still
> lose. In C++, if you use RAII, then destructor takes care of memory
> and there's no way to prevent that from happening.

That sounds like a problem if there's no way to prevent that from
happeningâ?¦


> What you're suggesting resembles try...catch approach.

--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Paul Wallich

6/12/2016 2:37:00 PM

0

On 6/12/16 8:40 AM, Malice wrote:
> On Sunday, 12 June 2016 02:15:35 UTC+2, Paul Rubin wrote:
>> The Lisp equivalent to that is called unwind-protect.
>
>
> I am aware of unwind-protect. The thing is, you need to call it explicitly, or make a macro that will use it - otherwise you still lose. In C++, if you use RAII, then destructor takes care of memory and there's no way to prevent that from happening.

It sounds as if you have the same issues, just in different places. In
C++, a programmer could build their own infrastructure that didn't
employ RAII, and they would face the same issues as a Lisp programmer
who didn't use a with- form or an explicit unwind-protect. (If you
really wanted belt and suspenders, you could build a framework that
checked for unprotected use of the things would wanted to be accessed
only within a with- or unwind-protect, but since at that point you're
trying to protect against deliberate stupidity it's unlikely to be
completely successful.)

paul

Kaz Kylheku

6/12/2016 3:17:00 PM

0

On 2016-06-12, Malice <gwmaniak@gmail.com> wrote:
> On Sunday, 12 June 2016 02:15:35 UTC+2, Paul Rubin wrote:
>> The Lisp equivalent to that is called unwind-protect.
>
>
> I am aware of unwind-protect. The thing is, you need to call it
> explicitly, or make a macro that will use it - otherwise you still
> lose.
>
> In C++, if you use RAII, then destructor takes care of memory
> and there's no way to prevent that from happening.

Except, of course, not using RAII.

Barry Margolin

6/13/2016 1:13:00 AM

0

In article <db797032-25b0-4587-a4dd-c71bb1ce4e45@googlegroups.com>,
Malice <gwmaniak@gmail.com> wrote:

> On Sunday, 12 June 2016 02:15:35 UTC+2, Paul Rubin wrote:
> > The Lisp equivalent to that is called unwind-protect.
>
>
> I am aware of unwind-protect. The thing is, you need to call it explicitly,
> or make a macro that will use it - otherwise you still lose

Which is precisely what the with-window macro you mentioned does.

RAII always seemed to be C++'s way to shoehorn what all the WITH-xxx
macros do into its paradigm. Since it's not really feasible to write
wrapping macros in C/C++, they came up with this kludge using
constructors and destructors.

But I'm sure C++ afficionados would say that UNWIND-PROTECT is the
kludge.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

ram

6/13/2016 10:28:00 AM

0

Barry Margolin <barmar@alum.mit.edu> writes:
>RAII always seemed to be C++'s way to shoehorn what all the WITH-xxx
>macros do into its paradigm. Since it's not really feasible to write
>wrapping macros in C/C++, they came up with this kludge using
>constructors and destructors.

Many well-known languages have variables that pertain to a
block or procedure. For example Pascal, Algol, C and Java
have this feature: A local int variable outside of object-
oriented programming will deallocate its storage upon block
exit.

With RAII, the same now also holds true for variables of
a user-defined type in object-oriented programming. For
example, a string variable might /allocate/ both stack
and heap memory (a resource) when its block is entered.
So it's only natural (following the lead of int variables)
when the string variable /deallocates/ its memory (stack
/and/ heap) upon block exit. And since there is no reason
to treat other kinds of resources different than heap,
it is only natural (i. e., not a kludge) to deallocate
(release) them upon block exit, too.

Pascal J. Bourguignon

6/13/2016 5:39:00 PM

0

ram@zedat.fu-berlin.de (Stefan Ram) writes:

> Barry Margolin <barmar@alum.mit.edu> writes:
>>RAII always seemed to be C++'s way to shoehorn what all the WITH-xxx
>>macros do into its paradigm. Since it's not really feasible to write
>>wrapping macros in C/C++, they came up with this kludge using
>>constructors and destructors.
>
> Many well-known languages have variables that pertain to a
> block or procedure. For example Pascal, Algol, C and Java
> have this feature: A local int variable outside of object-
> oriented programming will deallocate its storage upon block
> exit.

Indeed.

And in CL we have LET for that.

Upon completion, LET will automatically unwind dynamic bindings, will
automatically free the memory used by lexical bindings, and will
automatically drop the references to the objects so that they may be
garbage collected.

If you want to have onter RAII semantics, (eg. external memory), then if
you just need to implement a variant of LET. It just happens that in CL
most of the LET variants are called WITH-. The name nonwithstanding,
they are just LET macros, establishing variable bindings, and with
additionnal specific RAII semantics.

So we just told you to use a WITH- macro half a dozen time. Your choice
is now to just do it, or go back writing C++ code.

--
__Pascal Bourguignon__ http://www.informat...
â??The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.� -- Carl Bass CEO Autodesk

Barry Margolin

6/13/2016 6:09:00 PM

0

In article <RAI-20160613112006@ram.dialup.fu-berlin.de>,
ram@zedat.fu-berlin.de (Stefan Ram) wrote:

> Barry Margolin <barmar@alum.mit.edu> writes:
> >RAII always seemed to be C++'s way to shoehorn what all the WITH-xxx
> >macros do into its paradigm. Since it's not really feasible to write
> >wrapping macros in C/C++, they came up with this kludge using
> >constructors and destructors.
>
> Many well-known languages have variables that pertain to a
> block or procedure. For example Pascal, Algol, C and Java
> have this feature: A local int variable outside of object-
> oriented programming will deallocate its storage upon block
> exit.

There's a difference between releasing a variable binding and undoing
all the external changes that were made when the variable was
initialized. The problem with RAII is that it couples the two notions.

--
Barry Margolin, barmar@alum.mit.edu
Arlington, MA
*** PLEASE post questions in newsgroups, not directly to me ***

Elias Mårtenson

6/14/2016 11:34:00 PM

0

On Sunday, 12 June 2016 08:07:24 UTC+8, Malice wrote:

> I have a little C++ background. There's a really nice thing in C++ that's called RAII: http://stackoverflow.com/questions/2321511/what-is-meant-by-resource-acquisition-is-initializ...

People have mentioned WITH-macros, which is the best way of handling this, and the way most libraries that use CFFI to integrate with C libraries use.

There is another, nonstandard, solution which is to use finaliser functions.. It allows you to have a function called when an object gets garbage collected. For certain native resources, this is an appropriate solution. However, for many reasons, it should only be used when other solutions are not appropriate.

The library TRIVIAL-GARBAGE provides a generic interface to this functionality on most Common Lisp implementations.

As an example where I've used it with good results in in CL-GSS. Here's the specific code that handles this. It ensures that the native resources for a GSSAPI name object is released once the wrapper object is GC'ed: https://github.com/lokedhs/cl-gss/blob/master/src/cl-gs...