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

Jason E. Aten j.e.aten at gmail.com
Fri Apr 8 12:22:13 PDT 2011


On Fri, Apr 8, 2011 at 10:53 AM, <dherring at tentpost.com> wrote:

> Jon Anthony wrote:
> > Jason E. Aten wrote:
> > ;; Since Common Lisp doesn't support method overloading (apparently,
> > ;; please correct me if I've misunderstood the comments at the bottom of
> > ;; page 194 of Practical Common Lisp),
> >
> > See the lambda list keywords: optional, rest and key.  For this simple
> > example, optional looks like what you want.
>
> In CLOS, generic functions distinguish between required and optional
> keywords; dispatch only occurs on the required keywords.  (I feel I've
> misstated the details, but the gist is ok.)  Conceptually, all CLOS
> dispatch happens at runtime, like virtual functions in C++.  (CLOS
> implementations may leverage compile-time constants and type information
> to achieve static dispatch.)
>
> C++ static dispatch follows a different ruleset; it can distinguish
> between both the arity and type of arguments.  For virtual functions, C++
> runtime dispatch invokes a function implementation stored in the vtable of
> the first argument (left of the dot).
>
>
> Here's one approach for expressing C++ semantics in CL.  (Warning: Code
> typed over lunch and not tested.)
>
> // C++
> struct S
> {
>  virtual void f(int);
>  virtual void f(float);
>  virtual void f(int, float);
>  ...
> };
>
>
>
Excellent!  I was able to get this approach to work very cleanly!  Here is
the slightly cleaned and tested version of Daniel's outline.

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.

- Jason


;;
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"))))

(setf mys (make-instance 'S))

; test arity handling: these should
succeed.

(f mys 1)
(f mys 1.0)
(f mys 1 1.0)


; test arity error conditions too: these should
fail.

(f mys)
(f)
(f mys 1 1 1 )

;;; success! this all works. Thank you Daniel Herring.  right on!



? (setf mys (make-instance 'S))
#S(S :a nil)

? (f mys 1)
"method f_1: (s S) (x integer)"

? (f mys 1.0)
"method f_1: (s S) (x float)"

? (f mys 1 1.0)
"method f_2 (s S) (x interger) (y float)"

;;; and it gives errors when caller's arity is wrong: (Horray!)

? (f mys)
> Error: function/method f takes at least 1 argument in addition to an
object
> While executing: f, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.


1 > (f)
> Error: function/method f need an object an object to be applied to
> While executing: f, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.


2 > (f mys 1 1 1 )
> Error: too many arguments to function f
> While executing: f, in process listener(1).
> Type :POP to abort, :R for a list of available restarts.
> Type :? for other options.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.clozure.com/pipermail/openmcl-devel/attachments/20110408/d0d91843/attachment.htm>


More information about the Openmcl-devel mailing list