2017-02-04 21:49 GMT+01:00 Larry Garfield <la...@garfieldtech.com>:

> On 02/03/2017 11:53 AM, Levi Morrison wrote:
>
>>
>> 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:
>>>
>>>    1. `fn` is searchable in search engines and in our manual
>>>    2. Is more intuitive than just syntax
>>>
>>> However, `fn` does have downsides:
>>>
>>>    1. Can break existing code
>>>    2. 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
>
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>
>

Reply via email to