On Sat, Sep 26, 2015 at 1:07 PM, Rowan Collins <rowan.coll...@gmail.com>
wrote:

> On 26/09/2015 17:17, Levi Morrison wrote:
>
>> What concerns do you have about `fn($x) => $x * 2` or `function($x) =>
>> $x * 2`? I will be writing a proper RFC later but I wanted to get
>> discussion going now.
>>
>
> If a keyword is required next to the parameters, having the => as a
> separate token looks a bit weird. It no longer matches other languages, so
> how about thinking a bit further outside the box?
>
> One of the random thoughts that popped into my head during the previous
> discussion was to base the syntax on the C for-loop, which would also give
> a place for bound variables without the "use" keyword. e.g. your example
> could become fn($x;; $x * 2)
>
> I picked "lambda" as the keyword before, and gave these examples:
>
> # lambda(params; bound vars; expression)
> $double = lambda($a;; 2*$a)
> $x=3; $triple = lambda($a; $x; $x * $a)
>
> function sumEventScores($events, $scores) {
>     $types = array_map(lambda($event;; $event['type']), $events);
>     return array_reduce($types, lambda($sum, $type; $scores; $sum +
> $scores[$type]));
> }
>
>
> Adding in the type information, we'd get this:
>
> lambda(int $sum, string $type; $scores; $sum + $scores[$type])
> # or with fn() if you prefer:
> fn(int $sum, string $type; $scores; $sum + $scores[$type])
>
>
> If return typehints are also required, I'm not sure where they'd best be
> placed. If they're outside the parens, they end up after the expression,
> which might look odd:
> fn(int $sum, string $type; $scores; $sum + $scores[$type]): int
>
> A few other possibilities:
> fn(int $sum, string $type; $scores; $sum + $scores[$type]; int)
> fn(int $sum, string $type: int; $scores; $sum + $scores[$type])
> fn:int(int $sum, string $type; $scores; $sum + $scores[$type])
>
>
> All of this assumes that the shorthand is only available for simple
> expressions, not function bodies, but it seems a bit rendundant to allow
> both of these:
> function($x) { foo(); bar(); baz(); }
> fn($x) => { foo(); bar(); baz(); }
>
> And only marginally more useful if variables are auto-captured, with all
> the downsides of that which have already been raised:
> function($x) use ($y) { foo($x); bar($x, $y); }
> fn($x) => { foo($x); bar($x, $y); }


I'm leaning toward a compromise between Levi's suggested syntax (which is
unambiguous and short, but auto-closes over parent's scope) and Rowan's
for-loop style (which imports variables but the syntax feels cramped to
me).  Example:

$a = 1;
$b = fn($x; $a) => $x + $a;    // note the semi-colon here, $a is
explicitly imported
$c = $b(1); // 2

All variables after the semi-colon are imported.  The semi-colon and
variable list is optional.  This could be extended to function proper,
coexisting with, or deprecating, the use syntax.  Example:

Before:
function foo($x) use ($y) { ... }

Becomes:
function foo($x; $y) { ... }

And I think it continues to work with STH:

function bar(string $x, int $y; int $a):int {
    $b = strlen($x) + $y + $a;
    return fn(int $c; int $b):int => $b + $c;
}

$a = 5;
bar('hello', 1)(2); // lucky number 13

bishop

Reply via email to