From: ··········@eudoramail.com
Subject: no-next-method
Date: 
Message-ID: <1139757575.645588.174740@g43g2000cwa.googlegroups.com>
I have a question about using the no-next-method generic function.  I
know about next-method-p and I understand how no-next-method should be
used, but I am unsure about how to create methods on no-next-method.
Let's say that I do this (my explanation is at the end):

CL-USER 1 > (defgeneric foo (x y))
#<STANDARD-GENERIC-FUNCTION FOO 2150CB5A>

CL-USER 2 > (defmethod foo ((x integer) (y integer))
              (format t "~&Foo called. Integer specialization.")
              (call-next-method))
#<STANDARD-METHOD FOO NIL (INTEGER INTEGER) 2066987C>

CL-USER 4 > (defmethod foo ((x rational) (y rational))
              (format t "~&Foo called. Rational specialization.")
              (call-next-method))
#<STANDARD-METHOD FOO NIL (RATIONAL RATIONAL) 2066AE64>

CL-USER 5 > (defmethod foo ((x t) (y t))
              (format t "~&Foo called. T specialization.")
              (call-next-method))
#<STANDARD-METHOD FOO NIL (T T) 2067371C>

CL-USER 6 > (foo 4 2) ;; This will cause an error.
Foo called. Integer specialization.
Foo called. Rational specialization.
Foo called. T specialization.
Error: No next method for  #<STANDARD-METHOD FOO NIL (T T) 2067371C> of
generic function #<STANDARD-GENERIC-FUNCTION FOO 2150CB5A>  with args
(4 2)
  1 (abort) Return to level 0.
  2 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other
options

CL-USER 7 : 1 > :top

;;;  I define a method on no-next-method

CL-USER 8 > (defmethod no-next-method ((foo-fn
standard-generic-function) (foo-method standard-method) &rest args)
              (format t "~&No next method for foo."))

Error: Defining method #<STANDARD-METHOD NO-NEXT-METHOD NIL
(STANDARD-GENERIC-FUNCTION STANDARD-METHOD) 20678DAC> visible from
package COMMON-LISP.
  1 (continue) Define it anyway.
  2 Discard the new method.
  3 (abort) Return to level 0.
  4 Return to top loop level 0.

Type :b for backtrace, :c <option number> to proceed,  or :? for other
options

-------------------------------

This is not what I want. I don't want to redefine no-next-method for
all generic functions -- just for foo.  Even if I define an :AFTER
method I'm not sure what the parameter specializations would look like.
How would you define no-next-method for foo?

And (I just want to check) no-next-method is just defined for
side-effects, isn't it? It doesn't return a value.

Thanks -- I really appreciate your insight, I have no clue about how to
set up the method.

-RS

(please don't email me as I'm having some problems with spam. Thanks.)

From: Coby Beck
Subject: Re: no-next-method
Date: 
Message-ID: <wGIHf.7255$bd4.3562@edtnps84>
<··········@eudoramail.com> wrote in message 
·····························@g43g2000cwa.googlegroups.com...
>I have a question about using the no-next-method generic function.  I
> know about next-method-p and I understand how no-next-method should be
> used, but I am unsure about how to create methods on no-next-method.
> Let's say that I do this (my explanation is at the end):
>
> CL-USER 1 > (defgeneric foo (x y))
> #<STANDARD-GENERIC-FUNCTION FOO 2150CB5A>
>
> CL-USER 2 > (defmethod foo ((x integer) (y integer))
>              (format t "~&Foo called. Integer specialization.")
>              (call-next-method))
> #<STANDARD-METHOD FOO NIL (INTEGER INTEGER) 2066987C>
>
> CL-USER 4 > (defmethod foo ((x rational) (y rational))
>              (format t "~&Foo called. Rational specialization.")
>              (call-next-method))
> #<STANDARD-METHOD FOO NIL (RATIONAL RATIONAL) 2066AE64>
>
> CL-USER 5 > (defmethod foo ((x t) (y t))
>              (format t "~&Foo called. T specialization.")
>              (call-next-method))
> #<STANDARD-METHOD FOO NIL (T T) 2067371C>
>
> CL-USER 6 > (foo 4 2) ;; This will cause an error.
> Foo called. Integer specialization.
> Foo called. Rational specialization.
> Foo called. T specialization.
> Error: No next method for  #<STANDARD-METHOD FOO NIL (T T) 2067371C> of
> generic function #<STANDARD-GENERIC-FUNCTION FOO 2150CB5A>  with args
> (4 2)
>  1 (abort) Return to level 0.
>  2 Return to top loop level 0.
>
> Type :b for backtrace, :c <option number> to proceed,  or :? for other
> options
>
> CL-USER 7 : 1 > :top
>
> ;;;  I define a method on no-next-method
>
> CL-USER 8 > (defmethod no-next-method ((foo-fn
> standard-generic-function) (foo-method standard-method) &rest args)
>              (format t "~&No next method for foo."))
>
> Error: Defining method #<STANDARD-METHOD NO-NEXT-METHOD NIL
> (STANDARD-GENERIC-FUNCTION STANDARD-METHOD) 20678DAC> visible from
> package COMMON-LISP.
>  1 (continue) Define it anyway.
>  2 Discard the new method.
>  3 (abort) Return to level 0.
>  4 Return to top loop level 0.
>
> Type :b for backtrace, :c <option number> to proceed,  or :? for other
> options
>
> -------------------------------
>
> This is not what I want. I don't want to redefine no-next-method for
> all generic functions -- just for foo.  Even if I define an :AFTER
> method I'm not sure what the parameter specializations would look like.
> How would you define no-next-method for foo?
>
> And (I just want to check) no-next-method is just defined for
> side-effects, isn't it? It doesn't return a value.
>
> Thanks -- I really appreciate your insight, I have no clue about how to
> set up the method.

The HyperSpec says that NO-NEXT-METHOD returns an object, I assume the 
method object...?  It looks to me like if you really want to do that then 
select the first continuation and handle the situation for all method 
objects.  Whenever I have wanted to handle the no-next-method for myself I 
have written a method that speciallizes on T and do it there.  You used such 
a specialization above, I assume just for this demo, so do that but handle 
your error situation in there.

-- 
Coby Beck
(remove #\Space "coby 101 @ bigpond . com")
From: ··········@eudoramail.com
Subject: Re: no-next-method
Date: 
Message-ID: <1139763254.122673.70870@g47g2000cwa.googlegroups.com>
Gosh, that's right -- I should just use the T specialization.

Thanks for the straightening this out for me,
RS




(please don't email me as I am having problems with spam on this
account).
From: Pascal Costanza
Subject: Re: no-next-method
Date: 
Message-ID: <4594lcF51oimU1@individual.net>
··········@eudoramail.com wrote:
> I have a question about using the no-next-method generic function.  I
> know about next-method-p and I understand how no-next-method should be
> used, but I am unsure about how to create methods on no-next-method.
[...]

> CL-USER 8 > (defmethod no-next-method ((foo-fn
> standard-generic-function) (foo-method standard-method) &rest args)
>               (format t "~&No next method for foo."))
> 
> Error: Defining method #<STANDARD-METHOD NO-NEXT-METHOD NIL
> (STANDARD-GENERIC-FUNCTION STANDARD-METHOD) 20678DAC> visible from
> package COMMON-LISP.
>   1 (continue) Define it anyway.
>   2 Discard the new method.
>   3 (abort) Return to level 0.
>   4 Return to top loop level 0.
> 
> Type :b for backtrace, :c <option number> to proceed,  or :? for other
> options
> 
> -------------------------------
> 
> This is not what I want. I don't want to redefine no-next-method for
> all generic functions -- just for foo.  Even if I define an :AFTER
> method I'm not sure what the parameter specializations would look like.
> How would you define no-next-method for foo?

(defmethod no-next-method
   ((gf (eql #'foo)) (method standard-method) &rest args)
   ...)

should do the job.

If you have the CLOS MOP available, you can also do the following:

(defclass my-generic-function (standard-generic-function)
   ())

(defmethod no-next-method ((gf my-generic-function) ...)
   ...)

(defgeneric foo (...)
   (:generic-function-class my-generic-function))

...but this is probably overkill. Handling the default case in a method 
specialized on t is, as suggested by Coby, is probably good enough.


My impression from reading about the history of Common Lisp is that CLOS 
and the condition were developed roughly at the same time, so the CLOS 
designers didn't know (exactly?) what the condition system would look 
like. I guess that's why all the error reporting in CLOS has been 
defined via dedicated generic functions. Sometimes, this can be handy.

Pascal

-- 
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
From: ··········@eudoramail.com
Subject: Re: no-next-method
Date: 
Message-ID: <1139764225.223166.235110@z14g2000cwz.googlegroups.com>
Pascal,

Thank you for your (eql #'foo) example -- ahhh yes, I think that using
:generic-function-class is too complicated for me (but I'm glad you
showed an example because I've sometimes wondered about how you would
use that option).

Thanks again,
RS


(please don't email me because I'm having problems keeping up with my
spam)