On 20 March 2025 07:06:16 GMT, Edmond Dantes <edmond.ht@gmail.com> wrote:
I forgot to include some relevant text to quote, but I absolutely agree that syntax #2 should be our default.
I think the only thing I'm still unsure of is whether we need anything else on top of it, and if so what.
4: keyword inline_function
This option can be considered a special case of option #2. And that’s
exactly the case.
In terms of the grammar, it is a special case of #1, because the inline_function is evaluated in full as an expression, and then we *fabricate* a zero-argument function call to the resulting value.
Or to use your breakdown, #2 includes both elements we need: the callable, and the parameter list; #1, #3 and #4 all include just one element, the callable, and make the assumption that the argument list is empty.
This is less confusing, but has one surprising effect: if you refactor
the inline function to be a variable, you have to replace it with "$foo()"
not just "$foo", so that you hit rule #2
A completely logical transformation that does not contradict anything.
This example maybe helps explain why this might be surprising:
function foo() {
yield function() { whatever(); };
spawn function() { whatever(); };
return function() { whatever(); };
}
Three identical values, so let's replace with a shared variable:
function foo() {
$action = function() { whatever(); }
yield $action;
spawn $action;
return $action;
}
Looks right, but isn't - we needed to write "spawn $action()". Not a huge rule to learn, but a fairly arbitrary one from the point of view of the user.
The meaning of option #4 is different:
1. I want to define a closure at point A.
2. I want to use it at point A.
3. Point A knows what the closure looks like, so there is no need to
define arguments — it's the same place in the code.
This feels like a stretch to me: it's not that anything knows what arguments to pass, it's just that the syntax is restricted to passing no arguments. (You could presumably define a closure that *expects* arguments, but couldn't actually pass any, within the shorthand syntax.)
Therefore, the `keyword closure` does not break the clarity of the
description, whereas the `keyword $something` does.
From the user's point of view, it might be just as obvious that the closure put into a variable two lines above can also be called with zero arguments. It's only as unclear as any other code involving a variable - if it's badly named and defined 100 lines away, you'll have a problem, but no syntax can solve that.
6: keyword_bar function_call
This contains even more characters than the original and yet adds nothing
useful.
I tried to make clear that the keywords could stand in for anything. There's no reason that "two different keywords" has to mean "more characters". It could be "go foo();" and "run $closure;", and the point I was trying to illustrate would still hold.
But I do want to come back to the question I asked in my last e-mail:
what is the use case we're trying to cater for?
Goal #1: Improve code readability. Make it easier to understand.
Goal #2: Reduce the number of characters.
That's answering a different question, I want to know *what code* we are optimizing the readability of. What is the user trying to do, which we want to make readable and shorter?
Specifically, what is the use case where syntax #2, "spawn function_call" is not good enough, leading us to add a special case into the grammar.
The advantage of option #4 is not just that it removes parentheses, but
also that it keeps the code readable.
One is a consequence of the other. I don't disagree, but I personally find that introducing a temporary variable has much the same effect, without any special case grammar.
The second reason why option #4 makes sense: it will be used frequently.
Will it? By who, when? Honest question, and comes back to my point about identifying the use case.
For example, `spawn fn() => file_get_content()` won’t be, because it
doesn’t make sense.
If return values end up somewhere, I don't think it would be hard to come up with examples that were slightly more than one function call, but still fit in a single-expression closure.
Rowan Tommins
[IMSoP]