Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.
Here is an example of an existing closure:
function ($x) use ($arr) {
return $arr[$x];
}
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
More details are in the RFC. The implementation currently has no
known issues and is ready for you to download, build and test, which
we encourage you to do.
We look forward to a productive discussion period and are happy to
answer questions.
For historical purposes, the revision of this RFC is currently at
1485798604.
Levi Morrison levim@php.net schrieb am Mo., 30. Jan. 2017, 18:55:
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.Here is an example of an existing closure:
function ($x) use ($arr) { return $arr[$x]; }
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
More details are in the RFC. The implementation currently has no
known issues and is ready for you to download, build and test, which
we encourage you to do.
https://3v4l.org has a feature branch for arrow functions, you can find it
in the preview select box for playing around and in the RFC tab after a
full execution.
We look forward to a productive discussion period and are happy to
answer questions.
For historical purposes, the revision of this RFC is currently at
1485798604.
Levi Morrison levim@php.net schrieb am Mo., 30. Jan. 2017, 18:55:
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.Here is an example of an existing closure:
function ($x) use ($arr) { return $arr[$x]; }
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
More details are in the RFC. The implementation currently has no
known issues and is ready for you to download, build and test, which
we encourage you to do.https://3v4l.org has a feature branch for arrow functions, you can find
it
in the preview select box for playing around and in the RFC tab after a
full execution.We look forward to a productive discussion period and are happy to
answer questions.
For historical purposes, the revision of this RFC is currently at
1485798604.--
Looking good. Really excited for something like this in PHP.
Just a heads up, the section in the introduction that refers to other
languages having similar syntax still has a TODO in it. I agree that some
references to other languages' implementations (ES6 comes to mind) would be
a nice addition.
Awesome work,
Guy
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.
Firstly, I like this proposal a lot more than the previous, so thank you
for working on this based on previous discussion. In particular, I'm
glad to see it focused on single expressions with implicit return, as I
think that's where it has most value.
A few comments:
ThisRFC does support type declarations for parameters and return types.
An example of the syntax for this would be good, particularly how the
return type fits the syntax (which may conflict with my suggestion below).
The implementation currently supports static closures, for example |static fn($x) => static::get($x)|.
I was initially confused by this paragraph, because I was unaware that
static closures existed. I'm still not entirely sure why they exist,
but for anyone else wondering, here's what they currently look like:
http://php.net/manual/en/functions.anonymous.php#functions.anonymous-functions.static
Finally, my personal preference is still for a syntax that encloses the
whole definition somehow, and since we need the fn keyword anyway, I
wonder about stretching the brackets around the whole definition, e.g.
fn($x => $x * 2).
Personally, I find this:
->reduce(fn($tmp, $v => $tmp + $v), 0)
easier to mentally parse than this:
->reduce(fn($tmp, $v) => $tmp + $v, 0)
because you only have to match brackets to see where the ", 0" belongs.
I also think it would make combining closures clearer if they were
nested rather than associative (I guess those used to reading Haskell
will probably disagree with me):
$complement = fn($f) => fn(... $args) => !$f(... $args)
vs
$complement = fn($f => fn(... $args => !$f(... $args)))
Regards,
--
Rowan Collins
[IMSoP]
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.Firstly, I like this proposal a lot more than the previous, so thank you for
working on this based on previous discussion. In particular, I'm glad to see
it focused on single expressions with implicit return, as I think that's
where it has most value.A few comments:
ThisRFC does support type declarations for parameters and return types.
An example of the syntax for this would be good, particularly how the return
type fits the syntax (which may conflict with my suggestion below).
They go in the same places as regular functions. I'll update the RFC
later with examples, but for now here is an example that takes an
integer and returns it, which type declarations:
fn (int $x): int => $x
Levi Morrison wrote:
> Here is an example of an existing closure:
>
> function ($x) use ($arr) {
> return $arr[$x];
> }
>
> This RFC proposes syntax and semantics to simplify this common usage to:
>
> fn($x) => $arr[$x]
>
Is it necessary to introduce a new keyword, fn?
I think you'd get a similar benefit from:
function($x) => $arr[$x]
Likewise, is it necessary to restrict auto-capture to the => syntax?
Couldn't we allow the following?
function ($x) {
return $arr[$x];
}
That being said, I broadly support your goals.
--
Andrea Faulds
https://ajf.me/
> Hi Levi,
>
> Levi Morrison wrote:
> > Here is an example of an existing closure:
> >
> > function ($x) use ($arr) {
> > return $arr[$x];
> > }
> >
> > This RFC proposes syntax and semantics to simplify this common usage to:
> >
> > fn($x) => $arr[$x]
> >
>
> Is it necessary to introduce a new keyword, fn?
>
> I think you'd get a similar benefit from:
>
> function($x) => $arr[$x]
>
> Likewise, is it necessary to restrict auto-capture to the => syntax?
> Couldn't we allow the following?
>
> function ($x) {
> return $arr[$x];
> }
>
This looks too similar to the current syntax, just ignoring the use()
statement. I would add a concurance that => syntax is slightly awkward when
used within an array element
$a = [
'func' => fn($x) => Class::method($x),
];
But I'm not overly certain of a different syntax to handle this.
I would support expanding to function over fn, to make it more
readable/keep the same reserved word. (Although not too certain to the
complexity in the parser)
Otherwise +1, I like this.
--
Dave
David Walker wrote:
>
>
>> Is it necessary to introduce a new keyword, fn?
>>
>> I think you'd get a similar benefit from:
>>
>> function($x) => $arr[$x]
>>
>> Likewise, is it necessary to restrict auto-capture to the => syntax?
>> Couldn't we allow the following?
>>
>> function ($x) {
>> return $arr[$x];
>> }
>>
>
> This looks too similar to the current syntax, just ignoring the use()
> statement.
That's the idea. I'd prefer it if auto-capture was not restricted to
single-expression functions (“arrow functions”). Though arrow functions
make most sense with auto-capture, it doesn't need to be stricted to them.
Thanks.
--
Andrea Faulds
https://ajf.me/
That's the idea. I'd prefer it if auto-capture was not restricted to
single-expression functions (“arrow functions”). Though arrow
functions make most sense with auto-capture, it doesn't need to be
stricted to them.
I respectfully disagree completely.
Variable scope in PHP is very simple: inside a function, all variables
are local to that function, and fetching them from anywhere else
requires them to be enumerated with a specific keyword (e.g. global,
static, use). The only exceptions are superglobals, the magic $this, and
the odd mysterious materialisation like $http_response_header 1. This
means you can look at a function in isolation, no matter how it's
declared, and see where every variable comes from.
Auto-capture with a full function body would be throwing out that
principle. If a variable was read from before it was assigned to, that
might mean it was unset, or it might mean it was imported from an
outer scope. Changing the variable name in the outer scope might or
might not require you to look for that variable name in the closure;
adding a variable in the outer scope might accidentally change the
behaviour of the closure; and so on.
This is a lot easier in Javascript, although still a cause of confusion,
because you can carry on until you hit "var" or "let". I understand C#
also has auto-importing closures, but it too requires variables to be
declared at some point.
Initially, I was sceptical of auto-capture even with a single
expression, but I've come round to its usefulness in short closures.
Limiting it to a single expression ensures it's short, and means you can
assume that all variables in the expression are imported other than
those listed as parameters.
Just an opinion, obviously, but I'm glad that the current proposal is
limited to and optimised for this single expression case.
Regards,
--
Rowan Collins
[IMSoP]
That's the idea. I'd prefer it if auto-capture was not restricted to
single-expression functions (“arrow functions”). Though arrow functions
make most sense with auto-capture, it doesn't need to be stricted to them.
This goes against a very basic characteristic of PHP. The fact that you
have to be explicit about globals and outer scope variables leaves you with
a clean sandbox with no side effects inside your function. Changing that,
especially after the fact for existing closures, is a complete non-starter
and would subtly break a ton of code.
The reason it is feasible to do this for single-expression closures in this
short form syntax is that you don't typically need a local scope at all for
these short closures and the syntax doesn't convey the idea that you would
have a local scope.
-Rasmus
The reason it is feasible to do this for single-expression closures in this
short form syntax is that you don't typically need a local scope at all for
these short closures and the syntax doesn't convey the idea that you would
have a local scope.
Does this mean, in the context of this RFC, that short-form lambdas
won't have their own scope though? I think it's not clear from RFC.
Example:
// would this create $ret in the outer scope assuming $ret was not
// defined
array_map(fn($elt) => $ret[] = $elt, [1]);
var_dump($ret); // NULL
or array(1) ?
Current implementation (available on 3v4l.org) does create a local
scope, but it should probably be explicitly stated in the RFC (and
docs, should the RFC get accepted).
The reason it is feasible to do this for single-expression closures in
this
short form syntax is that you don't typically need a local scope at all
for
these short closures and the syntax doesn't convey the idea that you
would
have a local scope.Does this mean, in the context of this RFC, that short-form lambdas
won't have their own scope though? I think it's not clear from RFC.Example:
// would this create $ret in the outer scope assuming $ret was not
// defined
array_map(fn($elt) => $ret[] = $elt, [1]);
var_dump($ret); //NULL
or array(1) ?Current implementation (available on 3v4l.org) does create a local
scope, but it should probably be explicitly stated in the RFC (and
docs, should the RFC get accepted).
I actually tend to think of these short-form lambdas as not having a local
scope. That might sound a bit odd, but let me demonstrate:
$f = fn() => print($var=1);
$f();
echo $var;
This should output 1 and then give a notice about $var being undefined on
the echo. You probably think of $var as being a local scope variable here,
but really it isn't. It is an imported variable that happened to not exist
in the outer scope and it was assigned a value in the inner scope, but that
assignment can't leak back out so it is still unassigned in the outer
scope. I think of it this way, because if you do:
$var = 3;
$f = fn() => print(++$var);
$f();
echo $var;
You should see: 43
$var did not originate in the inner scope, it was imported from the outer
scope by-value and reassigned. To me, automatic import precludes the notion
of a local scope entirely. When a variable you use within the lambda isn't
defined in the outer scope it acts exactly like a locally scoped variable,
but it isn't, because defining it in the outer scope could potentially
affect it depending on how it is used within the lambda.
-Rasmus
You probably think of $var as being a local scope variable here,
but really it isn't. It is an imported variable that happened to not exist
in the outer scope and it was assigned a value in the inner scope, but that
assignment can't leak back out so it is still unassigned in the outer
scope.
I'm very confused by your terminology here. You definitely talk about
two distinct scopes, "the inner scope" and "the outer scope", but then
you assert that there is no "local scope". Surely the "inner scope" is
"local" to the closure?
In actual fact, it's local to each invocation of the closure, because
the function is initialised with the original values each time. For
instance:
$a = 1;
$fn = fn() => ++$a;
$a = 42;
echo $fn(), ' ', $fn, ' ', $fn();
This echoes 2 2 2, not 2 3 4, because the $a being incremented is new
for each invocation. Nor does it echo 43 43 43, because it is only the
value of $a that is captured, not its reference.
I think the best description is this: the closure has its own scope,
which is initialised on each invocation with a copy of another scope
taken when it was defined.
To go back to Bruce's question, the original statement was:
you don't typically need a local scope at all for these short closures
The important point here is that within a single expression there is
very little you can meaningfully do with a local scope other than read
from it. It's generally a bad idea to alter the value of a variable and
expect another part of the same expression to see the new value, because
you can't always predict how the compiler will rewrite the expression (I
think an example of this came up on the list a while back, but can't
think how to search for it).
So for most purposes you can consider all the automatically imported
variables to be immutable values, which makes their scope much less
relevant.
Regards,
--
Rowan Collins
[IMSoP]
On Wed, Feb 1, 2017 at 3:06 PM, Rowan Collins rowan.collins@gmail.com
wrote:
You probably think of $var as being a local scope variable here,
but really it isn't. It is an imported variable that happened to not exist
in the outer scope and it was assigned a value in the inner scope, but
that
assignment can't leak back out so it is still unassigned in the outer
scope.I'm very confused by your terminology here. You definitely talk about two
distinct scopes, "the inner scope" and "the outer scope", but then you
assert that there is no "local scope". Surely the "inner scope" is "local"
to the closure?In actual fact, it's local to each invocation of the closure, because
the function is initialised with the original values each time. For
instance:$a = 1;
$fn = fn() => ++$a;
$a = 42;
echo $fn(), ' ', $fn, ' ', $fn();This echoes 2 2 2, not 2 3 4, because the $a being incremented is new for
each invocation. Nor does it echo 43 43 43, because it is only the value of
$a that is captured, not its reference.I think the best description is this: the closure has its own scope, which
is initialised on each invocation with a copy of another scope taken when
it was defined.To go back to Bruce's question, the original statement was:
you don't typically need a local scope at all for these short closures
The important point here is that within a single expression there is very
little you can meaningfully do with a local scope other than read from it.
It's generally a bad idea to alter the value of a variable and expect
another part of the same expression to see the new value, because you can't
always predict how the compiler will rewrite the expression (I think an
example of this came up on the list a while back, but can't think how to
search for it).So for most purposes you can consider all the automatically imported
variables to be immutable values, which makes their scope much less
relevant.
It is mostly a semantic thing. Of course you have a local scope, but
because of automatic import you don't have a clean local scope so it is not
like the function-local scope people are used to. Like you said, it is a
mostly immutable copy of the outer scope.
But people need to understand that the immutability doesn't apply to class
variables because there is no automatic clone done on outer scope objects.
class C {
static $var = 1;
}
$f = fn() => C::$var++;
echo $f().$f().$f();
will output 123 and the value of C::$var would be 4 after this.
-Rasmus
Hi Andrea, All,
Is it necessary to introduce a new keyword, fn?
I think you'd get a similar benefit from:
function($x) => $arr[$x]
Likewise, is it necessary to restrict auto-capture to the => syntax? Couldn't we allow the following?
function ($x) {
return $arr[$x];
}
I agree that the fn
keyword isn’t really necessary. I’ve never quite understood how arrow functions with implied returns etc are supposed to make for more readable code, but if they’re going to be part of the language please at least keep some consistency with regular closures.
In the case that regular closures got auto-capture, would a use($foo, $bar, $baz)
segment on a closure still be honoured (i.e. disable auto-capture), and would it have any impact (positive or negative) on performance/memory usage? After several years of JS closure ‘fun’ I kind of like that with PHP you only inherit the variables you explicitly use()
in closures.
Cheers
Stephen
Am 31.01.2017 um 05:53 schrieb Stephen Reay:
Hi Andrea, All,
Is it necessary to introduce a new keyword, fn?
I think you'd get a similar benefit from:
function($x) => $arr[$x]
Likewise, is it necessary to restrict auto-capture to the => syntax? Couldn't we allow the following?
function ($x) {
return $arr[$x];
}I agree that the
fn
keyword isn’t really necessary. I’ve never quite understood how arrow functions with implied returns etc are supposed to make for more readable code, but if they’re going to be part of the language please at least keep some consistency with regular closures.In the case that regular closures got auto-capture, would a
use($foo, $bar, $baz)
segment on a closure still be honoured (i.e. disable auto-capture), and would it have any impact (positive or negative) on performance/memory usage? After several years of JS closure ‘fun’ I kind of like that with PHP you only inherit the variables you explicitlyuse()
in closures.
I like the general idea, too. But with similar feelings for:
-
Introducing a second keyword for closures is confusing - and mor
confusing if they are basically the same words -
Also I like the "use" keyword you have to define your variables
-> Would it be helpful to allow "function () use (*) {}" to inline
all available variables? -
Or based on Rowans idea to stretching the brackets but using the
function keyword:function($x => $arr[$x])
Thanks
Marc
Cheers
Stephen
Hi Marc,
Marc Bennewitz wrote:
Also I like the "use" keyword you have to define your variables
-> Would it be helpful to allow "function () use (*) {}" to inline
all available variables?
I did think of that, but it's not as concise as not having to specify
use
at all. You could take the opposite approach and auto-capture by
default, but permit use ()
to capture nothing, alongside regular use (...)
for explicit capture of variables.
Thanks.
--
Andrea Faulds
https://ajf.me/
Am 31.01.2017 um 21:45 schrieb Andrea Faulds ajf@ajf.me:
Hi Marc,
Marc Bennewitz wrote:
Also I like the "use" keyword you have to define your variables
-> Would it be helpful to allow "function () use (*) {}" to inline
all available variables?I did think of that, but it's not as concise as not having to specify
use
at all. You could take the opposite approach and auto-capture by default, but permituse ()
to capture nothing, alongside regularuse (...)
for explicit capture of variables.Thanks.
--
Andrea Faulds
https://ajf.me/
Hey Andrea,
you realize that you are actually proposing quite a heavy BC break?
Any code which uses the same variable than in parent scope and does not overwrite it before its first usage will break.
E.g.:
$foo = [1,2,3];
// more code working on foo
doSomeAction(function($bar) {
// waaah, $foo is now [1,2,3] instead of null
foreach ($bar as $x) {
$foo[] = $x;
}
return $foo;
});
Or what I have seen in real code:
$response_text = "Do action";
store_response($response_text);
// much later
doSomeAction(function() {
$response_text .= "Do other action"; // Note that accidental .= instead of =
store_response($response_text);
});
The code still works as expected, because things are NULL-initialized currently.
Now with implicit auto-capture this is breaking. No ahead of time errors like parse or compile errors, which warn you. Just subtly breaking. Depending on where it's done, it may not be even noticed soon (variables with the same name at different places tend to have compatible types), just misbehave subtly.
This is not acceptable.
Now, when you suggest "function($bar) use (*) => $foo + $bar", I feel like half the point of the RFC, the conciseness of the syntax, is missed.
And I'd also reject function($bar) => $foo + $bar as this would mean the "function" keyword introducing different semantics depending on what follows. [apart from being still not as concise as "fn"]
Thanks,
Bob
Hi Andrea, All,
Is it necessary to introduce a new keyword, fn?
I think you'd get a similar benefit from:
function($x) => $arr[$x]
Likewise, is it necessary to restrict auto-capture to the =>
syntax? Couldn't we allow the following?function ($x) {
return $arr[$x];
}I agree that the
fn
keyword isn’t really necessary. I’ve never
quite understood how arrow functions with implied returns etc are
supposed to make for more readable code, but if they’re going to be
part of the language please at least keep some consistency with
regular closures.
Yes, I also think that keeping the function keyword would be better.
In the case that regular closures got auto-capture, would a
use($foo, $bar, $baz)
segment on a closure still be honoured (i.e.
disable auto-capture), and would it have any impact (positive or
negative) on performance/memory usage? After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.
Wouldn't there be just too many existing closures, which do not use
use
but (maybe) expect a clean scope?
--
Regards,
Mike
Hey,
Am 31.01.2017 um 11:23 schrieb Michael Wallner mike@php.net:
Hi Andrea, All,
Is it necessary to introduce a new keyword, fn?
I think you'd get a similar benefit from:
function($x) => $arr[$x]
Likewise, is it necessary to restrict auto-capture to the =>
syntax? Couldn't we allow the following?function ($x) {
return $arr[$x];
}I agree that the
fn
keyword isn’t really necessary. I’ve never
quite understood how arrow functions with implied returns etc are
supposed to make for more readable code, but if they’re going to be
part of the language please at least keep some consistency with
regular closures.Yes, I also think that keeping the function keyword would be better.
In the case that regular closures got auto-capture, would a
use($foo, $bar, $baz)
segment on a closure still be honoured (i.e.
disable auto-capture), and would it have any impact (positive or
negative) on performance/memory usage? After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.Wouldn't there be just too many existing closures, which do not use
use
but (maybe) expect a clean scope?
The RFC is exclusively proposing single-expression short Closures.
We do NOT want multi-statement short Closures; it is a feature that generic Closures need an "use ($foo, $bar)".
This vastly improves readability and debuggability - it basically tells you whether the variables inside the code are imported or not. As Stephen Reay notes:
After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.
So, auto-import for generic Closures definitely isn't an option.
Just on short, single-line Closures there is no benefit to "use ()", as EVERY variable used in the short Closure is supposed to be an imported variable. There is no point in forcing the user to distinguish between imported and local variable here.
Also, using "fn" in favor of "function" has the advantage of less clutter in one line. Compare
array_map(fn($x) => $x + 1)
to
array_map(function($x) => $x + 1)
The syntactical construction is already pretty clearly showing what's going on. The "function" keyword itself is already larger than the whole body. It distracts while reading the actual code.
Additionally, using "fn" is optically highlighting the fact that it's a short-Closure with auto-import and not a normal Closure with explicit import.
Thanks,
Bob
2017-01-31 12:14 GMT+01:00 Bob Weinand bobwei9@hotmail.com:
Hey,
Am 31.01.2017 um 11:23 schrieb Michael Wallner mike@php.net:
Hi Andrea, All,
Is it necessary to introduce a new keyword, fn?
I think you'd get a similar benefit from:
function($x) => $arr[$x]
Likewise, is it necessary to restrict auto-capture to the =>
syntax? Couldn't we allow the following?function ($x) {
return $arr[$x];
}I agree that the
fn
keyword isn’t really necessary. I’ve never
quite understood how arrow functions with implied returns etc are
supposed to make for more readable code, but if they’re going to be
part of the language please at least keep some consistency with
regular closures.Yes, I also think that keeping the function keyword would be better.
In the case that regular closures got auto-capture, would a
use($foo, $bar, $baz)
segment on a closure still be honoured (i.e.
disable auto-capture), and would it have any impact (positive or
negative) on performance/memory usage? After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.Wouldn't there be just too many existing closures, which do not use
use
but (maybe) expect a clean scope?The RFC is exclusively proposing single-expression short Closures.
We do NOT want multi-statement short Closures; it is a feature that
generic Closures need an "use ($foo, $bar)".
This vastly improves readability and debuggability - it basically tells
you whether the variables inside the code are imported or not. As Stephen
Reay notes:After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.So, auto-import for generic Closures definitely isn't an option.
Just on short, single-line Closures there is no benefit to "use ()", as
EVERY variable used in the short Closure is supposed to be an imported
variable. There is no point in forcing the user to distinguish between
imported and local variable here.Also, using "fn" in favor of "function" has the advantage of less clutter
in one line. Comparearray_map(fn($x) => $x + 1)
to
array_map(function($x) => $x + 1)
"function" is actually easier to recognize than "fn" for me. Humans read
things by the first and last letter + contained letters, they don't read
each letter separately, so a little bit longer keyword doesn't hurt
readability, it might be even improved, because "function" is a keyword
people are used to. And it comes with the benefit of no BC break, because
"function" is already a keyword.
Also updating
array_map(function ($x) => 2 * $x, [...]);
to
array_map(function ($x) use (...) { ... }, [...]);
is a little bit easier then, just in case you need an additional statement
there.
The syntactical construction is already pretty clearly showing what's
going on. The "function" keyword itself is already larger than the whole
body.
Now we're counting chars again instead of keeping the focus on actual
readability?
It distracts while reading the actual code.
I disagree here, as mentioned above.
Additionally, using "fn" is optically highlighting the fact that it's a
short-Closure with auto-import and not a normal Closure with explicit
import.Thanks,
Bob
I think I prefer "function" instead of "fn", but I can also live with "fn".
Regards, Niklas
In the case that regular closures got auto-capture, would a
use($foo, $bar, $baz)
segment on a closure still be honoured (i.e.
disable auto-capture), and would it have any impact (positive or
negative) on performance/memory usage? After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.
Wouldn't there be just too many existing closures, which do not use
use
but (maybe) expect a clean scope?The RFC is exclusively proposing single-expression short Closures.
We do NOT want multi-statement short Closures; it is a feature that generic Closures need an "use ($foo, $bar)".
This vastly improves readability and debuggability - it basically tells you whether the variables inside the code are imported or not. As Stephen Reay notes:After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.So, auto-import for generic Closures definitely isn't an option.
Just on short, single-line Closures there is no benefit to "use ()", as EVERY variable used in the short Closure is supposed to be an imported variable. There is no point in forcing the user to distinguish between imported and local variable here.Also, using "fn" in favor of "function" has the advantage of less clutter in one line. Compare
array_map(fn($x) => $x + 1)
to
array_map(function($x) => $x + 1)
The syntactical construction is already pretty clearly showing what's going on. The "function" keyword itself is already larger than the whole body. It distracts while reading the actual code.
Additionally, using "fn" is optically highlighting the fact that it's a short-Closure with auto-import and not a normal Closure with explicit import.Thanks,
Bob
I must agree with Bob and the other authors. The entire point of this
RFC is to reduce the amount of typing, and therefore reading, that goes
into using simple closures as first-class values. Using longer keywords
instead of shorter ones is counter to that aim. It sounds like the
earlier proposal of keyword-less closures isn't technically feasible or
it would make sense to argue for that.
My question is why there's no mention of HHVM short closures, or the
previous RFC to take that approach. See:
https://docs.hhvm.com/hack/lambdas/introduction
If there's a good reason to not use that syntax, OK, but that should be
stated explicitly in the RFC with links to both HHVM and to the previous
short-closure RFC.
I also echo the previous call to clarify with examples how types would
be used, syntactically.
Since there is no "return" keyword used, that implies that no "yield"
keyword can be used, either. That is, arrow-function generators are not
supported. Is that correct? (In context they may not make sense to
have, but that should be clarified explicitly in the RFC.)
Overall I am +1 on this RFC.
--Larry Garfield
On Tue, Jan 31, 2017 at 12:29 PM, Larry Garfield larry@garfieldtech.com
wrote:
In the case that regular closures got auto-capture, would a
use($foo, $bar, $baz)
segment on a closure still be honoured (i.e.
disable auto-capture), and would it have any impact (positive or
negative) on performance/memory usage? After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.Wouldn't there be just too many existing closures, which do not use
use
but (maybe) expect a clean scope?The RFC is exclusively proposing single-expression short Closures.
We do NOT want multi-statement short Closures; it is a feature that
generic Closures need an "use ($foo, $bar)".
This vastly improves readability and debuggability - it basically tells
you whether the variables inside the code are imported or not. As Stephen
Reay notes:After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.So, auto-import for generic Closures definitely isn't an option.
Just on short, single-line Closures there is no benefit to "use ()", as
EVERY variable used in the short Closure is supposed to be an imported
variable. There is no point in forcing the user to distinguish between
imported and local variable here.Also, using "fn" in favor of "function" has the advantage of less clutter
in one line. Comparearray_map(fn($x) => $x + 1)
to
array_map(function($x) => $x + 1)
The syntactical construction is already pretty clearly showing what's
going on. The "function" keyword itself is already larger than the whole
body. It distracts while reading the actual code.
Additionally, using "fn" is optically highlighting the fact that it's a
short-Closure with auto-import and not a normal Closure with explicit
import.Thanks,
BobI must agree with Bob and the other authors. The entire point of this RFC
is to reduce the amount of typing, and therefore reading, that goes into
using simple closures as first-class values. Using longer keywords instead
of shorter ones is counter to that aim. It sounds like the earlier
proposal of keyword-less closures isn't technically feasible or it would
make sense to argue for that.My question is why there's no mention of HHVM short closures, or the
previous RFC to take that approach. See:
For what it's worth I'd rather look at
array_map( $x ==> $x + 1);
than
array_map( fn($x) => $x + 1 )
Not to mention the former isn't a bc break.
I guess that should avoid the usage of fn() or function() before arguments
(or then make it optional, but I don't like to give much options).
Some possibilites:
array_map(($x) return $x + 1); // or
array_map(($x) = $x + 1); // or
array_map(($x) => $x + 1); // or
array_map(($x) { $x + 1 });
Then:
array_map(($x) use ($y) { $x + $y });
array_map(($x) { $x + $y });
// maybe use($y) is needless here
array_map(($x) { $x + $this->y });
Or if arguments could be omitted:
array_map({ $0 + 1 });
2017-01-31 16:16 GMT-02:00 Michael Morris tendoaki@gmail.com:
On Tue, Jan 31, 2017 at 12:29 PM, Larry Garfield larry@garfieldtech.com
wrote:In the case that regular closures got auto-capture, would a
use($foo, $bar, $baz)
segment on a closure still be honoured (i.e.
disable auto-capture), and would it have any impact (positive or
negative) on performance/memory usage? After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.Wouldn't there be just too many existing closures, which do not use
use
but (maybe) expect a clean scope?The RFC is exclusively proposing single-expression short Closures.
We do NOT want multi-statement short Closures; it is a feature that
generic Closures need an "use ($foo, $bar)".
This vastly improves readability and debuggability - it basically tells
you whether the variables inside the code are imported or not. As
Stephen
Reay notes:After several years of JS
closure ‘fun’ I kind of like that with PHP you only inherit the
variables you explicitlyuse()
in closures.So, auto-import for generic Closures definitely isn't an option.
Just on short, single-line Closures there is no benefit to "use ()", as
EVERY variable used in the short Closure is supposed to be an imported
variable. There is no point in forcing the user to distinguish between
imported and local variable here.Also, using "fn" in favor of "function" has the advantage of less
clutter
in one line. Comparearray_map(fn($x) => $x + 1)
to
array_map(function($x) => $x + 1)
The syntactical construction is already pretty clearly showing what's
going on. The "function" keyword itself is already larger than the whole
body. It distracts while reading the actual code.
Additionally, using "fn" is optically highlighting the fact that it's a
short-Closure with auto-import and not a normal Closure with explicit
import.Thanks,
BobI must agree with Bob and the other authors. The entire point of this
RFC
is to reduce the amount of typing, and therefore reading, that goes into
using simple closures as first-class values. Using longer keywords
instead
of shorter ones is counter to that aim. It sounds like the earlier
proposal of keyword-less closures isn't technically feasible or it would
make sense to argue for that.My question is why there's no mention of HHVM short closures, or the
previous RFC to take that approach. See:For what it's worth I'd rather look at
array_map( $x ==> $x + 1);
than
array_map( fn($x) => $x + 1 )
Not to mention the former isn't a bc break.
--
David Rodrigues
On Tue, Jan 31, 2017 at 12:29 PM, Larry Garfield larry@garfieldtech.com
wrote:My question is why there's no mention of HHVM short closures, or the
previous RFC to take that approach. See:For what it's worth I'd rather look at
array_map( $x ==> $x + 1);
than
array_map( fn($x) => $x + 1 )
Not to mention the former isn't a bc break.
Neither is supposed to work, though. :)
Anyhow, I'm not sure whether I'd prefer
array_map($a, $b, $c ==> $a + $b + $c, $a1, $a2, $a3)
over
array_map(fn($a, $b, $c) => $a + $b + $c, $a1, $a2, $a3)
or maybe
array_map(fn $a, $b, $c => $a + $b + $c, $a1, $a2, $a3)
Somehow, I tend to like a trailing keyword for better left-to-right
readability.
--
Christoph M. Becker
Am 31.01.2017 um 19:41 schrieb Christoph M. Becker cmbecker69@gmx.de:
On Tue, Jan 31, 2017 at 12:29 PM, Larry Garfield larry@garfieldtech.com
wrote:My question is why there's no mention of HHVM short closures, or the
previous RFC to take that approach. See:For what it's worth I'd rather look at
array_map( $x ==> $x + 1);
than
array_map( fn($x) => $x + 1 )
Not to mention the former isn't a bc break.
Neither is supposed to work, though. :)
Anyhow, I'm not sure whether I'd prefer
array_map($a, $b, $c ==> $a + $b + $c, $a1, $a2, $a3)
over
array_map(fn($a, $b, $c) => $a + $b + $c, $a1, $a2, $a3)
or maybe
array_map(fn $a, $b, $c => $a + $b + $c, $a1, $a2, $a3)
Somehow, I tend to like a trailing keyword for better left-to-right
readability.--
Christoph M. Becker
The RFC states that we're needing some form of a prefix in order to avoid implementing gigantic lexer hacks.
HHVM internally implements it by parsing some part of the syntax INSIDE the lexer and then emitting a token before the first parameter to tell the parser where a short Closure begins.
Having a normal terminal symbol easily allows the parser to detect short Closures, without any hacks.
It is just not a practical option from a technical point of view, and thus not worth even considering.
Bob
Just throwing it in here while commuting, so it's a top-post with no
references. Saw it yesterday on reddit (!!! Reddit being useful for once
!!!): $callback = |$x| => $x ** 2;
Am 31.01.2017 um 19:41 schrieb Christoph M. Becker cmbecker69@gmx.de:
On Tue, Jan 31, 2017 at 12:29 PM, Larry Garfield <
larry@garfieldtech.com>
wrote:My question is why there's no mention of HHVM short closures, or the
previous RFC to take that approach. See:For what it's worth I'd rather look at
array_map( $x ==> $x + 1);
than
array_map( fn($x) => $x + 1 )
Not to mention the former isn't a bc break.
Neither is supposed to work, though. :)
Anyhow, I'm not sure whether I'd prefer
array_map($a, $b, $c ==> $a + $b + $c, $a1, $a2, $a3)
over
array_map(fn($a, $b, $c) => $a + $b + $c, $a1, $a2, $a3)
or maybe
array_map(fn $a, $b, $c => $a + $b + $c, $a1, $a2, $a3)
Somehow, I tend to like a trailing keyword for better left-to-right
readability.--
Christoph M. BeckerThe RFC states that we're needing some form of a prefix in order to avoid
implementing gigantic lexer hacks.
HHVM internally implements it by parsing some part of the syntax INSIDE
the lexer and then emitting a token before the first parameter to tell the
parser where a short Closure begins.
Having a normal terminal symbol easily allows the parser to detect short
Closures, without any hacks.It is just not a practical option from a technical point of view, and thus
not worth even considering.Bob
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.Here is an example of an existing closure:
function ($x) use ($arr) { return $arr[$x]; }
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
More details are in the RFC. The implementation currently has no
known issues and is ready for you to download, build and test, which
we encourage you to do.We look forward to a productive discussion period and are happy to
answer questions.For historical purposes, the revision of this RFC is currently at
1485798604.
Hey Levi, Bob,
that looks very good.
The fn prefix is peculiar yes but it's alright, it doesn't harm neither
readability nor writability, it even has some precedences in other
languages (think Rust, Elixir) and as we all know it is necessary for
parser.
Thanks for the work, I hope it lands in PHP.
> This RFC proposes syntax and semantics to simplify this common usage to:
>
> fn($x) => $arr[$x]
>
Could you explain why fn() cannot be removed like ES2015.
Rowan's syntax sounds attractive to me if fn() cannot be removed.
fn($x => $x * 2)
Or since many of us like "function", it could be
function($x => $x * 2)
I don't have strong preference, but some may have.
I suggest separate vote into 2 votes.
- Introduce arrow function
- Prefered syntax
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Or just drop any "fn" or "function" keyword, eg
($x, $y) => foo($x, $y);
array_map(($x) => $x + 1);
?
On Tue, Jan 31, 2017 at 9:06 PM, Nicolas Grekas <
nicolas.grekas+php@gmail.com> wrote:
Or just drop any "fn" or "function" keyword, eg
($x, $y) => foo($x, $y);
array_map(($x) => $x + 1);
?
I like your syntax if it cannot be like ES2015 syntax.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Or just drop any "fn" or "function" keyword, eg
($x, $y) => foo($x, $y);
array_map(($x) => $x + 1);
That has the great advantage of being much as Javascript does this.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information: http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h
2017-01-31 13:20 GMT+01:00 Alain Williams addw@phcomp.co.uk:
Or just drop any "fn" or "function" keyword, eg
($x, $y) => foo($x, $y);
array_map(($x) => $x + 1);
That has the great advantage of being much as Javascript does this.
https://developer.mozilla.org/en/docs/Web/JavaScript/
Reference/Functions/Arrow_functions
IMO it'll be hard to detect arrow function then.
Consider an example:
$y = 'a';
$x = 1;
$a = [
$y => 'b',
($x) => $x + 1,
];
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT
Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information:
http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h>--
--
regards / pozdrawiam,
Michał Brzuchalski
about.me/brzuchal
brzuchalski.com
Alain Williams addw@phcomp.co.uk schrieb am Di., 31. Jan. 2017, 13:20:
Or just drop any "fn" or "function" keyword, eg
($x, $y) => foo($x, $y);
array_map(($x) => $x + 1);
That has the great advantage of being much as Javascript does this.
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Functions/Arrow_functions
As noted in the RFC, this isn't possible due to ambiguities with array
keys and yield expressions with keys.
Regards, Niklas
--
Alain Williams
Linux/GNU Consultant - Mail systems, Web sites, Networking, Programmer, IT
Lecturer.
+44 (0) 787 668 0256 http://www.phcomp.co.uk/
Parliament Hill Computers Ltd. Registration Information:
http://www.phcomp.co.uk/contact.php
#include <std_disclaimer.h
As noted in the RFC, this isn't possible due to ambiguities with array
keys and yield expressions with keys.
There are not ambiguities technically, so it is possible if we want to:
$a = [
$y => 'b',
($x) => $x + 1, // key, value pair
];
$a = [
$y => 'b',
(($x) => $x + 1), // closure
];
Nicolas Grekas nicolas.grekas+php@gmail.com schrieb am Di., 31. Jan.
2017, 13:45:
As noted in the RFC, this isn't possible due to ambiguities with array
keys and yield expressions with keys.There are not ambiguities technically, so it is possible if we want to:
$a = [
$y => 'b',
($x) => $x + 1, // key, value pair
];$a = [
$y => 'b',
(($x) => $x + 1), // closure
];
Well, it is ambiguous. Your solution just arbitrarily resolves it to one of
them.
But as far as I know there are more problems like supporting types that
make it quite complicated with that syntax.
Regards, Niklas
>
>
>> This RFC proposes syntax and semantics to simplify this common usage to:
>>
>> fn($x) => $arr[$x]
>>
>
> Could you explain why fn() cannot be removed like ES2015.
I guess current PHP parser has to determine token type as they processed.
So distinguished keyword is needed. I don't have problem with the proposed
syntax. Large change is not preferred and current way should be faster.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.Here is an example of an existing closure:
function ($x) use ($arr) { return $arr[$x]; }
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
More details are in the RFC. The implementation currently has no
known issues and is ready for you to download, build and test, which
we encourage you to do.We look forward to a productive discussion period and are happy to
answer questions.For historical purposes, the revision of this RFC is currently at
1485798604.
Thank you to everyone who has participated in the discussion so far.
Several people have asked for examples of type declarations. I have
updated the RFC accordingly and also added an example for by-ref
parameters and returns. Here are the examples:
fn (array $x) => $x
fn (): int => 42
fn &(array &$xs) => $xs
I have also made some minor improvements to the formatting in various places.
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.Here is an example of an existing closure:
function ($x) use ($arr) { return $arr[$x]; }
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
More details are in the RFC. The implementation currently has no
known issues and is ready for you to download, build and test, which
we encourage you to do.We look forward to a productive discussion period and are happy to
answer questions.For historical purposes, the revision of this RFC is currently at
1485798604.
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.Here is an example of an existing closure:
function ($x) use ($arr) { return $arr[$x]; }
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
More details are in the RFC. The implementation currently has no
known issues and is ready for you to download, build and test, which
we encourage you to do.We look forward to a productive discussion period and are happy to
answer questions.For historical purposes, the revision of this RFC is currently at
1485798604.
Thanks to everyone who has participated in the discussion thus far.
Primarily the feedback has been directed at the fn
keyword. Let me
provide two benefits and drawbacks of using fn
as a keyword:
-
fn
is searchable in search engines and in our manual - Is more intuitive than just syntax
However, fn
does have downsides:
- Can break existing code
- We already have a similar keyword
function
To that end, I'd like to gauge interest in a pure syntax based
alternative that is similar to Rust and Ruby.
Instead of:
fn(params) => expr
What about:
|params| => expr
This trades the advantages of the keyword for the advantages of pure
syntax, and happens to be two characters shorter. To be explicit:
1. Preserves 100% backwards compatibility
2. Avoids having two keywords that both mean "function"
3. Is not easily searchable in engines or in the manual
4. Is a tad bit shorter
What do you think, Internals?
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.Here is an example of an existing closure:
function ($x) use ($arr) { return $arr[$x]; }
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
More details are in the RFC. The implementation currently has no
known issues and is ready for you to download, build and test, which
we encourage you to do.We look forward to a productive discussion period and are happy to
answer questions.For historical purposes, the revision of this RFC is currently at
1485798604.Thanks to everyone who has participated in the discussion thus far.
Primarily the feedback has been directed at thefn
keyword. Let me
provide two benefits and drawbacks of usingfn
as a keyword:
fn
is searchable in search engines and in our manual- Is more intuitive than just syntax
However,
fn
does have downsides:
- Can break existing code
- We already have a similar keyword
function
To that end, I'd like to gauge interest in a pure syntax based
alternative that is similar to Rust and Ruby.
Instead of:fn(params) => expr
What about:
|params| => expr
This trades the advantages of the keyword for the advantages of pure
syntax, and happens to be two characters shorter. To be explicit:1. Preserves 100% backwards compatibility 2. Avoids having two keywords that both mean "function" 3. Is not easily searchable in engines or in the manual 4. Is a tad bit shorter
What do you think, Internals?
One more thing: I'd like to re-emphasize that the syntax that
JavaScript uses and the one that HHVM/Hack uses are ambiguous in the
current class of our grammar. The following will not work unless we
move to a more powerful grammar and parser class:
(params) => expr
(params) ==> expr
This is why an un-ambiguous prefix is necessary: the prefix breaks the
ambiguities. The syntax I have suggested in the RFC and the one I
suggested just now are not ambiguous because distinct prefixes:
fn(params) => expr
|params| => expr
I look forward to more discussion!
To that end, I'd like to gauge interest in a pure syntax based
alternative that is similar to Rust and Ruby.
Instead of:fn(params) => expr
What about:
|params| => expr
Looks great to me from up here in the peanut gallery.
Hello folks!
I just not understand why "function" should be abbreviated. It's about "how
less character better"? I don't see it too much on PHP. I guess that is
more simple keep what exists current "function", that all knows about (that
should be better than the next example):
$mapped = array_map(function($x) => $x + $y); // vs current:
$mapped = array_map(function($x) use($y) { return $x + $y });
Or even, I too don't know why just ($x) => is an issue. There some possible
conflict why that?
2017-02-03 16:21 GMT-02:00 Michael Morris tendoaki@gmail.com:
To that end, I'd like to gauge interest in a pure syntax based
alternative that is similar to Rust and Ruby.
Instead of:fn(params) => expr
What about:
|params| => expr
Looks great to me from up here in the peanut gallery.
--
David Rodrigues
Or even, I too don't know why just ($x) => is an issue. There some possible
conflict why that?
Yes, this conflicts with existing syntax. The following code snippets
are valid today:
[($x) => $x + $y]
yield ($x) => $x + $y
There are other issues as well; this is just the easiest to point out.
Hi David,
David Rodrigues wrote:
Hello folks!
I just not understand why "function" should be abbreviated. It's about "how
less character better"? I don't see it too much on PHP. I guess that is
more simple keep what exists current "function", that all knows about (that
should be better than the next example):$mapped = array_map(function($x) => $x + $y); // vs current:
$mapped = array_map(function($x) use($y) { return $x + $y });
I feel the same way. It would be nice to have shorter syntax, but it
sacrifices readability and familiarity here, and adds yet another new
keyword.
It also feels inconsistent… isn't "fn" just short for "function"? Why is
it exclusive to the => syntax?
Thanks.
--
Andrea Faulds
https://ajf.me/
Hi David,
David Rodrigues wrote:
Hello folks!
I just not understand why "function" should be abbreviated. It's about
"how
less character better"? I don't see it too much on PHP. I guess that is
more simple keep what exists current "function", that all knows about
(that
should be better than the next example):$mapped = array_map(function($x) => $x + $y); // vs current:
$mapped = array_map(function($x) use($y) { return $x + $y });I feel the same way. It would be nice to have shorter syntax, but it
sacrifices readability and familiarity here, and adds yet another new
keyword.It also feels inconsistent… isn't "fn" just short for "function"? Why is it
exclusive to the => syntax?
This is not exactly on topic... unless you are implying you'd prefer
the |$x| => $x + $y
? Maybe you missed this message?
I like the suggested syntax. The only drawback I see is that it inhibits the future addition of union types for closures:
|int | float $x| => $x
Adding parentheses of course resolves the issue but looks a bit awkward:
|(int | float) $x| => $x
Apart from that I have nothing to complain about. I'd be happy either way.
Hi David,
David Rodrigues wrote:
Hello folks!
I just not understand why "function" should be abbreviated. It's about
"how
less character better"? I don't see it too much on PHP. I guess that is
more simple keep what exists current "function", that all knows about
(that
should be better than the next example):$mapped = array_map(function($x) => $x + $y); // vs current:
$mapped = array_map(function($x) use($y) { return $x + $y });I feel the same way. It would be nice to have shorter syntax, but it
sacrifices readability and familiarity here, and adds yet another new
keyword.It also feels inconsistent… isn't "fn" just short for "function"? Why is it
exclusive to the => syntax?This is not exactly on topic... unless you are implying you'd prefer
the|$x| => $x + $y
? Maybe you missed this message?
I like the suggested syntax. The only drawback I see is that it inhibits
the future addition of union types for closures:|int | float $x| => $x
Adding parentheses of course resolves the issue but looks a bit awkward:
|(int | float) $x| => $x
Apart from that I have nothing to complain about. I'd be happy either way.
Good point, but union types are going to come up in this context I think.
Remember, these are for one line functions, which highly limits what they
can do.
I like the suggested syntax. The only drawback I see is that it inhibits the future addition of union types for closures:
|int | float $x| => $x
Adding parentheses of course resolves the issue but looks a bit awkward:
|(int | float) $x| => $x
Apart from that I have nothing to complain about. I'd be happy either way.
While it may be ugly, I do not believe that this has any ambiguity.
$callback = |int|float $x| => $x ** 2;
When the second | is not followed by =>, the parser should be able to discern that a union type is being used.
Regards, Aaron Piotrowski
$callback = |int|float $x| => $x ** 2;
Forget the parser, you're giving my eyes diabetes trying to read that.
As has been said before, PHP is relatively verbose compared to other languages. That makes it slightly more characters to type, but it also makes it absolutely clear what is happening.
As Niklas said, all ambiguity/clarity issues are solved by using "function", at the cost of 6 characters.
Suggesting that a search for arrow functions will be easier with <insert random character here> and then using grep (which could also easily match arrow functions using "function") as your example search seems odd to me.
$callback = |int|float $x| => $x ** 2;
Forget the parser, you're giving my eyes diabetes trying to read that.
I absolutely agree that it's terrible… the point is that types (even potential future union types) can be used with short closures, but it certainly doesn't mean they should be. I don't think confusion with a non-existent and non-recommended way of coding should be a reason against a particular syntax.
As has been said before, PHP is relatively verbose compared to other languages. That makes it slightly more characters to type, but it also makes it absolutely clear what is happening.
Using function
IMO makes it more likely to confuse a short closure with a regular closure. Reusing the function
keyword with different semantics may result in some confusion.
As Niklas said, all ambiguity/clarity issues are solved by using "function", at the cost of 6 characters.
Suggesting that a search for arrow functions will be easier with <insert random character here> and then using grep (which could also easily match arrow functions using "function") as your example search seems odd to me.
I never suggested this, Björn Larsson did. Any of the possibilities mentioned in this thread could easily be searched.
Regards, Aaron Piotrowski
Hi Aaron,
Sent from my iPhone
$callback = |int|float $x| => $x ** 2;
Forget the parser, you're giving my eyes diabetes trying to read that.
I absolutely agree that it's terrible… the point is that types (even potential future union types) can be used with short closures, but it certainly doesn't mean they should be. I don't think confusion with a non-existent and non-recommended way of coding should be a reason against a particular syntax.
Using type hints is a part of the language. It even has benefits that I can absolutely see being used here:
array_map(function(Foo $x) => $x->bar());
If Foo is a class/interface with a method of bar, your IDE can know that it's a valid method to call.
That of course is in addition to the benefit of getting useful type errors from PHP itself.
As has been said before, PHP is relatively verbose compared to other languages. That makes it slightly more characters to type, but it also makes it absolutely clear what is happening.
Using
function
IMO makes it more likely to confuse a short closure with a regular closure. Reusing thefunction
keyword with different semantics may result in some confusion.
So we should instead use syntax already used for bit wise OR, and further confuse the situation when the function has no parameters and reusing the logical OR operator. Brilliant.
This is still a function, it has slightly different semantics, just like how a regular function, a class instance method and a static class method have slightly different semantics: we still use the function keyword for all of those.
The static keyword is used for functions, class static properties, static variables and even static closures: it's semantics are slightly different for each case but we reuse the same keyword.
As Niklas said, all ambiguity/clarity issues are solved by using "function", at the cost of 6 characters.
Suggesting that a search for arrow functions will be easier with <insert random character here> and then using grep (which could also easily match arrow functions using "function") as your example search seems odd to me.
I never suggested this, Björn Larsson did. Any of the possibilities mentioned in this thread could easily be searched.
Apologies I meant to quote the earlier message/author but I'm on a phone and forgot to do so. I didn't mean to imply this was your view.
Cheers
Stephen
Regards, Aaron Piotrowski
Hi Stephen,
I absolutely agree that it's terrible… the point is that types (even potential future union types) can be used with short closures, but it certainly doesn't mean they should be. I don't think confusion with a non-existent and non-recommended way of coding should be a reason against a particular syntax.
Using type hints is a part of the language. It even has benefits that I can absolutely see being used here:
array_map(function(Foo $x) => $x->bar());
If Foo is a class/interface with a method of bar, your IDE can know that it's a valid method to call.
That of course is in addition to the benefit of getting useful type errors from PHP itself.
You raise a good point about IDEs, types might have a place with short closures. Still, I don't see union types, if they ever exist, being common here. Taking your example with the other proposed syntax:
array_map(|Foo $x| => $x->bar());
Honestly I'm not sure which is better… personal preference at this point, each has their merits.
As has been said before, PHP is relatively verbose compared to other languages. That makes it slightly more characters to type, but it also makes it absolutely clear what is happening.
Using
function
IMO makes it more likely to confuse a short closure with a regular closure. Reusing thefunction
keyword with different semantics may result in some confusion.So we should instead use syntax already used for bit wise OR, and further confuse the situation when the function has no parameters and reusing the logical OR operator. Brilliant.
This is certainly a downside, though expressions cannot start with a logical or bitwise OR, so that will help differentiate them. However, it is hard to argue that function
could be confusing when something like || => $x ** 2
may be more confusing, so point taken. Regardless, I still prefer the visual difference since the auto-capture behavior is so different from other functions.
Cheers!
Aaron Piotrowski
So we should instead use syntax already used for bit wise OR, and further confuse the situation when the function has no parameters and reusing the logical OR operator. Brilliant.
Excuse me, good sir, but can you tell me what the &
symbol means? I
thought it meant reference but it's also bitwise and! And when we put
two of them together it is a different kind of and?!?!?!
Maybe you can tell from the language I used but I don't think your
argument has much merit. Symbol reuse is a problem that programmers
and programming languages have been dealing with for a long time. I
trust us to be able to deal with it, should we agree to go forward
with it.
So we should instead use syntax already used for bit wise OR, and further confuse the situation when the function has no parameters and reusing the logical OR operator. Brilliant.
Excuse me, good sir, but can you tell me what the
&
symbol means? I
thought it meant reference but it's also bitwise and! And when we put
two of them together it is a different kind of and?!?!?!Maybe you can tell from the language I used but I don't think your
argument has much merit. Symbol reuse is a problem that programmers
and programming languages have been dealing with for a long time. I
trust us to be able to deal with it, should we agree to go forward
with it.
Your sarcasm is in fact not lost on me my good man, and I do appreciate it.
Then surely you agree that there is no issue with function(){...} vs function() => ...being "confusing"?
So, is there any argument besides "6 more characters" for not using the function keyword?
Hi Stephen
Using type hints is a part of the language. It even has benefits that I can absolutely see being used here:
array_map(function(Foo $x) => $x->bar());
If Foo is a class/interface with a method of bar, your IDE can know that it's a valid method to call.
That of course is in addition to the benefit of getting useful type errors from PHP itself.
I agree but think that this is the wrong approach. PHP is a weakly typed language. Doesn’t it seem wrong that you have to specify types in more places than in many modern strongly typed languages? Look at Swift for example. IMHO, the right approach would be to implement proper closure type hints. This has the benefit of letting the callee specify what kind of closure is expected (who knows that much better than the caller anyway) while allowing for IDE autocompletion.
Nonetheless, specifying type hints on the closures is what we do right now. The approach Levi suggested works well with that.
So we should instead use syntax already used for bit wise OR, and further confuse the situation when the function has no parameters and reusing the logical OR operator. Brilliant.
This is still a function, it has slightly different semantics, just like how a regular function, a class instance method and a static class method have slightly different semantics: we still use the function keyword for all of those.
The static keyword is used for functions, class static properties, static variables and even static closures: it's semantics are slightly different for each case but we reuse the same keyword.
As Levi already mentioned, this argument is similar to claiming reusing the function
keyword could be confusing. Both should be perfectly clear to anyone who is serious about programming. I think we can expect for programmers to get informed about new features before using them. This seems to work for any other language. Also, it’s not like the suggested syntax is something we’ve never seen before. Ruby has it, Rust has it (or something similar at least). The rest personal preference I suppose.
I can see how people like function
more because of consistency. I like || => expr
more because of readability (for me, the less reading the better :P).
@Levi Maybe it would be best to vote for the closure syntax? My least favourite option is better than the RFC getting shot down because people dislike the syntax.
Hi Ilija
Hi Stephen
Using type hints is a part of the language. It even has benefits that I can absolutely see being used here:
array_map(function(Foo $x) => $x->bar());
If Foo is a class/interface with a method of bar, your IDE can know that it's a valid method to call.
That of course is in addition to the benefit of getting useful type errors from PHP itself.
I agree but think that this is the wrong approach. PHP is a weakly typed language.
Only if you omit type hints on your methods.
Doesn’t it seem wrong that you have to specify types in more places than in many modern strongly typed languages?
You don't have to specify types at all. If you want to use PHP without verifying/requiring types, thats your prerogative, but given the recent improvements to allow scalar type hinting, I think it’s a mistake to say that any use of type hints is “not recommended".
Look at Swift for example. IMHO, the right approach would be to implement proper closure type hints. This has the benefit of letting the callee specify what kind of closure is expected (who knows that much better than the caller anyway) while allowing for IDE autocompletion.
I'm not sure if you've mixed up your terms of if I'm too tired but I don't understand what you mean here. The short arrow function is the callee, and that’s where you’re suggesting we shouldn’t use type hints.
Are you actually referring to something like https://wiki.php.net/rfc/callable-types https://wiki.php.net/rfc/callable-types or https://wiki.php.net/rfc/typesafe-callable https://wiki.php.net/rfc/typesafe-callable where a callable type hint can define the signature the callable should match?
Nonetheless, specifying type hints on the closures is what we do right now. The approach Levi suggested works well with that.
The whole issue with that is that using a pipe character could make things much less clear/readable if the already established use of pipe for “type unions” (currently used in multi-catch) were to be implemented for general type hint usage.
Note: I’m not saying it’s not possible, but it’s much less readable, and any “solution” just adds more characters, which is apparently the only reason to not use function($foo) => $foo in the first place.
So we should instead use syntax already used for bit wise OR, and further confuse the situation when the function has no parameters and reusing the logical OR operator. Brilliant.
This is still a function, it has slightly different semantics, just like how a regular function, a class instance method and a static class method have slightly different semantics: we still use the function keyword for all of those.
The static keyword is used for functions, class static properties, static variables and even static closures: it's semantics are slightly different for each case but we reuse the same keyword.
As Levi already mentioned, this argument is similar to claiming reusing the
function
keyword could be confusing.
That was my point. There's no 'confusion' reason to not use function. The only reason is to make it less characters, which several people have noted doesn't automatically make it more readable.
Both should be perfectly clear to anyone who is serious about programming. I think we can expect for programmers to get informed about new features before using them. This seems to work for any other language. Also, it’s not like the suggested syntax is something we’ve never seen before. Ruby has it, Rust has it (or something similar at least). The rest personal preference I suppose.
As has been mentioned, the rust syntax can get very hard to read very quickly.
I can see how people like
function
more because of consistency. I like|| => expr
more because of readability (for me, the less reading the better :P).
For most people readability isn't just about the number of characters.
Cheers
Stephen
Hey Stephen
You don't have to specify types at all. If you want to use PHP without verifying/requiring types, thats your prerogative, but given the recent improvements to allow scalar type hinting, I think it’s a mistake to say that any use of type hints is “not recommended”.
Sure you don’t but then you loose all the benefits of specifying types. We want typing but only if we don’t have to specify types all over the place. I really dislike having to add PHPDocs everywhere just to get some proper autocompletions.
I'm not sure if you've mixed up your terms of if I'm too tired but I don't understand what you mean here. The short arrow function is the callee, and that’s where you’re suggesting we shouldn’t use type hints.
Sorry, that was confusing. I was thinking of a situation like this one:
func fetchUsers(callback: ([User]) -> Void) {
...
}
So, the callee (fetchUsers
) defines what the provided closure must look like.
The caller, on the other hand, doesn’t have to specify that again as you’re just repeating yourself.
fetchUsers { user in
// `user` is inferred to be a `User` object
}
So I don’t think the burden of providing typing information should be on the caller providing the closure.
The whole issue with that is that using a pipe character could make things much less clear/readable if the already established use of pipe for “type unions” (currently used in multi-catch) were to be implemented for general type hint usage.
Note: I’m not saying it’s not possible, but it’s much less readable, and any “solution” just adds more characters, which is apparently the only reason to not use function($foo) => $foo in the first place.
But again, that’s personal preference. I like short a precise and think it’s more readable. Not everyone’s the same.
For most people readability isn't just about the number of characters.
A lot of the time it is. Brains are very good at recognising patterns, they don’t need large keywords for that.
As for me, I think it just adds clutter to the actual logic that I’m interested in.
Ah, my example was of course wrong again -.-
The caller should’ve looked like this (although I think you get the point):
fetchUsers { users in
// `users` is inferred to be an array of `User`s
}
Regards
Hey Stephen
You don't have to specify types at all. If you want to use PHP without verifying/requiring types, thats your prerogative, but given the recent improvements to allow scalar type hinting, I think it’s a mistake to say that any use of type hints is “not recommended”.
Sure you don’t but then you loose all the benefits of specifying types. We want typing but only if we don’t have to specify types all over the place. I really dislike having to add PHPDocs everywhere just to get some proper autocompletions.
I'm not sure if you've mixed up your terms of if I'm too tired but I don't understand what you mean here. The short arrow function is the callee, and that’s where you’re suggesting we shouldn’t use type hints.
Sorry, that was confusing. I was thinking of a situation like this one:
func fetchUsers(callback: ([User]) -> Void) { ... }
So, the callee (
fetchUsers
) defines what the provided closure must look like.
The caller, on the other hand, doesn’t have to specify that again as you’re just repeating yourself.fetchUsers { user in // `user` is inferred to be a `User` object }
So I don’t think the burden of providing typing information should be on the caller providing the closure.
The whole issue with that is that using a pipe character could make things much less clear/readable if the already established use of pipe for “type unions” (currently used in multi-catch) were to be implemented for general type hint usage.
Note: I’m not saying it’s not possible, but it’s much less readable, and any “solution” just adds more characters, which is apparently the only reason to not use function($foo) => $foo in the first place.
But again, that’s personal preference. I like short a precise and think it’s more readable. Not everyone’s the same.
For most people readability isn't just about the number of characters.
A lot of the time it is. Brains are very good at recognising patterns, they don’t need large keywords for that.
As for me, I think it just adds clutter to the actual logic that I’m interested in.
Hi Ilija,
For some reason I don’t see your original reply yet. Anyway…
Ah, my example was of course wrong again -.-
The caller should’ve looked like this (although I think you get the point):
fetchUsers { users in // `users` is inferred to be an array of `User`s }
Regards
Hey Stephen
You don't have to specify types at all. If you want to use PHP without verifying/requiring types, thats your prerogative, but given the recent improvements to allow scalar type hinting, I think it’s a mistake to say that any use of type hints is “not recommended”.
Sure you don’t but then you loose all the benefits of specifying types. We want typing but only if we don’t have to specify types all over the place. I really dislike having to add PHPDocs everywhere just to get some proper autocompletions.
You’re really starting to lose me now. You want types but don’t want to define them, and you’re somehow mixing phpdoc into this.
Ultimately the common example everyone has for arrow functions/short closures is something like array_map or array_filter.
Currently PHP has zero support for Foo[] (or array<Foo> if you prefer) as a type hint. In theory an IDE could use the calling scope’s context (assuming the source of the array is purely local or from arguments/return values that are typed) to infer types, but I haven’t seen it, and I would likely still use type hints, to cover the case where something changes elsewhere.
I'm not sure if you've mixed up your terms of if I'm too tired but I don't understand what you mean here. The short arrow function is the callee, and that’s where you’re suggesting we shouldn’t use type hints.
Sorry, that was confusing. I was thinking of a situation like this one:
func fetchUsers(callback: ([User]) -> Void) { ... }
So, the callee (
fetchUsers
) defines what the provided closure must look like.
The caller, on the other hand, doesn’t have to specify that again as you’re just repeating yourself.fetchUsers { user in // `user` is inferred to be a `User` object }
So I don’t think the burden of providing typing information should be on the caller providing the closure.
Ok so yes, you’re talking about the same thing as the two RFC’s I linked to. I would love to be able to say “I expect a callable that accepts Foo and returns an int”, but again, PHP doesn’t support that now, and frankly that doesn’t negate the need for type hints on short functions.
The whole issue with that is that using a pipe character could make things much less clear/readable if the already established use of pipe for “type unions” (currently used in multi-catch) were to be implemented for general type hint usage.
Note: I’m not saying it’s not possible, but it’s much less readable, and any “solution” just adds more characters, which is apparently the only reason to not use function($foo) => $foo in the first place.
But again, that’s personal preference. I like short a precise and think it’s more readable. Not everyone’s the same.
For most people readability isn't just about the number of characters.
A lot of the time it is.
What were you saying about not everyone being the same?
Brains are very good at recognising patterns, they don’t need large keywords for that.
As for me, I think it just adds clutter to the actual logic that I’m interested in.
Hey Stephen
You’re really starting to lose me now. You want types but don’t want to define them, and you’re somehow mixing phpdoc into this.
Because we use PHPDoc to provide type hints to the IDE where PHP doesn’t support them yet (variables and properties).
Currently PHP has zero support for Foo[] (or array<Foo> if you prefer) as a type hint. In theory an IDE could use the calling scope’s context (assuming the source of the array is purely local or from arguments/return values that are typed) to infer types, but I haven’t seen it, and I would likely still use type hints, to cover the case where something changes elsewhere.
That’s because you don’t trust it ;) You should be able to trust it.
But anyway, that’s beside the point. Let’s get back to the RFC.
What were you saying about not everyone being the same?
What I’m saying is that maybe it would make sense to vote for syntax, as this would make most people happy.
People seem to complain about that the most but agree with the general idea of the RFC.
2017-02-03 21:23 GMT+01:00 Levi Morrison levim@php.net:
Hi David,
David Rodrigues wrote:
Hello folks!
I just not understand why "function" should be abbreviated. It's about
"how
less character better"? I don't see it too much on PHP. I guess that is
more simple keep what exists current "function", that all knows about
(that
should be better than the next example):$mapped = array_map(function($x) => $x + $y); // vs current:
$mapped = array_map(function($x) use($y) { return $x + $y });I feel the same way. It would be nice to have shorter syntax, but it
sacrifices readability and familiarity here, and adds yet another new
keyword.It also feels inconsistent… isn't "fn" just short for "function"? Why is
it
exclusive to the => syntax?This is not exactly on topic... unless you are implying you'd prefer
the|$x| => $x + $y
? Maybe you missed this message?
Why is using "function" instead of "fn" not on topic?
Thanks to everyone who has participated in the discussion thus far.
Primarily the feedback has been directed at the
fn
keyword. Let me
provide two benefits and drawbacks of usingfn
as a keyword:
fn
is searchable in search engines and in our manual
Just as "php function" is, too:
http://php.net/manual/en/language.functions.php
- Is more intuitive than just syntax
As is "function", too. With the added benefit that people are already
familiar with it.
However,
fn
does have downsides:
- Can break existing code
Which doesn't happen with reusing "function".
- We already have a similar keyword
function
Right, so why not use that?
To that end, I'd like to gauge interest in a pure syntax based
alternative that is similar to Rust and Ruby.
Instead of:
fn(params) => expr
What about:
|params| => expr
This trades the advantages of the keyword for the advantages of pure
syntax, and happens to be two characters shorter. To be explicit:
1. Preserves 100% backwards compatibility
2. Avoids having two keywords that both mean "function"
3. Is not easily searchable in engines or in the manual
4. Is a tad bit shorter
1, 2, and 3 are also solved by using "function".
4 is counting characters instead of focusing on readability.
There are more drawbacks to that syntax like no parameters looking pretty
weird: || =>
Regards, Niklas
2017-02-03 21:23 GMT+01:00 Levi Morrison levim@php.net:
Hi David,
David Rodrigues wrote:
Hello folks!
I just not understand why "function" should be abbreviated. It's about
"how
less character better"? I don't see it too much on PHP. I guess that is
more simple keep what exists current "function", that all knows about
(that
should be better than the next example):$mapped = array_map(function($x) => $x + $y); // vs current:
$mapped = array_map(function($x) use($y) { return $x + $y });I feel the same way. It would be nice to have shorter syntax, but it
sacrifices readability and familiarity here, and adds yet another new
keyword.It also feels inconsistent… isn't "fn" just short for "function"? Why is
it
exclusive to the => syntax?This is not exactly on topic... unless you are implying you'd prefer
the|$x| => $x + $y
? Maybe you missed [this][1] message?Why is using "function" instead of "fn" not on topic?
I did not ask for general syntax suggestions. What I am asking about
is specifically what the preference people might have between these
two options:
fn(params) => expr
|params| => expr
As well as potential issues (thanks, Ilija, for pointing out a
theoretical issue with union types).
As a disclaimer I'm trying to guide the discussion to these two
options, not suppress suggestions I don't like.
Den 2017-02-03 kl. 21:46, skrev Levi Morrison:
2017-02-03 21:23 GMT+01:00 Levi Morrison levim@php.net:
Hi David,
David Rodrigues wrote:
Hello folks!
I just not understand why "function" should be abbreviated. It's about
"how
less character better"? I don't see it too much on PHP. I guess that is
more simple keep what exists current "function", that all knows about
(that
should be better than the next example):$mapped = array_map(function($x) => $x + $y); // vs current:
$mapped = array_map(function($x) use($y) { return $x + $y });I feel the same way. It would be nice to have shorter syntax, but it
sacrifices readability and familiarity here, and adds yet another new
keyword.It also feels inconsistent… isn't "fn" just short for "function"? Why is
it
exclusive to the => syntax?
This is not exactly on topic... unless you are implying you'd prefer
the|$x| => $x + $y
? Maybe you missed [this][1] message?Why is using "function" instead of "fn" not on topic?
I did not ask for general syntax suggestions. What I am asking about
is specifically what the preference people might have between these
two options:fn(params) => expr |params| => expr
As well as potential issues (thanks, Ilija, for pointing out a
theoretical issue with union types).
As a disclaimer I'm trying to guide the discussion to these two
options, not suppress suggestions I don't like.
I can live with both, maybe with a preference for the
last one. Using function with another semantic I don't
like at all. Imagine for example if different kind of loops
had the same starting keyword (for for everything ;-).
Also using fn or || helps when searching in a codebase
for all ordinary functions and no arrow ones, e.g. grep
'function($' files would give everything with fucntion
keyword.
Anothe angle I came to think of is if PHP in the future
would have async / await functionality. How does that
play together with arrow functions? HHVM has some
example: https://docs.hhvm.com/hack/async/blocks
Anyway, I do appreciate that finally arrow functions in
PHP are on the horizon :-)
Regards //Björn Larsson
There are more drawbacks to that syntax like no parameters looking pretty
weird: || =>
I can't think of a valid example of an arrow function without any arguments
at all. These functions are very simple iterators to plug into things like
array_map. If you can think of one please post it.
There are more drawbacks to that syntax like no parameters looking pretty
weird: || =>I can't think of a valid example of an arrow function without any arguments
at all. These functions are very simple iterators to plug into things like
array_map. If you can think of one please post it.
There are many situations where one might want a closure that takes no
arguments.
$option->unwrapOrThrow(|| => new Exception('my message'));
Creating a supplier callable is often less resource intensive than
actually computing the supplied value.
Rust has exactly that syntax but it can become rather cryptic and PHP is
a verbose language in general. I think that it is best for PHP to go for
function
to keep things nicely aligned and to avoid problems with
union types (which we really need).
--
Richard "Fleshgrinder" Fussenegger
2017-02-03 23:26 GMT+01:00 Michael Morris tendoaki@gmail.com:
There are more drawbacks to that syntax like no parameters looking pretty
weird: || =>I can't think of a valid example of an arrow function without any arguments
at all. These functions are very simple iterators to plug into things like
array_map. If you can think of one please post it.
One example might be callbacks operating on $this
:
register_some_callback(|| => $this->someFlag = false);
Another example are supplier functions as mentioned by Fleshgrinder.
Regards, Niklas
"Andrea Faulds" wrote in message news:19.45.38491.677D4985@pb1.pair.com...
Hi David,
David Rodrigues wrote:
Hello folks!
I just not understand why "function" should be abbreviated. It's about
"how
less character better"? I don't see it too much on PHP. I guess that is
more simple keep what exists current "function", that all knows about
(that
should be better than the next example):$mapped = array_map(function($x) => $x + $y); // vs current:
$mapped = array_map(function($x) use($y) { return $x + $y });I feel the same way. It would be nice to have shorter syntax, but it
sacrifices readability and familiarity here, and adds yet another new
keyword.It also feels inconsistent… isn't "fn" just short for "function"? Why is it
exclusive to the => syntax?Thanks.
If something can already be done in PHP then why the rush to complicate the
language so that the same thing can be accomplished with slightly fewer
keystrokes? The idea that you should reduce 'function' to 'fn' just to save
6 keystrokes strikes me as ludicrous. It also breaks one of the fundamental
rules of programming which is "Programs must be written for people to read,
and only incidentally for machines to execute."
Replacing proper words with TLAs or even symbols will make the language less
readable. It will also make it difficult for someone to spot a piece of
unusual code and look it up in the manual to find out what it means. Those
who want a language with hieroglyphic syntax should go back to Perl, but
please leave PHP alone!
Anybody who is in favour of such a bad move deserves to have their keyboard
confiscated and to be sent to bed without any supper.
--
Tony Marston
One more thing: I'd like to re-emphasize that the syntax that
JavaScript uses and the one that HHVM/Hack uses are ambiguous in the
current class of our grammar. The following will not work unless we
move to a more powerful grammar and parser class:(params) => expr (params) ==> expr
I'm not really familiar with re2c and bison, but I wonder why it's
possible to distinguish
expr > expr
from
expr -> expr
then.
Note that I'm not suggesting to use the Hack syntax here – I'm just curious.
--
Christoph M. Becker
One more thing: I'd like to re-emphasize that the syntax that
JavaScript uses and the one that HHVM/Hack uses are ambiguous in the
current class of our grammar. The following will not work unless we
move to a more powerful grammar and parser class:(params) => expr
(params) ==> exprThis is why an un-ambiguous prefix is necessary: the prefix breaks the
ambiguities. The syntax I have suggested in the RFC and the one I
suggested just now are not ambiguous because distinct prefixes:fn(params) => expr
|params| => exprI look forward to more discussion!
--
http://www.php.net/unsub.php
I personally prefer the|params| => expr
syntax.
I like the visual separation the syntax provides between auto-capturing, short closures and regular closures. It gives the impression that it should behave differently, rather than just being a shorter way of declaring a closure.
Below are a couple of real-world single line closures using the proposed syntax:
[1] Loop::defer(|| => ($this->when)($exception, $value));
[2] $this->watcher = Loop::delay($time, || => $this->resolve($value));
IMHO, the reduced boilerplate required makes it easier to discern what is happening.
Regards, Aaron Piotrowski
[1] https://github.com/amphp/amp/blob/master/lib/Coroutine.php#L45-L47
[2] https://github.com/amphp/amp/blob/master/lib/Pause.php#L21-L23
Hi Levi,
One more thing: I'd like to re-emphasize that the syntax that
JavaScript uses and the one that HHVM/Hack uses are ambiguous in the
current class of our grammar. The following will not work unless we
move to a more powerful grammar and parser class:(params) => expr (params) ==> expr
This is why an un-ambiguous prefix is necessary: the prefix breaks the
ambiguities. The syntax I have suggested in the RFC and the one I
suggested just now are not ambiguous because distinct prefixes:
Thanks for explanation.
an un-ambiguous prefix is necessary
This is what I guessed.
This should be emphasized and everyone should understand.
Otherwise, discussion goes nowhere.
fn(params) => expr |params| => expr
I look forward to more discussion!
It's unfortunate we cannot have HHVM/Hack syntax now
https://docs.hhvm.com/hack/lambdas/introduction
but both
fn(params) => expr
|params| => expr
would be good enough for now. I don't see much problem with
|(int | float) params| => expr
It's better to be compatible with other implementations if it is possible.
PHP may have HHVM/Hack syntax support in the future.
Regards,
--
Yasuo Ohgaki
yohgaki@ohgaki.net
fn(params) => expr |params| => expr
I look forward to more discussion!
It's unfortunate we cannot have HHVM/Hack syntax now
https://docs.hhvm.com/hack/lambdas/introductionbut both
fn(params) => expr
|params| => expr
would be good enough for now. I don't see much problem with
|(int | float) params| => expr
One question. Does the syntax allow chains?
function chained_allow_func() {
$f = |$x| => |$y| => $x + $y;
$fn = $f(3);
return $fn(2); // Returns 5
}
It would be great if this is supported.
Thanks.
--
Yasuo Ohgaki
yohgaki@ohgaki.net
Thanks to everyone who has participated in the discussion thus far.
Primarily the feedback has been directed at thefn
keyword. Let me
provide two benefits and drawbacks of usingfn
as a keyword:
fn
is searchable in search engines and in our manual- Is more intuitive than just syntax
However,
fn
does have downsides:
- Can break existing code
- We already have a similar keyword
function
To that end, I'd like to gauge interest in a pure syntax based
alternative that is similar to Rust and Ruby.
Instead of:fn(params) => expr
What about:
|params| => expr
This trades the advantages of the keyword for the advantages of pure
syntax, and happens to be two characters shorter. To be explicit:1. Preserves 100% backwards compatibility 2. Avoids having two keywords that both mean "function" 3. Is not easily searchable in engines or in the manual 4. Is a tad bit shorter
What do you think, Internals?
One more thing: I'd like to re-emphasize that the syntax that
JavaScript uses and the one that HHVM/Hack uses are ambiguous in the
current class of our grammar. The following will not work unless we
move to a more powerful grammar and parser class:(params) => expr (params) ==> expr
This is why an un-ambiguous prefix is necessary: the prefix breaks the
ambiguities. The syntax I have suggested in the RFC and the one I
suggested just now are not ambiguous because distinct prefixes:fn(params) => expr |params| => expr
I look forward to more discussion!
Off hand, either of the above options would be acceptable to me. The
union type concern is a valid one, but as noted I don't know how much of
an issue that would be in practice even if we ever did get union types.
(Now, if we also added defined type aliases... :-) )
I am definitely not a fan of reusing function
. The way I see it, the
point of a short-closure is to take a simple expression and wrap it into
a function so that it can be plugged into a function context. I don't
even think of it in the same way I would a named function/method, more
casting an expression to a function.
Additionally, to the point that was raised about developers being able
to understand syntax reused in different context, that's true... if the
context is in fact different. A bitwise AND and a reference are
extremely different situations so there's no reason for my brain to
expect both to mean the same thing. One is never a viable substitute
for the other.
In contrast, however, we're talking about two different syntaxes for
defining anonymous functions that have different closure semantics.
Reusing function
would mean:
$n = 2;
$x = function ($a) use ($n) { return $a * $n; }
$y = function ($a) => $a * $n;
Are equivalent. But in order to know what the capture semantics are I
can't tell from the start of the expression. I have to look halfway
down the line to know what the behavior is going to be for these two
extremely similar actions.
In contrast:
$n = 2;
$x = function ($a) use ($n) { return $a * $n; }
$y = fn($a) => $a * $n;
$z = |$a| => $a * $n;
I in versions $y and $z, I can tell right from the beginning of the line
which variant of "anonymous function capture logic" I will be dealing
with. I know from character 1 or 2, not character 12.
And then there's the extra typing and visual space taken up, which is
not something to dismiss entirely. Also, as someone else mentioned this
syntax seems like it would support nesting. Compare the following:
$x = function($a) => function($b) => function($c) => $a * $b * $c;
$y = fn($a) => fn($b) => fn($c) => $a * $b * $c;
$z = |$a| => |$b| => |$c| => $a * $b * $c;
print $x(1)(2)(3); // prints 6
Which of these is more readable? Id' argue it's not $x.
--Larry Garfield
2017-02-04 21:49 GMT+01:00 Larry Garfield larry@garfieldtech.com:
Thanks to everyone who has participated in the discussion thus far.
Primarily the feedback has been directed at the
fn
keyword. Let me
provide two benefits and drawbacks of usingfn
as a keyword:
fn
is searchable in search engines and in our manual- Is more intuitive than just syntax
However,
fn
does have downsides:
- Can break existing code
- We already have a similar keyword
function
To that end, I'd like to gauge interest in a pure syntax based
alternative that is similar to Rust and Ruby.
Instead of:fn(params) => expr
What about:
|params| => expr
This trades the advantages of the keyword for the advantages of pure
syntax, and happens to be two characters shorter. To be explicit:1. Preserves 100% backwards compatibility 2. Avoids having two keywords that both mean "function" 3. Is not easily searchable in engines or in the manual 4. Is a tad bit shorter
What do you think, Internals?
One more thing: I'd like to re-emphasize that the syntax that
JavaScript uses and the one that HHVM/Hack uses are ambiguous in the
current class of our grammar. The following will not work unless we
move to a more powerful grammar and parser class:(params) => expr (params) ==> expr
This is why an un-ambiguous prefix is necessary: the prefix breaks the
ambiguities. The syntax I have suggested in the RFC and the one I
suggested just now are not ambiguous because distinct prefixes:fn(params) => expr |params| => expr
I look forward to more discussion!
Off hand, either of the above options would be acceptable to me. The union
type concern is a valid one, but as noted I don't know how much of an issue
that would be in practice even if we ever did get union types. (Now, if we
also added defined type aliases... :-) )I am definitely not a fan of reusing
function
. The way I see it, the
point of a short-closure is to take a simple expression and wrap it into a
function so that it can be plugged into a function context. I don't even
think of it in the same way I would a named function/method, more casting
an expression to a function.Additionally, to the point that was raised about developers being able to
understand syntax reused in different context, that's true... if the
context is in fact different. A bitwise AND and a reference are extremely
different situations so there's no reason for my brain to expect both to
mean the same thing. One is never a viable substitute for the other.In contrast, however, we're talking about two different syntaxes for
defining anonymous functions that have different closure semantics. Reusing
function
would mean:$n = 2;
$x = function ($a) use ($n) { return $a * $n; }
$y = function ($a) => $a * $n;Are equivalent. But in order to know what the capture semantics are I
can't tell from the start of the expression. I have to look halfway down
the line to know what the behavior is going to be for these two extremely
similar actions.
I'd say the capture semantics aren't the first thing to be concerned with.
First you want to know it's a anonymous function with one parameter,
exactly what "function ($a)" tells you. For normal closures, "use ($n)"
tells you it imports $n from the parent scope into the body enclosed in
braces. For short closures, you see the "=>" and an expression and know
that any outer variable you use will be imported from the parent scope.
Regards, Niklas
In contrast:
$n = 2;
$x = function ($a) use ($n) { return $a * $n; }
$y = fn($a) => $a * $n;
$z = |$a| => $a * $n;I in versions $y and $z, I can tell right from the beginning of the line
which variant of "anonymous function capture logic" I will be dealing
with. I know from character 1 or 2, not character 12.And then there's the extra typing and visual space taken up, which is not
something to dismiss entirely. Also, as someone else mentioned this syntax
seems like it would support nesting. Compare the following:$x = function($a) => function($b) => function($c) => $a * $b * $c;
$y = fn($a) => fn($b) => fn($c) => $a * $b * $c;
$z = |$a| => |$b| => |$c| => $a * $b * $c;print $x(1)(2)(3); // prints 6
Which of these is more readable? Id' argue it's not $x.
--Larry Garfield
And then there's the extra typing and visual space taken up, which is not
something to dismiss entirely. Also, as someone else mentioned this syntax
seems like it would support nesting. Compare the following:$x = function($a) => function($b) => function($c) => $a * $b * $c;
$y = fn($a) => fn($b) => fn($c) => $a * $b * $c;
$z = |$a| => |$b| => |$c| => $a * $b * $c;print $x(1)(2)(3); // prints 6
Which of these is more readable? Id' argue it's not $x.
In a past version the RFC included an example of chaining. The current
version doesn't show an example, but does say it is possible. To be
clear:
$x = fn($a) => fn($b) => fn($c) => $a * $b * $c;
Is supported in the current implementation. It would similarly be
supported in the |params| => expr
notation.
I'd strongly prefer a syntax without the introduction of "fn" keyword -
e.g. similar to closures in other languages.
I also feel that there's a feature missing - something that was possible
with closures:
$total = 0;
$add = function ($value) use (&$total) {
$total += $value;
};
Per the RFC:
When a variable in the expression is defined in the parent scope it will
be captured implicitly by-value
Whether you regard it as a good thing or bad thing (I'm only pointing it
out) this is inconsistent with JavaScript, where variables in the parent
scope are captured by-reference.
If we're introducing a new form and syntax for closures, why not make this
one align with something that's going to be familiar with developers?
That's just my opinion, but whether you agree with that or not - as long as
we're introducing a new form and syntax, why make it less capable than
ordinary PHP closures? At the very least, I feel there should be feature
parity - otherwise, code in the wild is going to continue to be a strange
mess of one form or the other, which doesn't help with language
comprehension at all, especially when both forms also work differently from
JavaScript closures, which are likely the form of closures that
web-developers are going to be most familiar with.
Don't get me wrong, I'm not saying "make it like JavaScript" - what I'm
saying is, make something that is familiar to developers somehow, e.g.
either provide feature parity with ordinary PHP closures and make it
familiar to PHP developers, or make it similar to JavaScript closures,
but don't throw yet another "original" idea on the pile.
Ultimately, I think what I'd like to see would be something along the lines
of this:
$total = 0;
$add = ($value) => {
&$total += $value;
};
That is:
- Lose the fn keyword - get the syntax down to something similar to
closures in most other languages. - Keep it working like PHP (which you intend to do anyhow) in terms of
importing variables by-value. - Provide feature parity with regular PHP closures by providing some means
of accessing variables by-reference.
I understand that the fn keyword is there to remove ambiguities, but I
think working around the ambiguities is possible, even if it's difficult -
there was ambiguity with < and > operators in the run-of-the-mill generics
syntax I proposed last year, and Dominic Grostate was able to work through
them and get it to parse after all. I understand it's probably difficult,
and it may not be possible to achieve something that is 100% technically
correct, but it's usually possible to achieve something that works for
almost any real-world use-case.
The last thing I would comment on is multi-statement bodies. Omitting this
is, in my opinion, a very bad decision - it will, again, lead to lack of
feature parity with regular closures, which will mean, in practice,
factoring back and forth between regular closures and fat arrow functions,
which will be frustrating. It will also encourage developers to attempt to
fold complex operations into a single expression, leading to further
frustration for the programmer, and unreadable code for collaborators,
because "damnit I'm not going back to regular closures!", right?
In my opinion, if you can't provide feature parity on these points with
regular closures, this feature will hurt more than help - it will lead to a
lot of meaningless struggles, unreadable code, and code that doesn't
refactor well, and, eventually, BC breaks when PHP 7.x finally does
introduce these missing features.
Bob Weinand and I are happy to announce that the Arrow Functions
RFC is moving into the public discussion phase. We have been
collaborating on this RFC for many months now and finally have a
proposal we are happy to discuss in the open.Here is an example of an existing closure:
function ($x) use ($arr) { return $arr[$x]; }
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
More details are in the RFC. The implementation currently has no
known issues and is ready for you to download, build and test, which
we encourage you to do.We look forward to a productive discussion period and are happy to
answer questions.For historical purposes, the revision of this RFC is currently at
1485798604.
Here is an example of an existing closure:
function ($x) use ($arr) { return $arr[$x]; }
This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
I think a lot of the disagreements and confusions on this thread come
down to there being three fundamental views of what this new syntax is for:
(a) an improved syntax for declaring closures (in the way that [$foo,
$bar] is a shorter syntax for array($foo, $bar))
(b) improved semantics for declaring closures, where you don't have to
list the variables to be captured
(c) a new kind of closure designed for specific use cases, with its own
syntax and semantics
These aren't mutually exclusive aims, but which of them you have in mind
makes a big difference to what you see as "better" or "worse".
Many of those starting from view (a) or (b) would like to see the syntax
extended to closures with full bodies, and perhaps eventually become the
most common way of declaring closures. Even if not included initially,
they want to design the feature with that in mind. From view (c), the
syntax is expected to exist alongside existing closures forever, just as
we have both "for" and "while" loops.
For the record, I generally come from view (c).
as long as we're introducing a new form and syntax, why make itless capable than
ordinary PHP closures?
This is a good summary of the natural position from view (a) or (b) - if
this is going to be the new way of declaring closures, we should make it
the best way of declaring closures.
If it was just about making the syntax shorter, this would be fine -
like [...] for array(...) - but the Big Idea here is automatic capture
of variables, and that is a lot more than just a nicety of syntax. As
Rasmus L. has pointed out, making automatic variable capture the norm
would be a huge change in how PHP defined variable scope.
Since the comparison to JS keeps coming up, consider this: in JS, all
functions capture scope greedily when they're declared; in PHP, no
functions capture scope automatically; the use() clause maintains that
rule for anonymous functions, and (in my opinion) that is a feature, not
a mistake that needs fixing.
At the very least, I feel there should be feature
parity - otherwise, code in the wild is going to continue to be a strange
mess of one form or the other, which doesn't help with language
comprehension at all
To be clear, from view (c), there is absolutely nothing "strange" or
"messy" about future code having both closures and arrow-functions; they
are different tools, to be used in different circumstances.
So, is there any argument besides "6 more characters" fornot using the function keyword?
This question presumably comes from view (b) - if it's just another way
of declaring a function, why do we need a new keyword?
From view (a), those 6 more characters are enough argument in
themselves, because if the aim is to make it shorter, why stop early?
From view (c), the fact that the keywords are different is a feature
not a bug - these aren't functions in the normal sense, they are a new
way of defining a callable, so they should look different.
The way I see it, the point of a short-closure is to take a simple
expression and wrap it into a function so that it can be plugged into
a function context. I don't even think of it in the same way I would
a named function/method, more casting an expression to a function.
This, meanwhile, is a good summary of view (c), and expresses my view
better than I could myself.
If anything, I agree that "fn" is too much like "function"; perhaps we
should find something more distinct, like "lambda" ($foo = lambda($x)
=> $x * 2). That would have the advantage of giving a proper name to
these new callables, and make them easier to discuss: "when your
callback is too complex for a lambda, use a closure".
Obviously that would imply permanently cutting off all chance of full
function bodies with auto capture. Personally, I think that's a good
thing, but I realise not everyone agrees.
In short, remember that something that is "obviously better" for you may
be "obviously worse" for someone else, simply because you are measuring
against different aims.
Regards,
--
Rowan Collins
[IMSoP]
Hey everyone
I’m on team C as well.
One complaint about the RFC is that it doesn’t support multi-statement bodies. Arrow functions are especially useful for functional programming where it’s common to return a value in a single expression. Using multiple statements (partly) destroys the usefulness of the arrow function as that would require a return
keyword, braces and semicolons.
Additionally, long closures with multiple statements may actually benefit from not implicitly capturing variables from the outer scope, especially since in PHP there’s no keyword to declare your variables, which might lead to you accidentally capturing a variable instead of creating a new one. This isn’t as much of a problem with arrow functions as assignments are much less useful when you’re limited to a single expression.
Thus it might be best to use each when most appropriate.
@Levi, @Bob
Just out of curiosity, are variables captured by value for a specific reason?
Would there be any limitations capturing the variables by reference?
And also, have you considered letting people vote for their preferred arrow function syntax?
I kinda don’t think we’re gonna find an agreement as there are so many different opinions.
Regards,
Ilija
Here is an example of an existing closure:
function ($x) use ($arr) {
return $arr[$x];
}This RFC proposes syntax and semantics to simplify this common usage to:
fn($x) => $arr[$x]
I think a lot of the disagreements and confusions on this thread come
down to there being three fundamental views of what this new syntax is for:(a) an improved syntax for declaring closures (in the way that [$foo,
$bar] is a shorter syntax for array($foo, $bar))
(b) improved semantics for declaring closures, where you don't have to
list the variables to be captured
(c) a new kind of closure designed for specific use cases, with its own
syntax and semanticsThese aren't mutually exclusive aims, but which of them you have in mind
makes a big difference to what you see as "better" or "worse".Many of those starting from view (a) or (b) would like to see the syntax
extended to closures with full bodies, and perhaps eventually become the
most common way of declaring closures. Even if not included initially,
they want to design the feature with that in mind. From view (c), the
syntax is expected to exist alongside existing closures forever, just as
we have both "for" and "while" loops.For the record, I generally come from view (c).
as long as we're introducing a new form and syntax, why make itless capable than
ordinary PHP closures?This is a good summary of the natural position from view (a) or (b) - if
this is going to be the new way of declaring closures, we should make it
the best way of declaring closures.If it was just about making the syntax shorter, this would be fine -
like [...] for array(...) - but the Big Idea here is automatic capture
of variables, and that is a lot more than just a nicety of syntax. As
Rasmus L. has pointed out, making automatic variable capture the norm
would be a huge change in how PHP defined variable scope.Since the comparison to JS keeps coming up, consider this: in JS, all
functions capture scope greedily when they're declared; in PHP, no
functions capture scope automatically; the use() clause maintains that
rule for anonymous functions, and (in my opinion) that is a feature, not
a mistake that needs fixing.At the very least, I feel there should be feature
parity - otherwise, code in the wild is going to continue to be a strange
mess of one form or the other, which doesn't help with language
comprehension at allTo be clear, from view (c), there is absolutely nothing "strange" or
"messy" about future code having both closures and arrow-functions; they
are different tools, to be used in different circumstances.So, is there any argument besides "6 more characters" fornot using the function keyword?
This question presumably comes from view (b) - if it's just another way
of declaring a function, why do we need a new keyword?From view (a), those 6 more characters are enough argument in
themselves, because if the aim is to make it shorter, why stop early?
From view (c), the fact that the keywords are different is a feature
not a bug - these aren't functions in the normal sense, they are a new
way of defining a callable, so they should look different.The way I see it, the point of a short-closure is to take a simple
expression and wrap it into a function so that it can be plugged into
a function context. I don't even think of it in the same way I would
a named function/method, more casting an expression to a function.This, meanwhile, is a good summary of view (c), and expresses my view
better than I could myself.If anything, I agree that "fn" is too much like "function"; perhaps we
should find something more distinct, like "lambda" ($foo = lambda($x)
=> $x * 2). That would have the advantage of giving a proper name to
these new callables, and make them easier to discuss: "when your
callback is too complex for a lambda, use a closure".Obviously that would imply permanently cutting off all chance of full
function bodies with auto capture. Personally, I think that's a good
thing, but I realise not everyone agrees.In short, remember that something that is "obviously better" for you may
be "obviously worse" for someone else, simply because you are measuring
against different aims.Regards,
--
Rowan Collins
[IMSoP]
Hi Ilija,
And also, have you considered letting people vote for their preferred
arrow function syntax?
I kinda don’t think we’re gonna find an agreement as there are so many
different opinions.
The problem with voting on alternative syntaxes is precisely that there are so many different options. Designing a vote with multiple options that gives an answer people are happy with is a whole science in itself.
I think the best we can do is have a "without prejudice" vote on a single proposal - if it is declined, a new proposal can be made after a suitable period of reflection. This has already happened once with this very topic, this RFC having emerged from a previous one being rejected.
That doesn't mean we can't discuss other syntaxes, but just opening up all possible options to a vote doesn't really help IMHO.
Regards,
--
Rowan Collins
[IMSoP]
Hi Rowan
I see. I still think a simple poll would be useful to choose the least controversial syntax.
Otherwise I fear that the RFC might get rejected out of superficial reasons.
Regards,
Ilija
Hi Ilija,
And also, have you considered letting people vote for their preferred
arrow function syntax?
I kinda don’t think we’re gonna find an agreement as there are so many
different opinions.The problem with voting on alternative syntaxes is precisely that there are so many different options. Designing a vote with multiple options that gives an answer people are happy with is a whole science in itself.
I think the best we can do is have a "without prejudice" vote on a single proposal - if it is declined, a new proposal can be made after a suitable period of reflection. This has already happened once with this very topic, this RFC having emerged from a previous one being rejected.
That doesn't mean we can't discuss other syntaxes, but just opening up all possible options to a vote doesn't really help IMHO.
Regards,
--
Rowan Collins
[IMSoP]
Den 2017-03-24 kl. 21:08, skrev ilija.tovilo@me.com:
Hi Rowan
I see. I still think a simple poll would be useful to choose the least controversial syntax.
Otherwise I fear that the RFC might get rejected out of superficial reasons.Regards,
IlijaHi Ilija,
And also, have you considered letting people vote for their preferred
arrow function syntax?
I kinda don’t think we’re gonna find an agreement as there are so many
different opinions.
The problem with voting on alternative syntaxes is precisely that there are so many different options. Designing a vote with multiple options that gives an answer people are happy with is a whole science in itself.I think the best we can do is have a "without prejudice" vote on a single proposal - if it is declined, a new proposal can be made after a suitable period of reflection. This has already happened once with this very topic, this RFC having emerged from a previous one being rejected.
That doesn't mean we can't discuss other syntaxes, but just opening up all possible options to a vote doesn't really help IMHO.
Regards,
--
Rowan Collins
[IMSoP]--
Hi,
My suggestion for a vote would be:
- Vote about the feature.
- Vote about syntax if no consensus can be reached.
My suggestion would be to both have a short and long version:
- |params| => expr
- lambda(params) => expr
An example where one have two syntaxes for same feature is
the jQuery library, i.e. $() and jQuery().
I plan to read up on the RFC once more this week regarding
the feature itself. Any plans to go with this for 7.2?
Regards //Björn Larsson
Any plans to go with this for 7.2?
I have been working on this RFC a bit in the last two weeks and intend
to start voting within the next week.
Den 2017-04-05 kl. 23:57, skrev Levi Morrison:
Any plans to go with this for 7.2?
I have been working on this RFC a bit in the last two weeks and intend
to start voting within the next week.
Great, I look forward to reading the updated RFC :) Will you
include both a short- and longhand version of the syntax or
only one?
Regards //Björn Larsson