3 ms·
The case analysis for this stuff often seems incomplete. Let's say you're going to "pass something to a function", what're the common options: 1. Evaluate it i
by JonChesterfield 3y ago
The case analysis for this stuff often seems incomplete. Let's say you're going to "pass something to a function", what're the common options:
1. Evaluate it in the caller, pass the result. "Strict".
2. Build a thunk, pass the thunk, eval it on use. "Normal".
3. Build a thunk, pass the thunk, eval on first use, cache result. "Lazy".
4. Pass the value unchanged. "Macro?". Might be a better name.
5. Associate it with surrounding context, pass unchanged. "Hygienic macro".
6. Mangle things in a preprocessor, call the constructs "macro". Unrelated to the above but sometimes gets thrown in anyway.
In particular people are really prone to conflating lazy evaluation with macros. I think it's because the standard example of "if" only evaluating two of the three arguments happens to work with lazy evaluation or macros. Passing a thunk representing the evaluated form of an argument is a different thing to passing the unevaluated data. I see a lot of Haskell people saying they have no use for macros since the language is lazy - that might be true, but lazy is a subset of macro semantics so it's not immediate.
I'm not totally sure that being able to annotate a specific function as call-by-value or call-by-thunk (or call-by-name) is especially useful but you can certainly do it. It's a flag stored in the function that call dispatch checks, ideally at compile time. Annotating a function as either "strict" or "macro" works well in kernel (the lisp).
The other dimension is whether individual arguments should get specific calling conventions. For example, if would do well with the predicate given strict semantics while the consequent and antecedent have something else. Also interesting, not sure that's worth the bother either. I believe some prior art called this nlambda.
The other thought is you can annotate the call site instead of the function. That could give you a single function implementation used for strict or lazy evaluation, though that's probably syntactically confusing.
That's a rambling way to say I think the current setup of a language having a default calling convention and some way to choose a different one at function granularity seems fine.