Nikita Nefedov wrote on 01/10/2015 15:58:
On Thu, 01 Oct 2015 15:33:51 +0300, Rowan Collins <rowan.coll...@gmail.com> wrote:
It is a tool for making them shorter, yes, but it is not the only way, and it comes with a cost of changing established behaviour. Again, look at C++'s lambda syntax - it is much shorter than PHP's, but requires a list of all variables from the outer scope being captured.

C++11 doesn't *require* the list of all variables, but it does require explicit "wildcard" ([=] for copy semantics, [&] for capturing by reference).

I'm not actually that familiar with C++'s lambdas, and was basing my understanding on this page: https://msdn.microsoft.com/en-us/library/dd293608.aspx

I read this line as implying the same behaviour as PHP's:

> An empty capture clause, *[ ]*, indicates that the body of the lambda expression accesses no variables in the enclosing scope.

But on closer inspection, the meaning of [=] on its own is just not terribly clear on that particular description, so I stand corrected.


But C++ is not the best place for picking up syntax choices, quite frankly it's one of the least readable languages in a way that it allows you to write very cryptic code easily (but still allows to write perfectly readable code as well).

Sure, short syntax leads to hard-to-read code. A good argument to stick to the existing PHP verbosity.

And, again, I was not advocating C++'s exact syntax (it conflicts with existing syntax anyway), merely showing that "short" and "explicitly listed captures" are not mutually exclusive.


I don't think there was a dozen of different ideas, I could only find those about `lambda(arg-list; use-list; expression)` and variations of it with different keywords and different return-type syntax.

Fair enough. But there's no point me addressing bikeshedding details about semi-colon vs other punctuation, etc, etc, if you are fundamentally opposed to requiring an explicit list of used variables.


And one thing that makes auto capture much better choice than explicit capture (as it've been said a couple of times already) is partial application:

    $mul = fn($x) => fn($y) => fn($z) => $x * $y * $z;

Looks simpler than:

    $mul = fn($x) => fn($y; $x) => fn($z; $x, $y) => $x * $y * $z;

It looks simpler, but it's an illusion - there is actually a closure hidden in there that has argument ($z) and captures ($x, $y). To someone not used to chaining, and not expecting scopes to be inherited, it's far from simple to follow where $x and $y come from and end up.

Let's pick another syntax - again, completely off the top of my head, may not even be possible:

# { args|captures => return }
$double = { $x => $x * 2 }
$mul = {$x => {$y|$x => {$z|$x,$y => $x * $y * $z} } }

Note that the nesting is indicated explicitly, rather than via associativity, the captured variables are listed explicitly, but clearly separated from the argument list.

So my question is: if a short syntax was suggested which required explicit capture but otherwise seemed compact and elegant, would you be interested, or do you consider auto-capture a non-negotiable feature?

Regards,
--
Rowan Collins
[IMSoP]

Reply via email to