On 13-02-2020 17:55, Larry Garfield wrote:
> I walked right into that one, didn't I...

You did. :)

> Well, Dik asked me to post a "fabulous functional programming example".  I 
> dont' have one, so I'll go with one from the book I'm working on instead. :-)

Thanks, much appreciated.

> $() or variations thereof
> 
> $result = Stats::of($string)
>     ->analyze($(normalizeNewlines))
>     ->analyze($(readingLevel))
>     ->analyze($(countStats))
>     ->analyze($($synonymSuggester, 'analyze'))
>     ->analyze($(WordCouter::class, 'analyze'))
>     ->analyze(fn($s) => wordDistribution($s, 3))
> ;
> 
> Analysis: I'm not sure I like this one, visually.  "($(..))" feels like a lot 
> of sigils soup.  It also doesn't offer a way to deal with the method names in 
> the object versions, unless we just assume that bare strings are allowed 
> there, like so:
> 
> $result = Stats::of($string)
>     ->analyze($(normalizeNewlines))
>     ->analyze($(readingLevel))
>     ->analyze($(countStats))
>     ->analyze($($synonymSuggester, analyze))
>     ->analyze($(WordCouter::class, analyze))
>     ->analyze(fn($s) => wordDistribution($s, 3))
> ;

If the $() construct would only accept methods then it provides an
environment without the usual ambiguity and we can write:

$result = Stats::of($string)
    ->analyze($(normalizeNewlines))
    ->analyze($(readingLevel))
    ->analyze($(countStats))
    ->analyze($($synonymSuggester->analyze))
    ->analyze($(WordCouter::analyze))
    ->analyze(fn($s) => wordDistribution($s, 3));

The RFC of Michał (https://wiki.php.net/rfc/short-closures) would yield:

$result = Stats::of($string)
    ->analyze({normalizeNewlines})
    ->analyze({readingLevel})
    ->analyze({countStats})
    ->analyze({$synonymSuggester->analyze})
    ->analyze({WordCouter::analyze})
    ->analyze(fn($s) => wordDistribution($s, 3));

To me this looks less soup-ish compared to using $().

> I will say that, given the behavior of ::class now, ::fn or ::name "feel 
> like" they should return a string, whereas $() "feels like" it should return 
> a callable, or something richer than a string.  That's naturally subjective 
> but is consistent with ::foo being a constant value and $() being, um, jQuery.

Although a closure would also be a constant I share your 'feel like'
issue. It might just need getting used to.

> Of course... I feel compelled to ask why we can't just use bare function 
> names.  Treating a bare string as a string has been deprecated for several 
> versions.  If we remove that in PHP 8 and instead let it mean constant, then 
> function, then class name, the following would become legal:
> 
> $result = Stats::of($string)
>     ->analyze(normalizeNewlines)
>     ->analyze(readingLevel)
>     ->analyze(countStats)
>     ->analyze([$synonymSuggester, analyze])
>     ->analyze([WordCouter, analyze])
>     ->analyze(fn($s) => wordDistribution($s, DISTRIBUTION_LIMIT))
> ;
> 
> Which would be much more in line with how many other languages handle symbol 
> names.  (There is likely some engine reason why it's way harder than I make 
> it sound; I'd love to hear what that is so I know not to suggest it again, 
> unless it really is that simple in which case...)

I guess using bare function names in that context could be supported. I
would prefer getting rid of these awkward array constructs altogether
though and just write $synonymSuggester->analyze in stead. This requires
a context that only accepts methods, which is what $() or {} could provide.

As a side note, I would love to have a name for these closure producing
constructs we are talking about. Maybe: 'enclosure'?

Regards,
Dik Takken

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to