Question about call-next-method

"Edward Kiser (as edkiser at gmail dot com)" <[email protected]>
Newsgroups gmane.lisp.lispworks.general
Message-ID <CACzs4FhwSF0QKJo6WGVeKWKoD3FyY0VUHHPxZ2iO663OaC4azQ@mail.gmail.com>
Hello,

Can call-next-method be safely captured in a lambda and returned, to
be replayed later? Will it retain the meaning it had when it was
captured?

My testing in LispWorks suggests that it can be, but I want to know if
I can always expect that to be the case or if I am accidentally
relying on undefined behavior.

The Common Lisp HyperSpec says, "The function call-next-method has
lexical scope and indefinite extent, and can only be used within the
body of a method defined by a method-defining form."

There are various ways to interpret this. For example, it's possible
that call-next-method is a global function with indefinite extent but
that its meaning varies depending on which method is currently
running, and if no method is running, it has no meaning. This would
mean that if you wrote a method (call it "A") that returned (lambda ()
(call-next-method)), or even just #'call-next-method, and later called
that procedure when no method was running, it would fail -- and if you
called it inside method "B" it would call B's next method instead of
A's.

When it says "can only be used within the body," does that mean
lexically within the body, or dynamically when the body is running, or
both?

I am sort of hoping that (lambda () (call-next-method)) would capture
whatever meaning call-next-method had when "lambda" created the
function, and use that same meaning whenever the function was called.

An implementation could ensure this by using symbol-macrolet
internally to define a different meaning for call-next-method for each
method, because call-next-method would be replaced by the macro
expander with whatever meaning it is supposed to have in that lexical
environment.

(The AMOP book uses an "add-function-bindings" function which
apparently adds the bindings to the lexical environment, but it
doesn't say how "add-function-bindings" works.)

The reason I want to save the meaning of call-next-method and use it
later is because I am doing continuation-passing-style with a
trampoline, and I wanted to use the long form of
define-method-combination to combine methods, and each method might
want to bounce off the trampoline several times.

Also I am using "amb" and I would like it if I could use the saved
lambdas more than once.

Sincerely,

Ed Kiser

----

Experiment:

CL-USER 1 > (defclass jikken1 () ())
#<STANDARD-CLASS JIKKEN1 40202ABAB3>

CL-USER 2 > (defclass jikken2 () ())
#<STANDARD-CLASS JIKKEN2 40202AE86B>

CL-USER 3 > (defgeneric try-something (j))
#<STANDARD-GENERIC-FUNCTION TRY-SOMETHING 4030031B24>

CL-USER 4 > (defmethod try-something ((j jikken1)) (format t "Hello 1 ~s!~%" j))
#<STANDARD-METHOD TRY-SOMETHING NIL (JIKKEN1) 402037294B>

CL-USER 5 > (defmethod try-something :around ((j jikken1)) (lambda ()
(call-next-method)))
#<STANDARD-METHOD TRY-SOMETHING (:AROUND) (JIKKEN1) 4020374B93>

CL-USER 6 > (defmethod try-something ((j jikken2)) (format t "Hello 2 ~s!~%" j))
#<STANDARD-METHOD TRY-SOMETHING NIL (JIKKEN2) 4020375A4B>

CL-USER 7 > (defmethod try-something :around ((j jikken2)) (lambda ()
(call-next-method)))
#<STANDARD-METHOD TRY-SOMETHING (:AROUND) (JIKKEN2) 40203768FB>

CL-USER 8 > (setq aa1 (try-something (make-instance 'jikken1)))
#<anonymous interpreted function 4030000ABC>

CL-USER 9 > (setq aa2 (try-something (make-instance 'jikken2)))
#<anonymous interpreted function 4030000D1C>

CL-USER 10 > (funcall aa1)
Hello 1 #<JIKKEN1 4020019FA3>!
NIL

CL-USER 11 > (funcall aa2)
Hello 2 #<JIKKEN2 402001DFC3>!
NIL

CL-USER 12 > (funcall aa1)
Hello 1 #<JIKKEN1 4020019FA3>!
NIL

_______________________________________________
Lisp Hug - the mailing list for LispWorks users
[email protected]
http://www.lispworks.com/support/lisp-hug.html
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.