It seems like a little thing, but providing a default USE-VALUE restart
for unbound function cells would make it relatively simple to
portably support completely dynamic function dispatch in Common Lisp.
Consider (doofus 3) where #'doofus is unbound.
If I want to replace the function called in the above form at runtime, I
believe the best I can do is something like:
(handler-bind ((undefined-function #'(lambda (c) (store-value c))))
(loop (restart-case (return (doofus 3))
(store-value (c)
(setf (symbol-function (cell-error-name c))
#'+)))))
This only works for each function I explicitly wrap, and fails for
lexically bound names.
Of the six CL implementations I use, currently two provide a USE-VALUE
restart for the UNDEFINED-FUNCTION condition.
Currently I have:
Implementation USE-VALUE restart for UNDEFINED-FUNCTION
OpenMCL Yes
CLISP Yes
SBCL No
ABCL No
ECL No
CMUCL No
I guess this bugs me because I have read and written code in Ruby, ObjC,
Io, and Smalltalk that uses this kind of flexibility (especially in
Library wrapping code): It's not fast, but it is extremely flexible.
I was wondering a few of things:
1. could people post the availability of the USE-VALUE restart for the
UNDEFINED-FUNCTION condition in Lisps I haven't mentioned.
2. could people comment on how hard it would be to support as a defacto
standard across implementations.
3. related to 2., am I missing something? Is there a way to get code like
the following to work w/o writing an interpreter?
(defun silly-dispatch (name args)
(list name (apply #'+ args)))
(defmacro with-alt-dispatch (&body forms)
`(handler-bind ((undefined-function
#'(lambda (c)
(use-value #'(lambda (&rest args)
(silly-dispatch (cell-error-name c)
args))))))
,@forms))
(with-alt-dispatch (list (* 2 2) (- 7 3) (unbound-fun 2 3 4 5)))
==> (4 4 (unbound-fun 14))
Matt
--
"You do not really understand something unless you can
explain it to your grandmother." — Albert Einstein.
LW provides for sure USE-VALUE for UNDEFINED-FUNCTION (I used to
implement IActiveScript under COM). I don't remember what were the
issues with STORE-VALUE/USE-VALUE and UNDEFINED-FUNCTION w.r.t. the
CLHS.
Cheers
--
Marco
Matthew D Swank wrote:
> I guess this bugs me because I have read and written code in Ruby, ObjC,
> Io, and Smalltalk that uses this kind of flexibility (especially in
> Library wrapping code): It's not fast, but it is extremely flexible.
I guess the Lisp way for providing library wrappers is to try to get
some form of reflective access to the library, and then generate the
wrappers upfront. In the worst case, this means parsing header files,
but in not-so-bad cases this could be done at runtime.
Pascal
--
My website: http://p-cos.net
Closer to MOP & ContextL:
http://common-lisp.net/project/closer/
[Matthew Swank]
> It seems like a little thing, but providing a default USE-VALUE restart
> for unbound function cells would make it relatively simple to
> portably support completely dynamic function dispatch in Common Lisp.
I'm trying to picture why you want to do this. Can you provide a bit
more context?
-- Drew McDermott, Yale University
········@ ··@ alum .dot. mit .dot. edu
On Fri, 16 Dec 2005 20:17:07 -0800, Drew McDermott wrote:
> [Matthew Swank]
>> It seems like a little thing, but providing a default USE-VALUE restart
>> for unbound function cells would make it relatively simple to
>> portably support completely dynamic function dispatch in Common Lisp.
>
> I'm trying to picture why you want to do this. Can you provide a bit
> more context?
It's related to this thread:
http://groups.google.com/group/comp.lang.lisp/browse_thread/thread/e3a45043c461c66a
Frequently a fast and dynamic way to wrap a library (or other "foreign"
computational resource) in a Smalltalk style language is to route
unimplemented methods (which might be _all_ of them) to some handler,
by implementing a method for #doesNotUnderstand message. Since all
methods are tied to classes (and their instances), it is possible to
basically conjure a method out of thin air by handling what is in effect a
condition.
In ANSI Common Lisp I need a little more scaffolding: the generic
function(s) need to exist in order to use NO-APPLICABLE-METHOD. That is
unless the implementation lets me handle the UNDEFINED-FUNCTION condition
by allowing a replacement. Hence the desire for a use-value/store-value
restart.
You can see from Marco's post that it can be handy.
It's also, for the lack of a better phrase, hacker friendly.
Finally, it seems like a reasonably small change. I'm not asking for
continuations or threads. We'll see, though; I've asked the SBCL guys if
they'll support it.
Matt
--
"You do not really understand something unless you can
explain it to your grandmother." — Albert Einstein.
"Drew McDermott" <········@alum.mit.edu> writes:
> [Matthew Swank]
>> It seems like a little thing, but providing a default USE-VALUE restart
>> for unbound function cells would make it relatively simple to
>> portably support completely dynamic function dispatch in Common Lisp.
>
> I'm trying to picture why you want to do this. Can you provide a bit
> more context?
Ah, in my younger days, in a more innocent age, I had this kind of
idea:
<http://groups.google.com/group/comp.lang.lisp/msg/64f047bb9678b9da>
Christophe