[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]


Mark Thomas <thommark@access.digex.net> writes:

> There appears to be a bug in the definition of
> COMPUTE-EFFECTIVE-METHOD, specifically in line 2716 of clos.lsp:
>       (loop (apply #'no-applicable-method gf args))
> You can see that if a programmer defines new methods for
> NO-APPLICABLE-METHOD, and if the resulting effective method returns to
> its caller, an endless loop will result.

What do you do in your method for NO-APPLICABLE-METHOD ? If you add
new methods to `gf', it might be better to put in a jump to the beginning

  (defun compute-effective-method (gf &rest args)
    (tagbody restart-compute
      (when (null methods)
        (apply #'no-applicable-method gf args)
        (go restart-compute))
  ) )

If you don't execute any corrective action, the endless loop will persist,
of course. That is intended.

> Question: Is NO-PRIMARY-METHOD specific to CLISP (I can't find it in
>           dpANS)?

Yes, it is specific to CLISP. If for a call to a generic function
only :around and :before/:after methods are applicable but no
primary methods, this is an error. dpANS apparently forgot to
introduce a generic function for this case.

> Question: Shouldn't NO-PRIMARY-METHOD be called only when there _are_
>           applicable methods?

Sure. It was your patch that made COMPUTE-EFFECTIVE-METHOD continue
although there were no applicable methods.

> Remark:   In line 2761 of clos.lsp, you see that that programmer
>           defined methods for NO-PRIMARY-METHOD might also loop
>           endlessly.  So, assuming that such programmer-defined
>           methods are allowed, this is another instance of the same
>           bug.

So change
      (when (null primary-methods)
        (loop (apply #'no-primary-method gf args))
      (when (null primary-methods)
        (apply #'no-primary-method gf args)
        (go restart-compute)

> Here's my test code (latest version of CLISP):
> (defmethod no-applicable-method ((fn (eql #'foo-id)) &rest args)
>    (format T "~&~S~S~%" fn args))

Whee! You just print something, no corrective action. What do you
expect the Lisp implementation to do??