Hi,
While people certainly appreciate that CFFI provides callbacks (their current state in UFFI or Kenny Tilton's hello-c fork is unknown to me), I wonder why they apply to named functions only.
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?
Of course, typical C callbacks provide a void *data pointer, but I'd feel silly if I had to hide some Lisp object within such a pointer. Actually, I don't even know how to map an arbitrary Lisp object this way (it would need some awful int -> obj registration code)!
The pattern I'm looking for is (defun my-application (let (x y) ...code... (register-callback 'close-window #'(lambda (data event) (return-from my-application))) (register-callback 'increase-x #'(lambda (data event) (incf x (event->value event)))) (main-loop)))
Given the name limitation, I wonder whether the following work-around may be acceptable (using defcallback not at top-level). If yes, I believe the cffi manual should mention it explicitly. Otherwise, it might as well work only in N out of M implementations running cffi, and users would start to write unportable code without knowing.
(defun my-callback (closure) (flet foo (defcallback ... ; problem: name is nevertheless global ;; possibly as a macro & backquotes ...))) Or (defun my-application (let (x y) (flet ((quit (data event) (return-from my-application)) (inc (data event) (incf x (event->value event)))) (defcallback close ... :body (quit date event)) (register-callback 'close-window (callback close)))))
Possibly this needs a macro&backquote generator, because DEFCALLBACK registers the given name globally in a property list. Thus it disallows running multiple instances of the above. GENSYM might help, but wouldn't this be a kludge?
This is quite similar to the (often undocumented) ability to use typical top-level forms in lexical contexts (e.g. the FAQ: is DEFCLASS within a function call etc. possible or not, and what happens). Many libraries don't define the semantics of their macros precisely enough.
Regards, Jorg Hohle