Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.
Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.
-
fn(params) => expr
-
function(params) => expr
-
(params) ==> expr
-
(params) => expr
Note that 3 and 4 require a more powerful grammar and parser and that
4 has ambiguities. I think we can work around them by rules -- only
mentioning it because its popular because of JavaScript and do not
prefer this at all.
Note that 1 requires a new keyword.
Option 2 looks the best from that perspective but is by far the
longest; remember people are partially interested in this feature
because they want shorter closures which this doesn't really help.
This is why everyone is so divisive. All options have drawbacks.
Additionally some people don't like binding by value and would prefer
ref, and others really would be against by-ref.
Which brings me to an option I don't think was ever discussed on list:
It has quite a few good qualities:
- No new keywords
- Can choose between reference and value
- Concise
- Has precedence in C++, a major language
- Can be done in our existing grammar and parser[1]
- Can be extended to allow explicit binding of variables:
// all equivalent
// y is bound by value, array by reference
&, $y => $array[] = $x + $y
=, &$array => $array[] = $x + $y
And of course it does have downsides:
-
Symbol soup (it uses a lot of symbols)
-
A minor BC break. Empty arrays which are invoked as functions are
currently guaranteed to be errors at runtime and would have a new
valid meaning. Here's an example from inside an array literal:// error at runtime previously
[ => $x ]
// now an array with one item which is a closure that returns
its parameter
Sara pointed out that we'd need to keep a leading =
or &
in the
array to disambiguate from our array closure form.
Overall I'd prefer 1 or 5. What do you guys think?
[1]: I'm pretty sure it can be done but until it's done I can't say
so confidently because sometimes there are things lurking in our
grammar I forget about.
Den 2017-05-30 kl. 19:58, skrev Levi Morrison:
Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.
fn(params) => expr
function(params) => expr
(params) ==> expr
(params) => expr
Note that 3 and 4 require a more powerful grammar and parser and that
4 has ambiguities. I think we can work around them by rules -- only
mentioning it because its popular because of JavaScript and do not
prefer this at all.Note that 1 requires a new keyword.
Option 2 looks the best from that perspective but is by far the
longest; remember people are partially interested in this feature
because they want shorter closures which this doesn't really help.This is why everyone is so divisive. All options have drawbacks.
Additionally some people don't like binding by value and would prefer
ref, and others really would be against by-ref.Which brings me to an option I don't think was ever discussed on list:
It has quite a few good qualities:
- No new keywords
- Can choose between reference and value
- Concise
- Has precedence in C++, a major language
- Can be done in our existing grammar and parser[1]
- Can be extended to allow explicit binding of variables:
// all equivalent
// y is bound by value, array by reference
&, $y => $array[] = $x + $y
=, &$array => $array[] = $x + $yAnd of course it does have downsides:
Symbol soup (it uses a lot of symbols)
A minor BC break. Empty arrays which are invoked as functions are
currently guaranteed to be errors at runtime and would have a new
valid meaning. Here's an example from inside an array literal:// error at runtime previously
[ => $x ]
// now an array with one item which is a closure that returns
its parameterSara pointed out that we'd need to keep a leading
=
or&
in the
array to disambiguate from our array closure form.Overall I'd prefer 1 or 5. What do you guys think?
[1]: I'm pretty sure it can be done but until it's done I can't say
so confidently because sometimes there are things lurking in our
grammar I forget about.
As I said in the old thread, option 5 with ==> instead of => might
be an option. I think that would mitigate the minor BC break.
r//Björn
On Tue, May 30, 2017 at 12:16 PM, Björn Larsson
bjorn.x.larsson@telia.com wrote:
Den 2017-05-30 kl. 19:58, skrev Levi Morrison:
Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.
fn(params) => expr
function(params) => expr
(params) ==> expr
(params) => expr
Note that 3 and 4 require a more powerful grammar and parser and that
4 has ambiguities. I think we can work around them by rules -- only
mentioning it because its popular because of JavaScript and do not
prefer this at all.Note that 1 requires a new keyword.
Option 2 looks the best from that perspective but is by far the
longest; remember people are partially interested in this feature
because they want shorter closures which this doesn't really help.This is why everyone is so divisive. All options have drawbacks.
Additionally some people don't like binding by value and would prefer
ref, and others really would be against by-ref.Which brings me to an option I don't think was ever discussed on list:
It has quite a few good qualities:
- No new keywords
- Can choose between reference and value
- Concise
- Has precedence in C++, a major language
- Can be done in our existing grammar and parser[1]
- Can be extended to allow explicit binding of variables:
// all equivalent
// y is bound by value, array by reference
&, $y => $array[] = $x + $y
=, &$array => $array[] = $x + $yAnd of course it does have downsides:
Symbol soup (it uses a lot of symbols)
A minor BC break. Empty arrays which are invoked as functions are
currently guaranteed to be errors at runtime and would have a new
valid meaning. Here's an example from inside an array literal:// error at runtime previously
[ => $x ]
// now an array with one item which is a closure that returns
its parameterSara pointed out that we'd need to keep a leading
=
or&
in the
array to disambiguate from our array closure form.Overall I'd prefer 1 or 5. What do you guys think?
[1]: I'm pretty sure it can be done but until it's done I can't say
so confidently because sometimes there are things lurking in our
grammar I forget about.As I said in the old thread, option 5 with ==> instead of => might
be an option. I think that would mitigate the minor BC break.r//Björn
The compatibility issue is with [](params)
is that it is currently
an empty array literal that will be invoked; this is guaranteed to be
an error at runtime so it is unlikely to cause much trouble. A
trailing ==>
would not help here.
On Tue, May 30, 2017 at 12:16 PM, Björn Larsson
bjorn.x.larsson@telia.com wrote:Den 2017-05-30 kl. 19:58, skrev Levi Morrison:
Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.
fn(params) => expr
function(params) => expr
(params) ==> expr
(params) => expr
Note that 3 and 4 require a more powerful grammar and parser and that
4 has ambiguities. I think we can work around them by rules -- only
mentioning it because its popular because of JavaScript and do not
prefer this at all.Note that 1 requires a new keyword.
Option 2 looks the best from that perspective but is by far the
longest; remember people are partially interested in this feature
because they want shorter closures which this doesn't really help.This is why everyone is so divisive. All options have drawbacks.
Additionally some people don't like binding by value and would prefer
ref, and others really would be against by-ref.Which brings me to an option I don't think was ever discussed on list:
It has quite a few good qualities:
- No new keywords
- Can choose between reference and value
- Concise
- Has precedence in C++, a major language
- Can be done in our existing grammar and parser[1]
- Can be extended to allow explicit binding of variables:
// all equivalent
// y is bound by value, array by reference
&, $y => $array[] = $x + $y
=, &$array => $array[] = $x + $yAnd of course it does have downsides:
Symbol soup (it uses a lot of symbols)
A minor BC break. Empty arrays which are invoked as functions are
currently guaranteed to be errors at runtime and would have a new
valid meaning. Here's an example from inside an array literal:// error at runtime previously
[ => $x ]
// now an array with one item which is a closure that returns
its parameterSara pointed out that we'd need to keep a leading
=
or&
in the
array to disambiguate from our array closure form.Overall I'd prefer 1 or 5. What do you guys think?
[1]: I'm pretty sure it can be done but until it's done I can't say
so confidently because sometimes there are things lurking in our
grammar I forget about.As I said in the old thread, option 5 with ==> instead of => might
be an option. I think that would mitigate the minor BC break.r//Björn
The compatibility issue is with
[](params)
is that it is currently
an empty array literal that will be invoked; this is guaranteed to be
an error at runtime so it is unlikely to cause much trouble. A
trailing==>
would not help here.
You mentioned ability to explicitly specify binding as a possible
extension. However
[$var1, $var2]()
is not necessarily failing right now, it may be a valid array callable.
Nikita
On Tue, May 30, 2017 at 12:16 PM, Björn Larsson
bjorn.x.larsson@telia.com wrote:Den 2017-05-30 kl. 19:58, skrev Levi Morrison:
Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.
fn(params) => expr
function(params) => expr
(params) ==> expr
(params) => expr
Note that 3 and 4 require a more powerful grammar and parser and that
4 has ambiguities. I think we can work around them by rules -- only
mentioning it because its popular because of JavaScript and do not
prefer this at all.Note that 1 requires a new keyword.
Option 2 looks the best from that perspective but is by far the
longest; remember people are partially interested in this feature
because they want shorter closures which this doesn't really help.This is why everyone is so divisive. All options have drawbacks.
Additionally some people don't like binding by value and would prefer
ref, and others really would be against by-ref.Which brings me to an option I don't think was ever discussed on list:
It has quite a few good qualities:
- No new keywords
- Can choose between reference and value
- Concise
- Has precedence in C++, a major language
- Can be done in our existing grammar and parser[1]
- Can be extended to allow explicit binding of variables:
// all equivalent
// y is bound by value, array by reference
&, $y => $array[] = $x + $y
=, &$array => $array[] = $x + $yAnd of course it does have downsides:
Symbol soup (it uses a lot of symbols)
A minor BC break. Empty arrays which are invoked as functions are
currently guaranteed to be errors at runtime and would have a new
valid meaning. Here's an example from inside an array literal:// error at runtime previously
[ => $x ]
// now an array with one item which is a closure that returns
its parameterSara pointed out that we'd need to keep a leading
=
or&
in the
array to disambiguate from our array closure form.Overall I'd prefer 1 or 5. What do you guys think?
[1]: I'm pretty sure it can be done but until it's done I can't say
so confidently because sometimes there are things lurking in our
grammar I forget about.As I said in the old thread, option 5 with ==> instead of => might
be an option. I think that would mitigate the minor BC break.r//Björn
The compatibility issue is with
[](params)
is that it is currently
an empty array literal that will be invoked; this is guaranteed to be
an error at runtime so it is unlikely to cause much trouble. A
trailing==>
would not help here.You mentioned ability to explicitly specify binding as a possible extension.
However[$var1, $var2]()
is not necessarily failing right now, it may be a valid array callable.
Nikita
As already mentioned we must maintain a leading =
or &
:
=, $var1, $var2
=, $var1, $var2
Sorry if that was unclear.
You mentioned ability to explicitly specify binding as a possible extension.
However[$var1, $var2]()
is not necessarily failing right now, it may be a valid array callable.
Nikita
As already mentioned we must maintain a leading
=
or&
:=, $var1, $var2
=, $var1, $var2Sorry if that was unclear.
Oops, forgot to change the bottom line:
=, $var1, $var2
&, $var1, $var2
The first line means "bind any implicit usages of variables by value,
and also bind $var1 and $var2 by value".
The second line means "bind any implicit usages of variables by
reference, and bind $var1 and $var2 by value".
This exists in C++ but C++ allows you to drop the leading =
or &
.
We cannot, for precisely the reason you mentioned.
Den 2017-05-30 kl. 20:24, skrev Levi Morrison:
On Tue, May 30, 2017 at 12:16 PM, Björn Larsson
bjorn.x.larsson@telia.com wrote:Den 2017-05-30 kl. 19:58, skrev Levi Morrison:
Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.1. fn(params) => expr 2. function(params) => expr 3. (params) ==> expr 4. (params) => expr
Note that 3 and 4 require a more powerful grammar and parser and that
4 has ambiguities. I think we can work around them by rules -- only
mentioning it because its popular because of JavaScript and do not
prefer this at all.Note that 1 requires a new keyword.
Option 2 looks the best from that perspective but is by far the
longest; remember people are partially interested in this feature
because they want shorter closures which this doesn't really help.This is why everyone is so divisive. All options have drawbacks.
Additionally some people don't like binding by value and would prefer
ref, and others really would be against by-ref.Which brings me to an option I don't think was ever discussed on list:
5. [](params) => expr // binds no values [=](params) => expr // binds by value [&](params) => expr // binds by reference
It has quite a few good qualities:
- No new keywords - Can choose between reference and value - Concise - Has precedence in C++, a major language - Can be done in our existing grammar and parser[1] - Can be extended to allow explicit binding of variables: // all equivalent // y is bound by value, array by reference [&, $y]($x) => $array[] = $x + $y [=, &$array]($x) => $array[] = $x + $y
And of course it does have downsides:
- Symbol soup (it uses a lot of symbols) - A minor BC break. Empty arrays which are invoked as functions are
currently guaranteed to be errors at runtime and would have a new
valid meaning. Here's an example from inside an array literal:// error at runtime previously [ []($x) => $x ] // now an array with one item which is a closure that returns
its parameter
Sara pointed out that we'd need to keep a leading
=
or&
in the
array to disambiguate from our array closure form.Overall I'd prefer 1 or 5. What do you guys think?
[1]: I'm pretty sure it can be done but until it's done I can't say
so confidently because sometimes there are things lurking in our
grammar I forget about.As I said in the old thread, option 5 with ==> instead of => might
be an option. I think that would mitigate the minor BC break.r//Björn
The compatibility issue is with[](params)
is that it is currently
an empty array literal that will be invoked; this is guaranteed to be
an error at runtime so it is unlikely to cause much trouble. A
trailing==>
would not help here.
Ok, but how about having ==> to improve readability and make it
less ambiguous & quicker to read the code. Also enable the syntax:
- (params) ==> expr // binds no values.
r//Björn
Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.
fn(params) => expr
function(params) => expr
(params) ==> expr
(params) => expr
Note that 3 and 4 require a more powerful grammar and parser and that
4 has ambiguities. I think we can work around them by rules -- only
mentioning it because its popular because of JavaScript and do not
prefer this at all.Note that 1 requires a new keyword.
Option 2 looks the best from that perspective but is by far the
longest; remember people are partially interested in this feature
because they want shorter closures which this doesn't really help.This is why everyone is so divisive. All options have drawbacks.
Additionally some people don't like binding by value and would prefer
ref, and others really would be against by-ref.Which brings me to an option I don't think was ever discussed on list:
It has quite a few good qualities:
- No new keywords
- Can choose between reference and value
- Concise
- Has precedence in C++, a major language
- Can be done in our existing grammar and parser[1]
- Can be extended to allow explicit binding of variables:
// all equivalent
// y is bound by value, array by reference
&, $y => $array[] = $x + $y
=, &$array => $array[] = $x + $yAnd of course it does have downsides:
Symbol soup (it uses a lot of symbols)
A minor BC break. Empty arrays which are invoked as functions are
currently guaranteed to be errors at runtime and would have a new
valid meaning. Here's an example from inside an array literal:// error at runtime previously
[ => $x ]
// now an array with one item which is a closure that returns
its parameterSara pointed out that we'd need to keep a leading
=
or&
in the
array to disambiguate from our array closure form.Overall I'd prefer 1 or 5. What do you guys think?
I think 5 is terrible from a readability point of view. As you said it:
"symbol soup".
For a similar reason, I would discount 1 as being too vague. And hence
would prefer 2, but I'm not actually convinced about this feature at
all.
cheers,
Derick
--
https://derickrethans.nl | https://xdebug.org | https://dram.io
Like Xdebug? Consider a donation: https://xdebug.org/donate.php
twitter: @derickr and @xdebug
Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.
I was just pondering alternative approaches to stop the => token being ambiguous, and wondered if surrounding the whole expression with braces could work:
{ => $bound * 2 }
{ $a, $b => $a * $b }
I believe this eliminates the ambiguity with array notation, and is more concise than pretty much every alternative. I'm my opinion, grouping the arguments and body would make it more readable in context, as well.
The only potential difficulty with parsing would be that this would technically be valid:
if ( $test ) { $a => $a * 5 };
Because it means this:
if ( $test ) { function ($a) { return $a * 5; }; }
It's not ambiguous, but I don't know if this and similar constructs would cause problems with backtracking in the parser. Worst case, they could probably be defined as illegal, since it's pretty hard to construct a use case for such a thing.
Regards,
--
Rowan Collins
[IMSoP]
Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.I was just pondering alternative approaches to stop the => token being ambiguous, and wondered if surrounding the whole expression with braces could work:
{ => $bound * 2 }
{ $a, $b => $a * $b }I believe this eliminates the ambiguity with array notation, and is more concise than pretty much every alternative. I'm my opinion, grouping the arguments and body would make it more readable in context, as well.
This does not work. We permit expressions as statements and we also
allow empty blocks:
{
$a = $foo;
}
These will conflict in the grammar.
On Wed, May 31, 2017 at 7:36 AM, Rowan Collins
rowan.collins@gmail.com wrote:I was just pondering alternative approaches to stop the => token
being ambiguous, and wondered if surrounding the whole expression with
braces could work:{ => $bound * 2 }
{ $a, $b => $a * $b }This does not work. We permit expressions as statements and we also
allow empty blocks:{
$a = $foo;
}These will conflict in the grammar.
Yeah, I wondered if that would be the case, but don't know enough about how parsers work to be sure one way or the other. It's not ambiguous, because the => wouldn't be legal there, but I guess it's "too late" by the time that token is reached. :(
Regards,
--
Rowan Collins
[IMSoP]
My preferences: 1, 3, 4, 5, (big void), 2.
I actually like 4 the most but I get that that might not be practical if it leads to unexpected behaviour.
I can’t think of a scenario where capturing by reference would be helpful in a single line closure. 5 just adds additional complexity with no additional benefit IMHO.
Also, in response to Rowan, a Ruby-style syntax should be possible though:
{|param| expr}
Only caveat is that the || would be required if there are no parameters:
{|| expr}
Levi has mentioned this one before. You could even omit the braces here.
Ilija
Internals,
The previous discussion thread has died down significantly and so I'd
like to start a new one to refocus. This message has some redundant
information by design so people don't have to reference the other
thread so much.Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.
fn(params) => expr
function(params) => expr
(params) ==> expr
(params) => expr
Note that 3 and 4 require a more powerful grammar and parser and that
4 has ambiguities. I think we can work around them by rules -- only
mentioning it because its popular because of JavaScript and do not
prefer this at all.Note that 1 requires a new keyword.
Option 2 looks the best from that perspective but is by far the
longest; remember people are partially interested in this feature
because they want shorter closures which this doesn't really help.This is why everyone is so divisive. All options have drawbacks.
Additionally some people don't like binding by value and would prefer
ref, and others really would be against by-ref.Which brings me to an option I don't think was ever discussed on list:
=> expr // binds no values
= => expr // binds by value
& => expr // binds by referenceIt has quite a few good qualities:
- No new keywords
- Can choose between reference and value
- Concise
- Has precedence in C++, a major language
- Can be done in our existing grammar and parser[1]
- Can be extended to allow explicit binding of variables:
// all equivalent
// y is bound by value, array by reference
&, $y => $array[] = $x + $y
=, &$array => $array[] = $x + $yAnd of course it does have downsides:
- Symbol soup (it uses a lot of symbols)
- A minor BC break. Empty arrays which are invoked as functions are
currently guaranteed to be errors at runtime and would have a new
valid meaning. Here's an example from inside an array literal:// error at runtime previously
[ => $x ]
// now an array with one item which is a closure that returns
its parameterSara pointed out that we'd need to keep a leading
=
or&
in the
array to disambiguate from our array closure form.Overall I'd prefer 1 or 5. What do you guys think?
[1]: I'm pretty sure it can be done but until it's done I can't say
so confidently because sometimes there are things lurking in our
grammar I forget about.
I can’t think of a scenario where capturing by reference would be helpful in
a single line closure.
function($item) use($array) {
return $array[] = $item;
}
It's actually one of the first closures I discovered in the wild when
looking for closures that would be candidates for the short form.
I think it’s worth noting that the people most excited about arrow functions are probably the ones with a more functional approach.
Those kinds of side effects are usually avoided.
I also have nothing against capturing by reference. Given the last example:
fn($item) => $array[] = $item
All you have to do is glance a few characters to the left to see that $array is not a parameter and thus must be captured. And again, since it’s pretty obvious to see if you’re mutating the variable (spot the equal sign) this shouldn’t cause too many surprises. Only scenario I can think of is passing it to another function as a reference. But then again, no one ever complains about that in other languages.
Ilija
I can’t think of a scenario where capturing by reference would be helpful in
a single line closure.function($item) use($array) {
return $array[] = $item;
}It's actually one of the first closures I discovered in the wild when
looking for closures that would be candidates for the short form.
Based on the discussion there are a few different syntax choices
people liked. Overall it's a feature that people seem to want but
everyone seems to prefer a different syntax choice.
- fn(params) => expr
- function(params) => expr
- (params) ==> expr
- (params) => expr
=> expr // binds no values
= => expr // binds by value
& => expr // binds by reference
As a userland developer, I've been waiting/hoping for short arrow
functions for a long time!
Option 3 seems like the most obvious choice, since that's the
same syntax Hack uses. Would it be very difficult to implement the
parser changes necessary for this syntax? Or is there some other
downside to a more powerful grammar/parser (e.g. worse performance)?
If option 3 isn't viable, my next preference would be option 1.
Presumably the drawback of a new symbol is that it might break
existing code using fn
as the name of a class or function.
However, using a new symbol would arguably enable more readable
code than the other options.
Option 2 is not only lengthy, but it also could be confusing
since it reuses the function
symbol for something that isn't
a normal function.
Option 5 seems overly complex and hard to read.
Whether option 1, 2, or 3 is used, to me it seems that capturing by
reference would be the most useful and intuitive behavior. It's
intuitive since implicit capture makes it feel like all the captured
variables are in the same scope.