Hacker News new | past | comments | ask | show | jobs | submit login

You can pass closures to C as C functions in TXR Lisp, a language I created.

Example:

http://rosettacode.org/wiki/Window_creation#Win32.2FWin64

In this program, a translation of Microsoft's "Your First Windows Program" from MSDN, defun is used to define a WindowsProc callback. defun generates a lambda under the hood, which carries a lexical scope.

The lambda is passed directly to Win32 as a callback, which is nicely called for repainting the window. (Or at least, things appear that way to the programmer.)

Setting this up requires a few steps. We need a target function, of course, which can be any callable object.

Then there is this incantation:

  (deffi-cb wndproc-fn LRESULT (HWND UINT LPARAM WPARAM))
The deffi-cb operator takes a name and some type specifications: return type and parameters. The name is defined as a function; so here we get a function called wndproc-fn. This function is a converter. If we pass it a Lisp function, it gives back a FFI closure object.

Then in the program, we instantiate this closure object, and stick it into the WNDPROC structure as required by the Windows API. Here we use the above wndproc-fn converter to obtain WindowProc in the shape of a FFI closure:

  (let* ((hInstance (GetModuleHandle nil))
         (wc (new WNDCLASS
                  lpfnWndProc [wndproc-fn WindowProc]
         ...
The lpfnWndProc member of the WNDCLASS FFI structure is defined as having the FFI type closure; that will correspond to a function pointer on the C side. The rest is just Windows:

  (RegisterClass wc)
 
register the class, and then CreateWindow with that class by name and so on.



Here is another example of callbacks at work from the TXR Lisp test suite: using the C library funtion qsort to sort a Lisp array of strings.

http://www.kylheku.com/cgit/txr/tree/tests/017/qsort.tl

It's done in two ways, as UTF-8 char * strings and as wchar_t * strings.

What's used as the callback is the function cmp-str which is in TXR Lisp's standard library. A lambda expression could be used instead.

Also tested is the perpetration of a non-local control transfer out of the callback, instead of the normal return. This properly cleans up the temporary memory allocated for the string conversions.


TXR looks interesting. Is there a project README?


There is a boring and poorly maintained home page: http://www.nongnu.org/txr.

And big honkin' manual.




Join us for AI Startup School this June 16-17 in San Francisco!

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: