Jan Rychter | 1 Feb 2006 12:03
Gravatar

Re: Re: unnamed callback (closures?)

> >>>>> On Wed, 01 Feb 2006 09:46:27 +0100, Jan Rychter <jan <at> rychter.com> said:
> >>>>> "Luís" == Luís Oliveira <luismbo <at> gmail.com>:
> >  Luís> "Hoehle, Joerg-Cyril" <Joerg-Cyril.Hoehle <at> t-systems.com> writes:
> >  >> In CLISP, every closure can be turned into a callback, and this is
> >  >> valuable since it allows to retrieve context information out of the
> >  >> closure.  Is cffi's limitation caused by some implementations?
> > 
> >  Luís> To my knowledge, yes. AFAICT, only SBCL/x86 and CLISP support
> >  Luís> that.
> > 
> >  Luís> Regarding the behaviour of CFFI:DEFCALLBACK as a non-toplevel
> >  Luís> form, not only will it set it globally, the callback itself won't
> >  Luís> be generated at runtime on most Lisp, IIRC.
> > 
> > I've just ran into the same problem. I really really need closures as
> > callbacks. I've tried the naive approach:
> > 
> > (defmacro object-event-callback-add (obj type function)
> >   `(foreign-funcall "evas_object_event_callback_add"
> >     :pointer ,obj
> >     callback-type ,(foreign-enum-value 'callback-type type)
> >     :pointer (get-callback (defcallback ,(gensym "CB")
> >           :void
> >           ((data :pointer) (cb-e evas) (cb-obj object) (cb-event :pointer))
> >         (funcall ,function cb-e cb-obj cb-event)))
> >     :pointer (null-pointer)))
> > 
> > ... but that's a half-baked solution with too many limitations and only
> > works in a simple example that you run once.
> > 
(Continue reading)

Jan Rychter | 5 Feb 2006 14:41
Gravatar

Re: Re: unnamed callback (closures?)

I wrote:
> > >>>>> On Wed, 01 Feb 2006 09:46:27 +0100, Jan Rychter <jan <at> rychter.com> said:
> > >>>>> "Luís" == Luís Oliveira <luismbo <at> gmail.com>:
> > >  Luís> "Hoehle, Joerg-Cyril" <Joerg-Cyril.Hoehle <at> t-systems.com> writes:
> > >  >> In CLISP, every closure can be turned into a callback, and this is
> > >  >> valuable since it allows to retrieve context information out of the
> > >  >> closure.  Is cffi's limitation caused by some implementations?
> > > 
> > >  Luís> To my knowledge, yes. AFAICT, only SBCL/x86 and CLISP support
> > >  Luís> that.
> > > 
> > >  Luís> Regarding the behaviour of CFFI:DEFCALLBACK as a non-toplevel
> > >  Luís> form, not only will it set it globally, the callback itself won't
> > >  Luís> be generated at runtime on most Lisp, IIRC.
> > > 
> > > I've just ran into the same problem. I really really need closures as
> > > callbacks. I've tried the naive approach:
> > > 
> > > (defmacro object-event-callback-add (obj type function)
> > >   `(foreign-funcall "evas_object_event_callback_add"
> > >     :pointer ,obj
> > >     callback-type ,(foreign-enum-value 'callback-type type)
> > >     :pointer (get-callback (defcallback ,(gensym "CB")
> > >           :void
> > >           ((data :pointer) (cb-e evas) (cb-obj object) (cb-event :pointer))
> > >         (funcall ,function cb-e cb-obj cb-event)))
> > >     :pointer (null-pointer)))
> > > 
> > > ... but that's a half-baked solution with too many limitations and only
> > > works in a simple example that you run once.
(Continue reading)

Martin Simmons | 6 Feb 2006 16:56
Favicon

Re: Re: unnamed callback (closures?)

>>>>> On Sun, 05 Feb 2006 14:41:59 +0100, Jan Rychter <jan <at> rychter.com> said:
> Delivered-To: cffi-devel <at> common-lisp.net
> 
> I wrote:
> > > >>>>> On Wed, 01 Feb 2006 09:46:27 +0100, Jan Rychter <jan <at> rychter.com> said:
> > > >>>>> "Luís" == Luís Oliveira <luismbo <at> gmail.com>:
> > > >  Luís> "Hoehle, Joerg-Cyril" <Joerg-Cyril.Hoehle <at> t-systems.com> writes:
> > > >  >> In CLISP, every closure can be turned into a callback, and this is
> > > >  >> valuable since it allows to retrieve context information out of the
> > > >  >> closure.  Is cffi's limitation caused by some implementations?
> > > > 
> > > >  Luís> To my knowledge, yes. AFAICT, only SBCL/x86 and CLISP support
> > > >  Luís> that.
> > > > 
> > > >  Luís> Regarding the behaviour of CFFI:DEFCALLBACK as a non-toplevel
> > > >  Luís> form, not only will it set it globally, the callback itself won't
> > > >  Luís> be generated at runtime on most Lisp, IIRC.
> > > > 
> > > > I've just ran into the same problem. I really really need closures as
> > > > callbacks. I've tried the naive approach:
> > > > 
> > > > (defmacro object-event-callback-add (obj type function)
> > > >   `(foreign-funcall "evas_object_event_callback_add"
> > > >     :pointer ,obj
> > > >     callback-type ,(foreign-enum-value 'callback-type type)
> > > >     :pointer (get-callback (defcallback ,(gensym "CB")
> > > >           :void
> > > >           ((data :pointer) (cb-e evas) (cb-obj object) (cb-event :pointer))
> > > >         (funcall ,function cb-e cb-obj cb-event)))
> > > >     :pointer (null-pointer)))
(Continue reading)

Luís Oliveira | 5 Feb 2006 20:36
Picon
Gravatar

Re: unnamed callback (closures?)

Jan Rychter <jan <at> rychter.com> writes:
> Apart from a plea for suggestions, this brings me back to my original
> question -- can we expect any support for anonymous callbacks (closures
> as callback functions) in CFFI, at least on SBCL to begin with?

I'm pretty sure we could support anonymous callbacks, on SBCL and CLISP
anyway. Do any other Lisps support this?

--

-- 
Luís Oliveira
luismbo ( <at> ) gmail (.) com
Equipa Portuguesa do Translation Project
http://www.iro.umontreal.ca/translation/registry.cgi?team=pt
Jan Rychter | 5 Feb 2006 21:40
Gravatar

Re: Re: unnamed callback (closures?)

>>>>> "Luís" == Luís Oliveira <luismbo <at> gmail.com> writes:
 Luís> Jan Rychter <jan <at> rychter.com> writes:
 >> Apart from a plea for suggestions, this brings me back to my
 >> original question -- can we expect any support for anonymous
 >> callbacks (closures as callback functions) in CFFI, at least on SBCL
 >> to begin with?

 Luís> I'm pretty sure we could support anonymous callbacks, on SBCL and
 Luís> CLISP anyway. Do any other Lisps support this?

Quick googling of Lispworks and AllegroCL documentation seems to
indicate that in both cases one defines externally callable functions
with a macro. No mention of closures as callbacks. That would seem to
indicate that at least in these cases it isn't supported, but one would
have to ask the vendors to be sure.

ECL has si::make-dynamic-callback and would be able to support this, in
fact it seems that even defcallback expands to

[...]
          `(si::make-dynamic-callback
            #'(ext::lambda-block ,name ,arg-names , <at> body)
            ',name ',ret-type ',arg-types ,call-type)))
[...]

So, perhaps it is worth implementing as an optional feature. Hopefully
other implementations will follow suit.

--J.
(Continue reading)

James Bielman | 5 Feb 2006 23:14

Re: Re: unnamed callback (closures?)

Jan Rychter <jan <at> rychter.com> writes:

>>>>>> "Luís" == Luís Oliveira <luismbo <at> gmail.com> writes:
>  Luís> I'm pretty sure we could support anonymous callbacks, on SBCL and
>  Luís> CLISP anyway. Do any other Lisps support this?

> So, perhaps it is worth implementing as an optional feature. Hopefully
> other implementations will follow suit.

I took a shot at implementing this on SBCL and CLISP (I don't have a
working ECL installation), here's the patch:

Attachment (callback-lambda.patch): text/x-patch, 3003 bytes

This still needs unit tests but cursory testing from the REPL looks
good---please give it a try.

James
_______________________________________________
cffi-devel mailing list
cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Jan Rychter | 7 Feb 2006 09:51
Gravatar

Re: Re: unnamed callback (closures?)

>>>>> "James" == James Bielman <jamesjb <at> jamesjb.com> writes:
 James> Jan Rychter <jan <at> rychter.com> writes:
 >>>>>>> "Luís" == Luís Oliveira <luismbo <at> gmail.com> writes:
 >> Luís> I'm pretty sure we could support anonymous callbacks, on SBCL
 >> Luís> and CLISP anyway. Do any other Lisps support this?

 >> So, perhaps it is worth implementing as an optional
 >> feature. Hopefully other implementations will follow suit.

 James> I took a shot at implementing this on SBCL and CLISP (I don't
 James> have a working ECL installation), here's the patch:

 James> This still needs unit tests but cursory testing from the REPL
 James> looks good---please give it a try.

It works for me in SBCL. Neat, thanks!

However, I'm puzzled as to why you decided not to name the callback and
remember it. Is there really no way to release the memory occupied by
the trampoline code and let the closure be GCd when it's no longer
needed?

In my case, this is going to be a problem. If you generate a bunch of
callback-lambdas for each context menu appearance, you will soon end up
with lots of them in memory. If there really is no way to release them,
I'll probably have to think of a different approach (with dispatching
functions, I guess, as Martin suggested).

--J.
(Continue reading)

Jan Rychter | 16 Mar 2006 14:36
Gravatar

Re: Re: unnamed callback (closures?)

I wrote:
> >>>>> "James" == James Bielman <jamesjb <at> jamesjb.com> writes:
>  James> Jan Rychter <jan <at> rychter.com> writes:
>  >>>>>>> "Luís" == Luís Oliveira <luismbo <at> gmail.com> writes:
>  >> Luís> I'm pretty sure we could support anonymous callbacks, on SBCL
>  >> Luís> and CLISP anyway. Do any other Lisps support this?
> 
>  >> So, perhaps it is worth implementing as an optional
>  >> feature. Hopefully other implementations will follow suit.
> 
>  James> I took a shot at implementing this on SBCL and CLISP (I don't
>  James> have a working ECL installation), here's the patch:
> 
>  James> This still needs unit tests but cursory testing from the REPL
>  James> looks good---please give it a try.
> 
> It works for me in SBCL. Neat, thanks!

Are there plans for this to be included in CFFI? If not, why not?

--J.
James J Bielman | 7 Feb 2006 18:49

Re: Re: unnamed callback (closures?)


On Feb 7, 2006, at 12:51 AM, Jan Rychter wrote:
>
> However, I'm puzzled as to why you decided not to name the callback  
> and
> remember it. Is there really no way to release the memory occupied by
> the trampoline code and let the closure be GCd when it's no longer
> needed?
>
> In my case, this is going to be a problem. If you generate a bunch of
> callback-lambdas for each context menu appearance, you will soon  
> end up
> with lots of them in memory. If there really is no way to release  
> them,
> I'll probably have to think of a different approach (with dispatching
> functions, I guess, as Martin suggested).

Well, the idea was to also add an interface for freeing the callbacks
(if that is necessary on a particular Lisp), I just haven't gotten  
there yet.

I don't see how you could free them with finalizers since they won't
know about references held by foreign code.

James
Hoehle, Joerg-Cyril | 1 Feb 2006 18:30
Favicon

Re: unnamed callback (closures?)

Jan Rychter wrote:
>> What are the problems with unnamed callbacks? My guess was that they
>> will never get garbage-collected, but how about storing all 
>of these in
>> a table somewhere and explicitly freeing them after they are 
>no longer
>> needed? In my case I do have a way of finding out when a 
>callback is no
>> longer needed, and I suspect this is the case for many other
>> applications.

Martin Simmons wrote:
>The function evas_object_event_callback_add already makes a 
>closure -- on the C side.

Good observation.  So maybe, if CFFI will not provide an unnamed callback API via #+cffi-features:xyz,
maybe it could encapsulate this into a pattern and provide that?

The pattern is that many callbacks (AFAIK, all GUI callbacks), provide some void* data thing that can be
used as an indexing scheme as Martin Simmons from Lispworks describes (coincidentally IIRC, Allegro's
documentation also mentions indices somewhere, and if you dig into CLISP, you'll find some to :) That
could be put to use, together with a CFFI API for freeing the indices & callbacks.

The one true callback would be a CFFI-internal one, named, which dispatches to registered closures.
In fact one would need a family of such named callbacks, presumably one per function signature (e.g.
cb(void*data,int,xyz*) etc. -- Uh oh.
So there's maybe a need for a callback generator (macro writing macro). 
But possibly only one per GUI toolkit :-)

Beside that, cffi-features:no-lambda-callback might be an independent API to add (together with a means
(Continue reading)


Gmane