From: Pascal Bourguignon
Subject: Re: Q: CLOS and C++ overloaded methods.
Date: 
Message-ID: <871x8vn51r.fsf@thalassa.informatimago.com>
"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?
From: Pascal Bourguignon
Subject: Re: Q: CLOS and C++ overloaded methods.
Date: 
Message-ID: <87wtqnjkah.fsf@thalassa.informatimago.com>
<········@sch.gr> writes:

> "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?

No, it's ok.


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
In deep sleep hear sound,
Cat vomit hairball somewhere.
Will find in morning.
From: http://public.xdi.org/=pf
Subject: Re: Q: CLOS and C++ overloaded methods.
Date: 
Message-ID: <m24qdq3g3d.fsf@mycroft.actrix.gen.nz>
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.