Re: [RFC]

From: 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

« previous php.internals (#108554) next »