[Openmcl-devel] CCL <-> C++ interface generator in alpha, reviewers wanted

Daniel Herring dherring at tentpost.com
Sat Apr 9 10:19:36 PDT 2011

On Fri, 8 Apr 2011, Jason E. Aten wrote:
> This seems to provide a very general method. Unless I hear any additional suggestions (which I would be glad to incorporate), I'll make this method the default for wrapping C++ objects with SWIG in the CFFI module.
> ;; CL                                                                                                                                                                           
> (defstruct S a )
> (defgeneric f_1 (s x)
>  (:method ((s S) (x integer)) "method f_1: (s S) (x integer)")
>  (:method ((s S) (x float))   "method f_1: (s S) (x float)"))
> (defgeneric f_2 (s x y)
>  (:method ((s S) (x integer) (y float)) "method f_2 (s S) (x interger) (y float)"))
> (declaim (inline f))
> (defun f (&rest args)
>  "arity dispatch for S::f in C++"
>  (case (length args)
>    (0 (error "function/method f need an object an object to be applied to"))
>    (1 (error "function/method f takes at least 1 argument in addition to an object"))
>    (2 (apply #'f_1  args))
>    (3 (apply #'f_2  args))
>    (otherwise (error "too many arguments to function f"))))

A few points related to dispatch:

- f%1 may be a better name than f_1; the percent sign is often used as a 
convention to mark "implementation detail" symbols.

- The standard idiom for (case x ... (otherwise (error))) is (ecase x ...)

- CL/CLOS will already signal an error when an undefined/unspecialized 
function is invoked.  This includes arity and type errors.  Thus your 
error messages are not required and slightly nonstandard.

- If you do want to want to keep the custom arity errors, you probably 
need to rename f to S.f.  Otherwise there will be problems when class T 
defines T.f or there is a free function named f.  The subfunctions would 
then be S.f%1, ...

- CL/CLOS and C++ types do not have a 1-1 relationship.  There are times 
when the user will need to clarify which dispatch C++ should use.  This 
may require calling a slightly different function name or passing hints in 
extra parameters.

   - CFFI drops both S* and T* to :pointer (discarding class info)
   - should fixnum map to int16_t, int32_t, ... ?
   - Explicitly invoke a superclass function
     class C1 { virtual void f(); };
     class C2 : public C1 { void f() { ... C1::f(); ...} };

- See EQL for some good ideas on how to handle these situations.

- a related issue is the CL default readtable-case of :upcase


More information about the Openmcl-devel mailing list