From: polar@top.cis.syr.edu (Polar Humenn)
Subject: Re: ** LAZY LANGUAGES FASTER?? **
Organization: Syracuse University, CIS Dept.
Date: Mon, 27 Jul 92 12:39:47 EDT

In article <3737@svin02.info.win.tue.nl> erik@win.tue.nl writes:
>david@gdstech.grumman.com (David Nettles) writes:
>
>Lazy evaluation does indeed save time by not evaluating arguments
>that are not needed. However, eager evaluation saves times by never
>evaluating the same argument twice.
>
>In eager languages, all arguments are evaluated ONCE, regardless of
>whether they are actually needed.
>
>In lazy languages, an argument is evaluated once for every time that it 
>is used. If the argument is used N times, it will be evaluated N times. 
>So if the argument is not used, it will not be evaluated,
>   if the argument is used once, it will be evaluated once,
>   if the argument is used twice, it will be evaluated *TWICE*, etc.

Exuse me, I see your point, however, I don't really know of a *better*
lazy evaluator that doesn't take advantage of formal arguments that
are shared, and updates where necessary when the argument is finally evaluated.

There was a little problem with your example, However.
>  (\x.\y.xx)AB which reduces to AA which reduces to aa
   Assuming that A==>a
However, if indeed lazy evaluation then you have.
    (\x . \y x x) A B ==> AA  ==> aA  
To go any further "a" would have to engulf "A" and force its evaluation,
Just a making a lazy point.

Anyway, very naive lambda calculus evaluators may operate the way you assume, 
but most are implemented with an environment, in which uses of a variable
point to its environment entry.  Once evaluated, the environment entry(ies) are
updated to reflect the evaluation throughout.  Therefore, arguments that are
shared are evaluated only once, not twice, three times, etc.

IMHO, however, lazy evaluation is not a god that will do us *great* benefit.
Instead, I believe it is a useful tool in applications where it works
best.  For example when expressing a problem with infinite data structures, 
and possible _L avoidance is concise.   (That post showing an implementation
of lazy lists in SML was a good argument in this favor)
	
In the same light, Prolog is a good language where Left-to-right resolution 
and unification fits the problem best. Adding other things (which everybody
complains about) slows it down, or doesn't work well.
SML (aside from the appauling syntax) is a good
language where need for eager evaluation fits the problem well.
Ie. if you need a screwdriver, don't reach for the hammer or the vice-grips.

Of course, one of our biggest problems, is that we *think* we need standards,
   (and of course, we have and are developing *many* of them ;-) 
We all would feel more comfortable if we can do everything in one language.
Its sort of like pulling off the highway into the McDonalds in North Carolina
knowing that you can still get the same burger you got in South Dakota.
It's comforting.
However, I think PL/1 is a good example of where this philosophy 
has lead us in the past.

Personally, I think there will and should always be new languages solving 
specific problems, good tools.  This argument of whether or not lazy evaluation 
is better than eager evaluation is horse hockey.  People are always picking some
eager evaluation problem that has appauling lazy behavior, like matrix
multipication, obviously a problem suited better for eager evaluation and
updatable arrays --ie. handing the nail to the guy with the vice grips.

And the lazy advocates are always picking that damn ((\x\y.y) _L A) example --
Handing the screw to the guy with the wrench.  

One of these days, we will learn to integrate all these tools, methods, 
evaluation strategies so that we use the proper ones for the problem(s)
at hand. Instead of always trying to invent more "general-purpose" wheels.

Later,
-Polar