Ah, thanks for posting about my Fexl language. Although I'm the author of it, and somewhat fond of it, I must emphasize this caveat: <a href="http://news.ycombinator.com/item?id=2717560" rel="nofollow">http://news.ycombinator.com/item?id=2717560</a> .<p>Although lazy evaluation is quite amazing, in certain circumstances I find that it's kicking my ass. For example, consider a function that simply sums the numbers from 1 to N:<p><pre><code> \sum == (\N
long_le N 0
0
(long_add N (sum (long_sub N 1)))
)
</code></pre>
Or, more tersely, using the semicolon as a syntactic "pivot" to avoid right-nesting:<p><pre><code> \sum == (\N long_le N 0 0; long_add N; sum; long_sub N 1)
</code></pre>
The problem is that when you call (sum 100000) it builds up a giant chain of (long_add 100000; long_add 99999; long_add 99998; ...) and then evaluates that monstrosity recursively.<p>So I need to do some more work on forcing early evaluation. You can start by using the standard accumulator trick:<p><pre><code> \sum == (\total\N
long_le N 0
total
(sum (long_add total N) (long_sub N 1))
)
\sum = (sum 0)
</code></pre>
But even then you still have the massive recursion problem because you're not forcing the addition operation early.<p>I'm thinking I just need to allow basic types like "long" to be called as functions with no effect (i.e. equivalent to the identity function, so you can do things like this:<p><pre><code> \sum == (\total\N
long_le N 0
total
(
\total = (long_add total N)
total; # force evaluation; result is I (identity function)
sum total (long_sub N 1)
)
)
</code></pre>
However, <i>even that</i> doesn't always do the trick, particularly when you're dealing with higher-level values that aren't basic data types. The problem occurs generally when you build up a big "chain" of calculations with arbitrary values, and you have no simple way of forcing evaluation along the way.<p>This is, of course, the classic struggle between eager and lazy evaluation. But if I don't do the evaluation lazily, I can't define recursion in terms of the closed-form Y combinator, namely (Y F) = (F (Y F)). Instead I'd have to define it in terms of some kind of run-time "environment" using either key-value pairs or the de Bruijn positional technique -- something I've managed to avoid thanks to lazy evaluation in terms of pure combinators.<p>So I must say that although Fexl is an interesting pure-combinator lazy evaluation language, the jury is still out on its practical utility, in my humble opinion. I've used it in some projects as an embedded interpreter, but the application was quite constricted so you didn't encounter some of these larger issues.<p>That is why I emphasized this caveat earlier today: <a href="http://news.ycombinator.com/item?id=2717560" rel="nofollow">http://news.ycombinator.com/item?id=2717560</a> .