[cffi-devel] Extending defcfun and friends with extra options

Luís Oliveira luismbo at gmail.com
Tue Jan 30 07:52:37 UTC 2007


Hello,

There are a couple of features people need -- namely stdcall and dll
namespaces -- that depend on the ability to pass options to defcfun,
foreign-funcall and defcallback. So we need to agree on a proper
syntax to do this. Bonus points if we can get backwards compatibility.

This has been discussed in the past regarding defcfun but I forget
what the conclusions were. Anyway, starting with the easiest:

  (defcallback (foo :opt1 ... :opt2 ...) :rettype ((arg1 :type1) ...)
     body)

That seems to be the obvious place to put the options for defcallback.
Any objections? defcfun, however, has some more possibilities:

  ;; #1 -- backwards compatible, similar to defcallback
  (defcfun (foo :opt1 ... :opt2 ...) :rettype
    (arg1 :type1)
    (arg2 :type2))

  ;; #2 -- backwards compatible, slightly funky syntax IMHO
  (defcfun foo :rettype
    (arg1 :type1)
    (arg2 :type2)
    :opt1 ...
    :opt2 ...)

  ;; #3 -- not backwards compatible, indentation looks odd when
  ;; there are no options present
  (defcfun foo :rettype
      ((arg1 :type1)
       (arg2 :type2))
    :opt1 ...
    :opt2 ...)


IIRC, I used to be prefer option #3 because that way we could cleanly
define the keyword arguments in the defcfun macro but lately I'm more
inclined towards #1 since it indents better and the syntax is similar
to defcallback. Also, #1 is backwards compatible; that's a plus, I
guess. I think James used to prefer option #2. Is that still true? I
don't completely dislike option #2.

And finally there's foreign-funcall. The syntax here should be pretty
obvious too:

  (foreign-funcall ("foo" :opt1 ... :opt2 ...) :type1 arg1 :type2 arg2 :rettype)

Except foreign-funcall also accepts a pointer, and in that case the
first argument is evaluated (unlike the case where the argument is a
string). I think
  (foreign-funcall ((some-form ...) :opt1 ... :opt2 ...) :type1 arg1
... :rettype)
looks a bit odd. Does that justify splitting such functionality off to
another macro foreign-funcall-pointer with a different syntax? I think
I'd rather avoid that.

Oh, and we need options for define-foreign-library too. Once again I'm
thinking we should place the options in the name argument:
(define-foreign-library (name :opt1 ... :opt2 ...) ...).

Comments and suggestions are most welcome.

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/



More information about the cffi-devel mailing list