Antonio Leitao <aml@gia.ist.utl.pt> wrote:
+---------------
| >>>>> "Rob" =3D=3D Rob Warnock <rpw3@rigden.engr.sgi.com> writes:
| Rob> Scheme-the-standard doesn't give you a *choice* other than
| Rob> (presumably slow) "eval", so passing closures is usually
| Rob> considered the "only right thing".
|
| I don't understand why must we use eval.
+---------------
Because the original problem being discussed was hooks that are lists
of *symbols*, as is often done in Emacs & CL, not closures. That is:
(define my-hooks (list 'func1 'func2))
Now, if (for better or worse) that's how the hook is *defined*, how
do you call those functions in *standard* Scheme without using "eval"?
[...or a non-standard extension such as MzScheme's "global-defined-value".]
+---------------
| What's the problem with this approach?
...
| (define my-hooks (list func1 func2))
...
| (define (run-hooks hooks)
| (for-each (lambda (hook) ((car hook))) hooks))
+---------------
[Uh... You don't need the "car"; "for-each" does that for you.]
Well, your hook variable is a list of *closures*, not symbols.
That certainly "works" (for some definitions of "work"), but fails
to address two of the issues others expressed in this thread:
(1) that the traditional Lisp hook style is to use symbols, and
(2) that using symbols instead of closures has the advantage of
automatically using the *new* value of any hook function that's
redefined, even *after* being added to the hook. Compare both ways:
> (define (foo) (print "foo"))
> (define (bar) (print "bar"))
> (define sym-hook (list 'foo 'bar)) ; the symbol-based version
> (define (do-sym-hooks)
(for-each (lambda (x) ((eval x))) sym-hook))
> (define clo-hook (list foo bar)) ; the closure-based version
> (define (do-clo-hooks)
(for-each (lambda (x) (x)) clo-hook))
> (do-sym-hooks)
foo
bar
> (do-clo-hooks)
foo
bar
>
The same so far, yes? Now look what happens when we redefine one
of the hook functions:
> (define (foo) (print "this is a new, improved foo!!"))
> (do-sym-hooks)
this is a new, improved foo!!
bar
> (do-clo-hooks)
foo
bar
>
Oops!!
-Rob
p.s. Yes, there are ways to get around this problem *without* using
"eval", e.g., make every hook function be a trampoline for the "real"
function, the one that gets edited:
> (define (real-foo) (print "foo"))
> (define (foo) (real-foo))
> (define clo-hook (list foo bar))
> (do-clo-hooks)
foo
bar
> (define (real-foo) (print "this is a new, improved foo!!"))
> (do-clo-hooks)
this is a new, improved foo!!
bar
>
But 'tis a bit cumbersome, yes?
-----
Rob Warnock, 8L-846 rpw3@sgi.com
Applied Networking http://reality.sgi.com/rpw3/
Silicon Graphics, Inc. Phone: 650-933-1673
1600 Amphitheatre Pkwy. FAX: 650-933-0511
Mountain View, CA 94043 PP-ASEL-IA