[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