Clarify evaluation order in language ref
Aaron Sikes brought this up in Slack:
The evaluation semantics of function application is applicative order Call-by-Value. In the expression
f x y,xandyare fully evaluated in left-to-right order, thenfis fully evaluated, thenxandyare substituted into the body off, and lastly the body is evaluated
Originally I was thinking this should be changed to:
The evaluation semantics of function application is applicative order Call-by-Value. In the expression
f x:fis fully evaluated, thenx, thenxis substituted into the body off, and lastly the body is evaluated. This rule also covers expressions likeg a b, which are parsed as(g a) b.
But I don't think we want to guarantee one at a time evaluation order like this. For instance, consider:
g x =
Stream.emit 1
(y -> 12)
> Stream.toList 'let g (Stream.emit 0) (Stream.emit 2)
This currently will produce [0,2,1] - it evaluates left to right all the arguments being supplied, and then does substitutions and evaluation of the body. And this is what you want, since the one at a time order is crazy inefficient and would involve building N temporary closures just to pass N args to a function. I don't think any real language uses this.
So I think maybe the current description is not bad.
Perhaps just add a note that this diverges from the normal model for performance?
It might be worth including an example like what I gave above just to clarify the matter further. I'd be inclined to do that and leave it at that.
I'm not sure how many people would be expecting the one-at-a-time evaluation order, given that it is so rarely used in real languages, so mentioning that might just be confusing for some people.