From: vy
Subject: Documentation of a Specific Method
Date: 
Message-ID: <1182457895.813814.303480@q75g2000hsh.googlegroups.com>
Hi,

How can I assign a docstring to a _specific_ method (not a function!)
via (setf (documentation ...) ...). Also, is it possible to reach the
documentation string of a specific method?

I want to assign dynamic (not a constant string) docstring to a method
in a macro. I tried to figure out a solution on my own with no luck.
For instance, here's one of my failed attempts:

CL-USER> (defmacro foo-mak (bar-key)
           (with-gensyms (bar-str)
             `(let ((,bar-str (symbol-name ,bar-key)))
                (defmethod foo ((bar (eql ,bar-key)))
                  #.(format nil "~a called foo-mak" ,bar-str)
                  t))))
; The value BAR-STR is not of type LIST.

Does anybody have an idea about how to fix above macro?


Regards.

From: Rainer Joswig
Subject: Re: Documentation of a Specific Method
Date: 
Message-ID: <joswig-ACB424.22533021062007@news-europe.giganews.com>
In article <························@q75g2000hsh.googlegroups.com>,
 vy <·············@gmail.com> wrote:

> Hi,
> 
> How can I assign a docstring to a _specific_ method (not a function!)
> via (setf (documentation ...) ...). Also, is it possible to reach the
> documentation string of a specific method?
> 
> I want to assign dynamic (not a constant string) docstring to a method
> in a macro. I tried to figure out a solution on my own with no luck.
> For instance, here's one of my failed attempts:
> 
> CL-USER> (defmacro foo-mak (bar-key)
>            (with-gensyms (bar-str)
>              `(let ((,bar-str (symbol-name ,bar-key)))
>                 (defmethod foo ((bar (eql ,bar-key)))
>                   #.(format nil "~a called foo-mak" ,bar-str)
>                   t))))
> ; The value BAR-STR is not of type LIST.
> 
> Does anybody have an idea about how to fix above macro?
> 
> 
> Regards.

(defmacro foo-mak (bar-key)
  `(defmethod foo ((bar (eql ,bar-key)))
     ,(format nil "~a called foo-mak" bar-key)
     t))

CL-USER 4 > (macroexpand-1 '(foo-mak 'baz))
(DEFMETHOD FOO ((BAR (EQL BAZ))) "BAZ called foo-mak" T)

Check out whether you want BAZ quoted or not in the expansion.

-- 
http://lispm.dyndns.org
From: vy
Subject: Re: Documentation of a Specific Method
Date: 
Message-ID: <1182460505.342110.190720@o61g2000hsh.googlegroups.com>
On Jun 21, 11:53 pm, Rainer Joswig <······@lisp.de> wrote:
> (defmacro foo-mak (bar-key)
>   `(defmethod foo ((bar (eql ,bar-key)))
>      ,(format nil "~a called foo-mak" bar-key)
>      t))

Actually, I had first started with using an identical solution. But
consider this:

(defmacro foo-mak (bar-key)
  (with-gensyms (bar-str)
    `(let ((,bar-str (symbol-name ,bar-key)))
        (defmethod foo ((bar (eql ,bar-key))
          ,(format nil "~a called foo-mak" bar-str)))))

C-c C-m (foo-mak :baz) =>
(LET ((#:BAR-STR2496 (SYMBOL-NAME :BAZ)))
  (DEFMETHOD FOO ((BAR (EQL :BAZ)) "BAR-STR2496 called foo-mak")))

Or another whacky snippet:

(defmacro foo-mak (bar)
  `(defmethod foo ((bar (eql ,bar)))
     ,(format nil "~a [By FOO-MAK]" bar)))

C-c C-m (foo-mak :baz) =>
(DEFMETHOD FOO ((BAR (EQL :BAZ))) "BAZ [By FOO-MAK]")

So far so good. Let's try this in a loop: (In my real case problem, I
need to use the macro in a loop.)

(loop for item in
(list :foo :bar :baz)
      do (foo-mak item))

Guess (FOO-MAK ITEM) macroexpands to what?
From: Rainer Joswig
Subject: Re: Documentation of a Specific Method
Date: 
Message-ID: <joswig-F0421F.00253422062007@news-europe.giganews.com>
In article <························@o61g2000hsh.googlegroups.com>,
 vy <·············@gmail.com> wrote:

> On Jun 21, 11:53 pm, Rainer Joswig <······@lisp.de> wrote:
> > (defmacro foo-mak (bar-key)
> >   `(defmethod foo ((bar (eql ,bar-key)))
> >      ,(format nil "~a called foo-mak" bar-key)
> >      t))
> 
> Actually, I had first started with using an identical solution. But
> consider this:
> 
> (defmacro foo-mak (bar-key)
>   (with-gensyms (bar-str)
>     `(let ((,bar-str (symbol-name ,bar-key)))
>         (defmethod foo ((bar (eql ,bar-key))
>           ,(format nil "~a called foo-mak" bar-str)))))
> 
> C-c C-m (foo-mak :baz) =>
> (LET ((#:BAR-STR2496 (SYMBOL-NAME :BAZ)))
>   (DEFMETHOD FOO ((BAR (EQL :BAZ)) "BAR-STR2496 called foo-mak")))
> 
> Or another whacky snippet:
> 
> (defmacro foo-mak (bar)
>   `(defmethod foo ((bar (eql ,bar)))
>      ,(format nil "~a [By FOO-MAK]" bar)))
> 
> C-c C-m (foo-mak :baz) =>
> (DEFMETHOD FOO ((BAR (EQL :BAZ))) "BAZ [By FOO-MAK]")
> 
> So far so good. Let's try this in a loop: (In my real case problem, I
> need to use the macro in a loop.)
> 
> (loop for item in
> (list :foo :bar :baz)
>       do (foo-mak item))
> 
> Guess (FOO-MAK ITEM) macroexpands to what?

I don't need to guess. That's a common pitfall.

The macro gets statically expanded at compile time
and it expects certain data to be present.
But you want to put in some data at runtime, where
the macro expansion doesn't allow it.

See

  (let ((item 'baz))
     (eval (list 'foo-mak item)))


a) If you know your list of items at compile time,
   then you can write a macro that expand into a
   form with multiple DEFMETHODs.

b) If you know your items only at runtime, you can do the
   above and evaluate it. Or you can evaluate indivdual
   macro invocations.

c) If you know a protocol below the macros,
   then you can call that. For methods this can
   be done by the MOP (if provided by your Lisp):
   http://www.lisp.org/mop/concepts.html#defmethod

-- 
http://lispm.dyndns.org