Re: [RFC]
| From: | Dik Takken | Date: | Thu, 13 Feb 2020 23:13:31 +0000 |
| Subject: | Re: [RFC] | ||
| References: | 1 2 3 4 5 6 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-108554@lists.php.net to get a copy of this message | ||
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