From: Vladimir Zolotykh
Subject: mop: modify generic function
Date: 
Message-ID: <opsvpok1gl4w83rv@algow.eurocom.od.ua>
Suppose I have a method

   cl-user(1): (defmethod foo ((i integer)) t)
   #<standard-method foo (integer)>

If I redefine it I get an error (using ACL7.0)

   cl-user(2): (defmethod foo ((i integer) &key k) t)
   Error: Attempt to add the method #<standard-method foo (integer) @  
#x727aa77a> \
          to the generic function #<standard-generic-function foo> but the
	 method and generic function differ in whether they accept rest or  
keyword arguments.
     [condition type: program-error]

   Restart actions (select using :continue):
    0: Add method anyway and modify generic function.
    1: Return to Top Level (an "abort" restart).
    2: Abort entirely from this (lisp) process.
   [1c] cl-user(3):

If I didn't have this restart (0: Add method ...) how could I solve
the problem "manually"?  I could have uninterned the foo symbol, but
this seems too cruel a solution. I believe there is a way to "modify"
generic function manually, using mop I mean. Could you please tell me
how to do that?


-- 
Vladimir Zolotykh

From: R. Mattes
Subject: Re: mop: modify generic function
Date: 
Message-ID: <pan.2005.08.17.17.10.44.95151@mh-freiburg.de>
On Thu, 18 Aug 2005 19:11:15 +0300, Vladimir Zolotykh wrote:

> Suppose I have a method
> 
>    cl-user(1): (defmethod foo ((i integer)) t)
>    #<standard-method foo (integer)>
> 
> If I redefine it I get an error (using ACL7.0)
> 
>    cl-user(2): (defmethod foo ((i integer) &key k) t)
>    Error: Attempt to add the method #<standard-method foo (integer) @  
> #x727aa77a> \
>           to the generic function #<standard-generic-function foo> but the
> 	 method and generic function differ in whether they accept rest or  
> keyword arguments.
>      [condition type: program-error]
> 
>    Restart actions (select using :continue):
>     0: Add method anyway and modify generic function.
>     1: Return to Top Level (an "abort" restart).
>     2: Abort entirely from this (lisp) process.
>    [1c] cl-user(3):
> 
> If I didn't have this restart (0: Add method ...) how could I solve
> the problem "manually"?  I could have uninterned the foo symbol, but
> this seems too cruel a solution. I believe there is a way to "modify"
> generic function manually, using mop I mean. Could you please tell me
> how to do that?

The problem is that you try to add a method to a generic function (which
is generated authoatically by your first defmethod call) but the new
method's lambda-list doesn't fit to the generic method. You can't really
"fix" this since changing the lambda-list of a generic function might in-
validate other existing methods. 

 Cheers Ralf Mattes
From: John
Subject: Re: mop: modify generic function
Date: 
Message-ID: <slrndg9hk0.158c.IxfSWIna@mailinator.com>
On 2005-08-17, R. Mattes <··@mh-freiburg.de> wrote:
>  On Thu, 18 Aug 2005 19:11:15 +0300, Vladimir Zolotykh wrote:
> > Suppose I have a method
> > 
> >    cl-user(1): (defmethod foo ((i integer)) t)
> >    #<standard-method foo (integer)>
> 
>  The problem is that you try to add a method to a generic function (which
>  is generated authoatically by your first defmethod call) but the new
>  method's lambda-list doesn't fit to the generic method. You can't really
>  "fix" this since changing the lambda-list of a generic function might in-
>  validate other existing methods. 

As long as we are on this topic, maybe someone can answer a question I've
had for a while now.

In a lot of LISP code I've read I notice that people frequently don't use
defgeneric and just start defining things with defmethod. Why leave out
the defgeneric statement? It seems to me that putting one in improves
readability and lets you add an appropriate documentation string to inform
users as to the purpose of the generic method.

What purpose does leaving it out serve?
From: Pascal Bourguignon
Subject: Re: mop: modify generic function
Date: 
Message-ID: <87slx786o4.fsf@thalassa.informatimago.com>
John <········@mailinator.com> writes:
> What purpose does leaving it out serve?

What purpose does having it serve?

The more declarations you have, the more inconsistency you may get:

(defgeneric meth (a b))
(defclass c () ())
(defmethod ((self c) (p1 integer) (p2 istring))
            ...)


Personnaly, I use: M-x insert-generics RET when the compilers complain.

| insert-generics is an interactive compiled Lisp function in `pjb-sources'.
| (insert-generics &optional imported)
|
| Insert (DEFGENERIC ...) sexps from the (defmethod ...) found in file.

-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

There is no worse tyranny than to force a man to pay for what he does not
want merely because you think it would be good for him. -- Robert Heinlein
From: John
Subject: Re: mop: modify generic function
Date: 
Message-ID: <slrndg9lfu.15ds.MB42gDv0@mailinator.com>
On 2005-08-18, Pascal Bourguignon <····@mouse-potato.com> wrote:
>  John <········@mailinator.com> writes:
> > What purpose does leaving it out serve?
> 
>  What purpose does having it serve?

Well, according to the hyperspec:

  "The effect of the defgeneric macro is as if the following three steps
   were performed: first, methods defined by previous defgeneric forms are
   removed; second, ensure-generic-function is called; and finally,
   methods specified by the current defgeneric form are added to the
   generic function."

I can see why you wouldn't always care about those steps though so here
are a few other reasons:

  1. Convenient place to place a documentation string for the generic
     function. Makes it easier for people other than you to know
     what this function is intended to do.
  2. Establishes the correct argument list in an unambiguous fashion
     enabling the compile to provide better messages.

As far as I can see the only real reason people give for not including it
is to save typing.

At a typing rate of 60wpm (low estimate for people in this group) I fail
to see how much time this really saves. Certainly not enough to sacrifice
clarity.

Just my $.02
From: Marco Baringer
Subject: Re: mop: modify generic function
Date: 
Message-ID: <m2mzneuwrw.fsf@soma.local>
John <········@mailinator.com> writes:

> As far as I can see the only real reason people give for not including it
> is to save typing.
>
> At a typing rate of 60wpm (low estimate for people in this group) I fail
> to see how much time this really saves. Certainly not enough to sacrifice
> clarity.

when the generic-function is part of a public protocol then i use
defgeneric. if we're talking about the only method for a
generic-function, and it's not a function only to get some extra error
checking, then i'd not use defgeneric.

(defgeneric startup (object &key &allow-other-keys)
  ...)

(defmethod startup ((server server-type1) &key ...))

(defmethod startup ((server server-type2) &key ...)

vs.

(defmethod access-slot-with-dwim ((object object-type))
  ..)

in the second case access-slot-with-dwim isn't really a 'generic'
function, we don't plan of having other methods and the only
documentation we can think of only makes sense in the context of the
method.

-- 
-Marco
Ring the bells that still can ring.
Forget the perfect offering.
There is a crack in everything.
That's how the light gets in.
	-Leonard Cohen
From: Peter Seibel
Subject: Re: mop: modify generic function
Date: 
Message-ID: <m24q9nw39m.fsf@gigamonkeys.com>
"Vladimir Zolotykh" <······@eurocom.od.ua> writes:

> Suppose I have a method
>
>    cl-user(1): (defmethod foo ((i integer)) t)
>    #<standard-method foo (integer)>
>
> If I redefine it I get an error (using ACL7.0)
>
>    cl-user(2): (defmethod foo ((i integer) &key k) t)
>    Error: Attempt to add the method #<standard-method foo (integer) @
>    #x727aa77a> \
>           to the generic function #<standard-generic-function foo> but the
> 	 method and generic function differ in whether they accept
> 	 rest or  keyword arguments.
>      [condition type: program-error]
>
>    Restart actions (select using :continue):
>     0: Add method anyway and modify generic function.
>     1: Return to Top Level (an "abort" restart).
>     2: Abort entirely from this (lisp) process.
>    [1c] cl-user(3):
>
> If I didn't have this restart (0: Add method ...) how could I solve
> the problem "manually"?  I could have uninterned the foo symbol, but
> this seems too cruel a solution. I believe there is a way to
> "modify" generic function manually, using mop I mean. Could you
> please tell me how to do that?

Well, less drastic than uninterning the symbol (which would also
affect other things named with that symbol such as variables) would be:

  (fmakunbound 'foo)

I.e. remove the existing (generic) function definition. Then you can
start over defining this generic function and its methods.

-Peter

-- 
Peter Seibel           * ·····@gigamonkeys.com
Gigamonkeys Consulting * http://www.gigamonkeys.com/
Practical Common Lisp  * http://www.gigamonkeys.com/book/
From: Christophe Rhodes
Subject: Re: mop: modify generic function
Date: 
Message-ID: <sqoe7vari1.fsf@cam.ac.uk>
"Vladimir Zolotykh" <······@eurocom.od.ua> writes:

> If I didn't have this restart (0: Add method ...) how could I solve
> the problem "manually"?  I could have uninterned the foo symbol, but
> this seems too cruel a solution. I believe there is a way to "modify"
> generic function manually, using mop I mean. Could you please tell me
> how to do that?

Remove all existing methods of the generic function; redefine the
generic function; add back those methods which you want to add back.

Christophe