"vasilism" <········@sch.gr> writes:
> The question is how to map c++ overloaded methods
> so i will be able to do
> [...]
> is there a more efficient way? (without calling length, format,
> intern, symbol-function, fboundp at runtime)
Since you're trying to map one language to the other, you 're wanting
to upgrade the lisp language. So you're wanting a macro. Another
hint is that you're complaining about something done at
_run-time_. Let's do it at macro-expansion time instead!
[4]> (cat "variadic-methods.lisp")
(defclass <foo> () ())
(defmethod .test-1 ((self <foo>) (arg0 integer))
(print "... call CSharp_Foo_test__SWIG_0"))
(defmethod .test-1 ((self <foo>) (arg0 character))
(print "... call CSharp_Foo_test__SWIG_1"))
(defmethod .test-2 ((self <foo>) (arg0 integer) (arg1 character))
(print "... call CSharp_Foo_test__SWIG_2"))
(defmacro .test (self &rest arguments)
(case (length arguments)
(0 (error "Not enough arguments for ~A." '.TEST))
(1 `(.test-1 ,self ,@arguments))
(2 `(.test-2 ,self ,@arguments))
(otherwise (error "Too many arguments for ~A." '.TEST))))
(let ((foo (make-instance '<foo>)))
(.test foo 1)
(.test foo #\a)
(.test foo 1 #\a)
(.test foo 1 2 3))
[5]> (load"variadic-methods.lisp")
;; Loading file variadic-methods.lisp ...
"... call CSharp_Foo_test__SWIG_0"
"... call CSharp_Foo_test__SWIG_1"
"... call CSharp_Foo_test__SWIG_2"
*** - Too many arguments for .TEST.
Of course, you won't be writting the various .TEST macros yourself,
you'll write a macro to generate them from the Swig output.
--
__Pascal Bourguignon__ http://www.informatimago.com/
You never feed me.
Perhaps I'll sleep on your face.
That will sure show you.
From: vasilism
Subject: Re: Q: CLOS and C++ overloaded methods.
Date:
Message-ID: <4270a0f1$1@news.sch.gr>
Pascal Bourguignon <···@informatimago.com> wrote:
>Since you're trying to map one language to the other, you 're wanting
>to upgrade the lisp language. So you're wanting a macro.
>(defmacro .test (self &rest arguments)
> (case (length arguments)
> (0 (error "Not enough arguments for ~A." '.TEST))
> (1 `(.test-1 ,self ,@arguments))
> (2 `(.test-2 ,self ,@arguments))
> (otherwise (error "Too many arguments for ~A." '.TEST))))
>
Pascal Bourguignon <···@informatimago.com> wrote:
>Since you're trying to map one language to the other, you 're wanting
>to upgrade the lisp language. So you're wanting a macro.
>(defmacro .test (self &rest arguments)
> (case (length arguments)
> (0 (error "Not enough arguments for ~A." '.TEST))
> (1 `(.test-1 ,self ,@arguments))
> (2 `(.test-2 ,self ,@arguments))
> (otherwise (error "Too many arguments for ~A." '.TEST))))
>
This is ok for the simple case but there is a problem when you have
class Foo {
public:
Foo() { };
~Foo() {};
int intvar = 10;
void test(int i);
void test(char c);
void test(int i, char c);
}
class Boo : public Foo {
public:
void test(double d);
}
you can't redefine macro .test
For this case i will be able to do
(let ((boo (make-instance '<boo>)))
(.test boo 10) ;; call base class <foo> .test method
(.test boo 12d0)) ;; call <boo> .test method
From: [Invalid-From-Line]
Subject: Re: Q: CLOS and C++ overloaded methods.
Date:
Message-ID: <4270adc7@news.sch.gr>
"vasilism" <········@sch.gr> wrote:
>This is ok for the simple case but there is a problem when you have
>
>you can't redefine macro .test
>
With a second thought macro aproach seems ok.
(defmacro .test (self &rest arguments)
(let ((fname (intern (format nil ".TEST-~d" (length arguments)))))
`(,fname ,self ,@arguments)))
(defclass <foo> () ())
(defmethod .test-1 ((self <foo>) (arg0 integer))
(print `(<foo> .test-1 integer))))
(defmethod .test-1 ((self <foo>) (arg0 character))
(print `(<foo> .test-1 character)))
(defmethod .test-2 ((self <foo>) (arg0 integer) (arg1 character))
(print `(<foo> .test-2 integer character)))
(defclass <boo> (<foo>) ())
(defmethod .test-1 ((self <boo>) (arg0 float))
(print `(<boo> .test-1 float)))
(defmethod .test-3 ((self <boo>) (arg0 integer) (arg1 character) (arg2 float))
(print `(<boo> .test-3 integer character float)))
(let ((boo (make-instance '<boo>)))
(.test boo 10)
(.test boo #\a)
(.test boo 10 #\a)
(.test boo 12d0)
(.test boo 10 #\a 12d0))
(<FOO> .TEST-1 INTEGER)
(<FOO> .TEST-1 CHARACTER)
(<FOO> .TEST-2 INTEGER CHARACTER)
(<BOO> .TEST-1 FLOAT)
(<BOO> .TEST-3 INTEGER CHARACTER FLOAT)
am i missing something?
On 28 Apr 2005 11:38:09 +0300, vasilism wrote:
> Pascal Bourguignon <···@informatimago.com> wrote:
>> Since you're trying to map one language to the other, you 're wanting
>> to upgrade the lisp language. So you're wanting a macro.
>> (defmacro .test (self &rest arguments)
>> (case (length arguments)
>> (0 (error "Not enough arguments for ~A." '.TEST))
>> (1 `(.test-1 ,self ,@arguments))
>> (2 `(.test-2 ,self ,@arguments))
>> (otherwise (error "Too many arguments for ~A." '.TEST))))
>>
> This is ok for the simple case but there is a problem when you have
> class Foo {
> public:
> Foo() { };
> ~Foo() {};
> int intvar = 10;
> void test(int i);
> void test(char c);
> void test(int i, char c);
> }
> class Boo : public Foo {
> public:
> void test(double d);
> }
> you can't redefine macro .test
> For this case i will be able to do
> (let ((boo (make-instance '<boo>)))
> (.test boo 10) ;; call base class <foo> .test method
> (.test boo 12d0)) ;; call <boo> .test method
You don't want to do that anyway. You can't pass macros around as
values and FUNCALL/APPLY them.
You might try something like:
(defclass overloaded-function (pcl:funcallable-standard-object)
((methods :initform '()))
(:metaclass pcl:funcallable-standard-class))
(defmacro defoverload ((class name) args &body body)
`(progn
(push (cons '(,class ,@(mapcar #'second args))
(lambda (this ,@(mapcar #'first args))
(declare (ignorable this))
,@body))
(slot-value #',name 'methods))
',name))
(defmethod run-appropriate-method ((fn overloaded-function) args)
(with-slots (methods) fn
(dolist (method methods)
(when (and (= (length (car method)) (length args))
(every #'typep args (car method)))
(return-from run-appropriate-method (apply (cdr method) args))))
(no-applicable-method fn args)))
(defmethod shared-initialize :after ((inst overloaded-function) slots
&rest initargs)
(declare (ignore slots initargs))
(pcl:set-funcallable-instance-function inst
(lambda (arg1 &rest args)
(run-appropriate-method inst (list* arg1 args)))))
[Hmm; this doesn't actually work in my CMUCL -- if I do the
set-funcallable-instance-function manually after making an instance,
it works fine, but putting it in shared-initialize causes some weird
error when the instance is called. Anybody know what's wrong?]
(setf (symbol-function 'test) (make-instance 'overloaded-function))
(defoverload (foo test) ((arg integer))
(print "Foo::test(int)"))
(defoverload (foo test) ((arg character))
(print "Foo::test(char)"))
(defoverload (foo test) ((arg1 integer) (arg2 character))
(print "Foo::test(int, char)"))
(defoverload (boo test) ((arg integer))
(print "Boo::test(int)"))
(test (make-instance 'foo) 10)
(test (make-instance 'boo) 10)
(test (make-instance 'foo) #\f)
(test (make-instance 'boo) #\f)
etc.
[I leave it to you to fix the order dependency, replace redefined
"methods" rather than just adding new ones, etc...]
--
" ... I told my doctor I got all the exercise I needed being a
pallbearer for all my friends who run and do exercises!"
-- Winston Churchill
(setq reply-to
(concatenate 'string "Paul Foley " "<mycroft" '(··@) "actrix.gen.nz>"))
From: [Invalid-From-Line]
Subject: Re: Q: CLOS and C++ overloaded methods.
Date:
Message-ID: <42713226$1@news.sch.gr>
Paul Foley <···@below.invalid> (http://public.xdi.org/=pf) wrote:
>You don't want to do that anyway. You can't pass macros around as
>values and FUNCALL/APPLY them.
>
>You might try something like:
>
> (defclass overloaded-function (pcl:funcallable-standard-object)
> ((methods :initform '()))
> (:metaclass pcl:funcallable-standard-class))
>
at my first post i map overloaded functions as stadard clos methods
what is the benefit of using mop?
Thanks for your response.