call-next-next-method 
Author Message
 call-next-next-method

I would like to be able to call the next next-method in CLOS.  That
is the method that would be called if the method invoked by
call-next-method called call-next-method.  Is there any direct way to
do it?  Thanks,

--shiv--

Read on for the actual problem ...

I have made-up an artificial problem that hopefully reflects the
essentials of my actual problem.

(defclass matrix ()
  (...))

(defclass lower-triangular-matrix (matrix)
  (...))

(defclass upper-triangular-matrix (matrix)
  (...))

(defclass square-matrix (lower-triangular-matrix upper-triangular-matrix)
  ())

(defgeneric mref (matrix i j)
 (:documentation "Access (i,j)th element of matrix."))

(defmethod mref ((A lower-triangular-matrix) (i integer) (j integer))
  ... )

(defmethod mref ((A upper-triangular-matrix) (i integer) (j integer))
  ... )

It would be nice if I could say:

(defmethod mref ((A square-matrix) (i integer) (j integer))
  (+ (call-next-method) (call-next-next-method)))

or something equivalent to that, like

(defmethod mref ((A square-matrix) (i integer) (j integer))
(+ (call-method
     (find-method #'mref
                  (mapcar #'find-class '(lower-triangular-matrix integer
                                         integer)))
     A i j)
   (call-method
     (find-method #'mref
                  (mapcar #'find-class '(upper-triangular-matrix integer
                  integer)))
     A i j)))

Of course I cannot use call-method in defmethod.  So this doesn't work.

Another option seems to be to extend the standard-method-combination
with a + qualifier (using define-method-combination (long form)) that
would add all the results returned by applicable primary methods,

(defmethod mref + ((A square-matrix) (i integer) (j integer))
 0.0).

Yet another option is to just cut and paste the code together...



Mon, 28 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:

>I would like to be able to call the next next-method in CLOS.  That
>is the method that would be called if the method invoked by
>call-next-method called call-next-method.  Is there any direct way to
>do it?  Thanks,

No, you're not supposed to have this much direct control.  You can decide
whether or not to call the next method, by putting a conditional around
call-next-method, but it would be poor modularity to allow you to pick and
choose methods to call.  How do you know that some other class isn't going
to get inserted into the hierarchy, so that the next-next method isn't the
one you really intended to get?

Quote:
>Another option seems to be to extend the standard-method-combination
>with a + qualifier (using define-method-combination (long form)) that
>would add all the results returned by applicable primary methods,

I believe there's a built-in + method combination.

--

GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.



Mon, 28 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:

> I would like to be able to call the next next-method in CLOS.  ...

> I have made-up an artificial problem that hopefully reflects the
> essentials of my actual problem.

> (defclass matrix () (...))
> (defclass lower-triangular-matrix (matrix) (...))
> (defclass upper-triangular-matrix (matrix) (...))
> (defclass square-matrix (lower-triangular-matrix upper-triangular-matrix)
>   ())

Aside from the question you actually asked, which Barry adequately
answered, I must comment on the type relationships that your example
code defines.  Often when I have method combination problems or
questions, they really arise from a hastily composed class hierarchy
or one that was ill-driven by implementation considerations rather
than by model considerations.

The above class definitions tell me that a square matrix is a subtype
of both a lower triangular matrix and an upper triangular matrix.
Aren't the type relationships really the other way around?

                - Pat



Tue, 29 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:

>>I would like to be able to call the next next-method in CLOS.  That
>>is the method that would be called if the method invoked by
>>call-next-method called call-next-method.  Is there any direct way to
>>do it?
>No, you're not supposed to have this much direct control.  You can
>decide whether or not to call the next method, by putting a
>conditional around call-next-method, but it would be poor modularity
>to allow you to pick and choose methods to call.  How do you know that
>some other class isn't going to get inserted into the hierarchy, so
>that the next-next method isn't the one you really intended to get?

But that objection holds for call-next-method too!  In my case this
level of the class hierarchy is not meant to be public.  Not that
excuses bad design, but in this case it might let me proceed quicker.

Quote:
>>Another option seems to be to extend the standard-method-combination
>>with a + qualifier (using define-method-combination (long form)) that
>>would add all the results returned by applicable primary methods,
>I believe there's a built-in + method combination.

Couldn't find it in cltl2 or the hyperspec.  However, the examples
under define-method-combination seem good enough to churn one out
quickly.

--shiv--



Tue, 29 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:

> > I would like to be able to call the next next-method in CLOS.  ...

> > I have made-up an artificial problem that hopefully reflects the
> > essentials of my actual problem.

> > (defclass matrix () (...))
> > (defclass lower-triangular-matrix (matrix) (...))
> > (defclass upper-triangular-matrix (matrix) (...))
> > (defclass square-matrix (lower-triangular-matrix upper-triangular-matrix)
> >   ())

> Aside from the question you actually asked, which Barry adequately
> answered, I must comment on the type relationships that your example
> code defines.  Often when I have method combination problems or
> questions, they really arise from a hastily composed class hierarchy
> or one that was ill-driven by implementation considerations rather
> than by model considerations.

> The above class definitions tell me that a square matrix is a subtype
> of both a lower triangular matrix and an upper triangular matrix.
> Aren't the type relationships really the other way around?

>            - Pat


On the face it, sure, the answer is yes.  However, in my code,
"square-matrix" is really a "union" of "lower-triangular-matrix" and
"upper-triangular-matrix".  That is why I was wishing that I could
directly call all the methods at the previous level.

I guess the real answer is that the standard-method-combination is not
appropriate in such a case.

--shiv--



Tue, 29 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:


>>>I would like to be able to call the next next-method in CLOS.  That
>>>is the method that would be called if the method invoked by
>>>call-next-method called call-next-method.  Is there any direct way to
>>>do it?

>>No, you're not supposed to have this much direct control.  You can
>>decide whether or not to call the next method, by putting a
>>conditional around call-next-method, but it would be poor modularity
>>to allow you to pick and choose methods to call.  How do you know that
>>some other class isn't going to get inserted into the hierarchy, so
>>that the next-next method isn't the one you really intended to get?

>But that objection holds for call-next-method too!

Not really.  The idea is that a method can either augment the methods in
the superclass hierarchy (by doing stuff and calling call-next-method) or
completely override them (by not calling call-next-method).  But when it's
augmenting them, it doesn't have to know what the rest of the hierarchy
does; they merely have to implement the contract of the GF.

Quote:
>>I believe there's a built-in + method combination.

>Couldn't find it in cltl2 or the hyperspec.  However, the examples
>under define-method-combination seem good enough to churn one out
>quickly.

CLTL2 section 28.1.7.4 Built-in Method Comination Types, paragraph 2, says:
"The names of the built-in method combination types are +, AND, APPEND,
LIST, MAX, MIN, MCONC, OR, PROGN, and STANDARD."

--

GTE Internetworking, Powered by BBN, Burlington, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.



Tue, 29 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:


> >>I would like to be able to call the next next-method in CLOS.  That
> >>is the method that would be called if the method invoked by
> >>call-next-method called call-next-method.  Is there any direct way to
> >>do it?

> >No, you're not supposed to have this much direct control.  You can
> >decide whether or not to call the next method, by putting a
> >conditional around call-next-method, but it would be poor modularity
> >to allow you to pick and choose methods to call.  How do you know that
> >some other class isn't going to get inserted into the hierarchy, so
> >that the next-next method isn't the one you really intended to get?

> But that objection holds for call-next-method too!

No, it doesn't.  Sorry, I was too hasty there.

--shiv--



Tue, 29 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:

> On the face it, sure, the answer is yes.  However, in my code,
> "square-matrix" is really a "union" of "lower-triangular-matrix" and
> "upper-triangular-matrix".  That is why I was wishing that I could
> directly call all the methods at the previous level.

This usually means you're short one protocol.  Just name the methods
that you want to call something that can be accessed by name.  That
is, if you want to call FOO one level up, make the one-level-up method
be called FOO-AUX and then make the FOO method on that class call FOO-AUX
but also make your inheriting methods call FOO-AUX if they want to.

Quote:
> I guess the real answer is that the standard-method-combination is not
> appropriate in such a case.

I'm not sure method combination at all is your friend here.
This sounds to me like a case where you want to dead-reckon a particular
item (which is what "naming" is for).  Method combination is for
relative/vague naming ("call that thing above me" or "call those
other things"); it is specifically not about absolute naming.


Tue, 29 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:

> > On the face it, sure, the answer is yes.  However, in my code,
> > "square-matrix" is really a "union" of "lower-triangular-matrix" and
> > "upper-triangular-matrix".  That is why I was wishing that I could
> > directly call all the methods at the previous level.

> This usually means you're short one protocol.  Just name the methods
> that you want to call something that can be accessed by name.  That
> is, if you want to call FOO one level up, make the one-level-up method
> be called FOO-AUX and then make the FOO method on that class call FOO-AUX
> but also make your inheriting methods call FOO-AUX if they want to.

Thanks.  That is what I ended up doing.

--shiv--



Tue, 29 Jan 2002 03:00:00 GMT  
 call-next-next-method
To expand on this and what Pat O'Donnell said:

I like to distinguish between things which ARE a number of other things
(kind-of or mixin inheritance) and thigns which HAVE a number of other
things (part-of or part-whole inheritance).  CLOS directly supports only
the first, so we get very used to thinking in kind-of terms.  

If a model suggest, for example, that a matrix has two parts, then we're
dealing with part-whole arrangements.  CLOS doesn't address any
automatic combinations of these, so whenever this comes up you will
ALWAYS need an named "auxiliary" function.  

It's sometimes easy and/or desirable to combine the two styles, as when
the two parts do not interfere with each other at all.  Then we might
have a supply-part-A-mixin, and a supply-part-B-mixin.  That doesn't
change the fact that we're still dealing with part-whole, and still
require a mechanism other than the CLOS provided inheritance and method
combination.

Quote:


> > On the face it, sure, the answer is yes.  However, in my code,
> > "square-matrix" is really a "union" of "lower-triangular-matrix" and
> > "upper-triangular-matrix".  That is why I was wishing that I could
> > directly call all the methods at the previous level.

> This usually means you're short one protocol.  Just name the methods
> that you want to call something that can be accessed by name.  That
> is, if you want to call FOO one level up, make the one-level-up method
> be called FOO-AUX and then make the FOO method on that class call FOO-AUX
> but also make your inheriting methods call FOO-AUX if they want to.

> > I guess the real answer is that the standard-method-combination is not
> > appropriate in such a case.

> I'm not sure method combination at all is your friend here.
> This sounds to me like a case where you want to dead-reckon a particular
> item (which is what "naming" is for).  Method combination is for
> relative/vague naming ("call that thing above me" or "call those
> other things"); it is specifically not about absolute naming.



Tue, 29 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:



> > > (defclass matrix () (...))
> > > (defclass lower-triangular-matrix (matrix) (...))
> > > (defclass upper-triangular-matrix (matrix) (...))
> > > (defclass square-matrix (lower-triangular-matrix upper-triangular-matrix)

> > The above class definitions tell me that a square matrix is a subtype
> > of both a lower triangular matrix and an upper triangular matrix.
> > Aren't the type relationships really the other way around?

> On the face it, sure, the answer is yes.  However, in my code,
> "square-matrix" is really a "union" of "lower-triangular-matrix" and
> "upper-triangular-matrix".  That is why I was wishing that I could
> directly call all the methods at the previous level.

My point, though, is that (typep x 'lower-triangular-matrix) will
return true for a general square matrix.  Is that what you really
want?  My message was intended to concentrate on the type
relationships irrespective of the method combination issues.

On the topic of method combinations, however, I will offer the
observation that I have often regretted attempts to use method
combination types other than standard.  Similar to Kent's message,
most of the time I've though I've needed something other than primary,
before, after, and around, I've later found that I really had a badly
designed, half-baked protocol.  Sadly, it's almost always to late to
fix it by the time one realizes that.

                - Pat



Tue, 29 Jan 2002 03:00:00 GMT  
 call-next-next-method

Quote:



> >I would like to be able to call the next next-method in CLOS.  That
> >is the method that would be called if the method invoked by
> >call-next-method called call-next-method.  Is there any direct way to
> >do it?  Thanks,

> No, you're not supposed to have this much direct control.  You can decide
> whether or not to call the next method, by putting a conditional around
> call-next-method, but it would be poor modularity to allow you to pick and
> choose methods to call.  How do you know that some other class isn't going
> to get inserted into the hierarchy, so that the next-next method isn't the
> one you really intended to get?

The smell of C++ is felt all over the globe.  Since C++ does not help
you in any way when you have multiple inheritance, you must resort to
this sort of things in order to sort out what is being used.

This usually happens after a few recompile cycles.

Cheers

--
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa



Sat, 02 Feb 2002 03:00:00 GMT  
 call-next-next-method

| I have made-up an artificial problem that hopefully reflects the
| essentials of my actual problem.
|
| (defclass matrix ()
|   (...))
|
| (defclass lower-triangular-matrix (matrix)
|   (...))
|
| (defclass upper-triangular-matrix (matrix)
|   (...))
|
| (defclass square-matrix (lower-triangular-matrix upper-triangular-matrix)
|   ())

  why not simply talk about the parts

(defclass square-matrix (matrix)
  ((lower-triangle :type lower-triangular-matrix)
   (upper-triangle :type upper-triangular-matrix)))

| It would be nice if I could say:
|
| (defmethod mref ((A square-matrix) (i integer) (j integer))
|   (+ (call-next-method) (call-next-next-method)))

  why is the following the wrong solution?

(defmethod mref ((A square-matrix) (i integer) (j integer))
  (+ (mref (slot-value A 'lower-triangle) i j)
     (mref (slot-value A 'upper-triangle) i j)))

#:Erik
--
  (defun pringles (chips)
    (loop (pop chips)))



Sun, 03 Feb 2002 03:00:00 GMT  
 call-next-next-method

Quote:

>   why not simply talk about the parts

> (defclass square-matrix (matrix)
>   ((lower-triangle :type lower-triangular-matrix)
>    (upper-triangle :type upper-triangular-matrix)))

> | It would be nice if I could say:
> |
> | (defmethod mref ((A square-matrix) (i integer) (j integer))
> |   (+ (call-next-method) (call-next-next-method)))

>   why is the following the wrong solution?

> (defmethod mref ((A square-matrix) (i integer) (j integer))
>   (+ (mref (slot-value A 'lower-triangle) i j)
>      (mref (slot-value A 'upper-triangle) i j)))

> #:Erik
> --
>   (defun pringles (chips)
>     (loop (pop chips)))

This was the first approach I tried.  Unfortunately, it looked like it
would cause a lot of code duplication (other than just mref) and I
went with the subclass approach instead.

--shiv--



Sun, 03 Feb 2002 03:00:00 GMT  
 call-next-next-method

| Unfortunately, it looked like it would cause a lot of code duplication
| (other than just mref) and I went with the subclass approach instead.

  um, do I get this?  the approach would work, but would involve some code
  duplication, so you abandoned it for one that involves a lot less code
  that _doesn't_ work?

  code duplication is generally solved with macros.  in general, most of
  the CLOS magic is indeed macros and machinery that has been created for
  you, otherwise it would have caused a lot of difficult code duplication,
  so I don't see why "code duplication" doesn't _precisely_ mean that you
  automate the task of duplication yourself.

#:Erik
--
  (defun pringles (chips)
    (loop (pop chips)))



Sun, 03 Feb 2002 03:00:00 GMT  
 
 [ 17 post ]  Go to page: [1] [2]

 Relevant Pages 

1. Recursive methods with :around's and call-next-method results

2. multiple calls to CALL-NEXT-METHOD

3. CALL-NEXT-METHOD with changed parameters

4. Call-next-method extent and usage

5. call-next-method questions

6. Question about defmethod, call-next-method, and declarations

7. CALL-NEXT-METHOD behavior

8. condition system handler-bind analogy to call-next-method or compute-restarts

9. Next vs. Access.fliename.Next()

10. NeXT/NeXT STEP Oberon?

11. Array#next - Enumerable#next ?

12. next-method in FunDev

 

 
Powered by phpBB® Forum Software