Since the Perl has been commented on enough, I will
comment on the Lisp.
First of all I suspect that delay is not doing what you
think it is doing. For a start in, say, Common Lisp your
code crashes and burns because delay is a special form in
Scheme, but not Common Lisp. But beyond that delay is
meant to be used with force, which you are not doing. If
you look at
this
description
you will find that when you use a delay without force the
result is implementation dependent, but may be
indistinguishable from the immediate value. Even if it is
not indistinguishable, the code will run at most once and
be memoized.
Therefore your Lisp code is more portably and less
deceptively written as:
(setq closure (setq z (+ 2 2)))
(eval closure) ;;; works
because the code that defined closure is now evaluated
by having been used, and further "evals" of it should
no longer affect the value of z. (ie The promise set
up by delay in your code was redeemed in handing a 4
to eval. Further evals will continue to eval 4, but
will not run the promise again.)
Furthermore if you try to make the Lisp more like the Perl,
for instance by making closure an anonymous function, you
will find that the call semantics no longer work through
an eval. As people have pointed out, that is because your
Perl appears to reflect a deep misunderstanding about what
all of these programming constructs should be doing.
So while I believe that Lisp is more evaluatable than Perl,
I do not think this is an example that illustrates the
principle.
BTW further stylistic points. In Lisp it is considered
bad style to write code with side effects. As the advice
goes, pretend that operations like setq have a penalty
for use, and try to avoid them. Your pretend example of
trying to set up a closure that will modify a global at a
later date is indescribably bad - I would shudder to
face code like that. In any language.
Secondly in Lisp it is almost never a good idea to
actually use eval. Use macros instead. Just as
much power delivered in a more structured form.
What both of these points get at is that writing
debuggable code is a good idea. You seem to evaluate
constructs on the basis of their ability to get very
complex. You seem to entirely discount any notions that
lead to debuggable code. I am coming to the conclusion
that if the general programming world judged like you
seem to, then goto would have never fallen out of
favour...
|