Eager and Lazy Evaluation in Fexl

On Fri 2011-07-01 I expressed some misgivings I was having about lazy evaluation. Well never mind all that. On Saturday morning I figured out what to do, right before going out for a hike with some friends, both human and canine, down to the river for some swimming. Now that's what I call a good day.

The answer is simple: I'll make the "=" form do an eager evaluation. Currently the interpreter expands "=" with this rule:

\x=A B  ->  (\x B) A

That will continue to be true, except the interpreter will evaluate A eagerly before passing it in as an argument. Internally I will implement a new combinator "?" which forces evaluation of its first argument and then passes that value to its second argument. So the new expansion rule will be:

\x=A B  ->  ? A (\x B)

So now when you do things like this, the individual steps will be evaluated eagerly as you go:

\x = 3
\y = 4
\x = (+ x y)
\x = (* x x)
\y = (- x 5)
...

Previously, without the eager evaluation, this would merely build up a long chain of unevaluated forms, which would only be evaluated when you finally forced it by printing it or whatever. That is often harmless, but it can really bite you if you build an extremely long chain.

The rule for expanding the "==" form will remain unchanged:

\x==A B  ->  (\x B) (Y \x A)

That is typically used for recursive definitions, e.g.:

\append == (\x\y x y \h\t item h; append t y)

However, you are free to use it with non-recursive definitions as well, in cases where you do not want eager evaluation for some reason. For example, you might have a bunch of test suite functions with side effects, and you don't want them evaluated as you proceed through their definitions, but rather only at the very end under certain conditions.

Note

On Tue 2011-07-05 I implemented this feature in version a7 of Fexl.