Re: trouble understanding next-method and mixins

From: Erick Gallesio <Erick.Gallesio_at_unice.fr>
Date: Wed, 30 Jun 1999 08:37:54 +0200 (CEST)

Brian Denheyer writes:
>
> When I try the code given at the end of the e-mail I get the following
> results :
>
> Welcome to the STk interpreter version 3.99.4 [Linux-2.X-ix86]
> Copyright (C) 1993-1999 Erick Gallesio - I3S - CNRS / ESSI <eg_at_unice.fr>
> deleting baz #[<baz> 80970a8]
> deleting mixer #[<baz> 80970a8]
> deleting foo #[<baz> 80970a8]
> deleting boo #[<boo> 809499c]
> deleting mixer #[<boo> 809499c]
> *** Error at line 41 of file ./mix.scm:
> No next method when calling #[<generic> delete (4)]
> with (#[<boo> 809499c]) as argument
> Current eval stack:
> __________________
> 0 (error "No next method when calling ~S\nwith ~S as argument" gf args)
> 1 (next-method)
> 2 (next-method)
>
> The error is pretty clear. Delete<boo> is followed by delete<mixer>
> which sees a next-method and dies. Obviously stk thinks there should
> be yet another gf which will take <boo>, just like when <baz> was
> deleted.
>
> Although I understand the error doesn't this type of operation
> severely limit the use of mixins ? After all, once I have used
> <mixer> in a class, I'm stuck. I can't use it as a super class for
> any other class and invoke delete on that new class or I will get the
> same result that I did when trying to delete the <boo> instance. This
> is all due to the next-method in delete<mixer>.
>
> Do I need to write delete for <boo> (or <mixer>) differently somehow?
> Is there some other way to invoke delete for the <mixer> super class
> when deleting a <boo> object ? Do I have some larger problem in the
> class designs ??
>
> Inquiring minds want to know.
>
> Thanks

In fact, here again the MOP could be your friend ;-)
If you want, you can change the default behaviour when a bad
next-method is called. This can be achieved quite simply by doing

    (define-method no-next-method ((gf <generic>) args)
      (format #t "OK we are calling a generic function without next method\n")
      'this-is-the-result)

This, in fact replace the default no-next-method method of STklos.
Of course this is generally not suitable, but it here that inheritance
is your friend too: you can define a sub-class of <generic> to which
your associate this new behaviour only. This can be done by

    (define-class <my-generic> (<generic>) ())
    (define-method no-next-method ((gf <my-generic>) args)
      (format #t "OK we are calling a new generic function without next method\n")
      'this-is-the-result)

The only thing you have to do now is choose the generic function to
which you want to associate this behavior. For that, you have to
declare yourself the generic function, PRIOR to associate it any
method. For instance:

        (define delete (make <my-generic> :name 'delete))

I know that my response is a little bit aside what you ask (I don't
answer about mixins but how to avoid a no-next-method error), but
perhaps it could help.

>
> (define-class <foo> ()
> ((foo :accessor foo
> :init-keyword :foo)
> (foo1 :accessor foo1
> :initform 'foo1
> :init-keyword :foo1)))
>
> (define-class <mixer> ()
> ((mix :accessor mix
> :init-keyword :mix
> :initform 'mix)))
>
> (define-class <baz> (<mixer> <foo>)
> ())
>
> (define-class <boo> (<mixer>)
> ())
>
> (define-method delete
> ((self <foo>))
> (format #t "deleting foo ~A\n" self))
>
> (define-method delete
> ((self <baz>))
> (format #t "deleting baz ~A\n" self)
> (next-method))
>
> (define-method delete
> ((self <mixer>))
> (format #t "deleting mixer ~A\n" self)
> (next-method))
>
> (define-method delete
> ((self <boo>))
> (format #t "deleting boo ~A\n" self)
> (next-method))
>
> (define x (make <baz>))
> (delete x)
> (define y (make <boo>))
> (delete y)


                -- Erick
Received on Wed Jun 30 1999 - 08:54:28 CEST

This archive was generated by hypermail 2.3.0 : Mon Jul 21 2014 - 19:38:59 CEST