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