-
Notifications
You must be signed in to change notification settings - Fork 112
FFI Design Discussions
I open this page to discuss the design of the FFI system.
A primitive function (oget <object> <property1> <property2> ...) is exposed. A base *root* variable designates the main object (which is established by the runtime).
On NodeJS it doesn't work properly though as there are some variables that are in the module scope but are not in global, but I think those are just a few and the NodeJS runtime can provide them as special cases.
On top of that, a #j macrocharacter is implemented so (#j:console:log "test") is read as ((oget *root* "console" "log") "test") which basically does the right thing.
#j: always work with the root object, which make it inconvenient to work with your own CL variables. You can't do
(defvar canvas (#j:document:querySelector "#canvas"))
(#j:canvas:getContext "2d") ; would be read as ((oget *root* "canvas" "getContext") "2d")- Make
#j:a:b:cexpand to(oget a "b" "c"). Then you can use*root*if you need to or it could be provided by the shortcut#j::a:b(oget root "a" "b"). I don't like the first argument being different but not the syntax. Perhaps its hould be(#j/a:b:c)instead??
oget converts between JS and Lisp values automatically. Sometimes we do not want this, how should we disable this? Another variant of #j:: or #j/? A special variable *convert-ffi-values*? My concern with the latter is that special variables could not play well with async code.