Re: [PHP-DEV] pipes, scalar objects and on?
On Tue, Jul 18, 2023 at 8:05 AM Robert Landers wrote: > On Tue, Jul 18, 2023 at 3:18 PM Olle Härstedt > wrote: > > > > 2023-07-18 14:48 GMT+02:00, someniatko : > > > I am glad this topic arose! I was also planning to write on this topic > to > > > the internals mailing list, but have abandoned this idea, because I > feel it > > > might be inconvenient for the real active PHP developers on the list to > > > receive too many emails from the people which don't actively > participate in > > > the development itself. > > > > > > My interest in the pipe operator might seem a little non-standard - > > > basically what I'd really want to see is a **nullable** pipe operator! > > > > > > There is a popular library github.com/schmittjoh/php-option, which > has 250 > > > MILLION installations. Basically what it provides is a class-wrapper > of a > > > value of lack thereof: it's either `Some` or `None`. I also > maintain > > > a similar library > https://packagist.org/packages/someniatko/result-type > > > which fixes some shortcomings of the original one related to the static > > > analysis, but this is another story. Basically what the stats tell us > is > > > that such stuff is popular among the PHP community. > > > > > > In my eyes, it is actually semantically equivalent to the nullable PHP > > > types: `?Type`. And some operations provided by the lib, are actually > > > covered by PHP itself, which has multiple null-friendly operators: > > > `$option->getOrElse($defaultVal)` --> `$nullable ?? $defaultVal` > > > `$option->isEmpty()` --> `$nullable === null` > > > `$option->getOrThrow(new \Exception('blah'))` --> `$nullable ?? throw > new > > > \Exception('blah')` > > > > > > I'd like to use the arguably "more idiomatic" native PHP nullables, > rather > > > than a foreign-feeling userspace construct, if they were more > convenient. > > > > > > But there is a very important operation, `map()`, which is > unfortunately > > > not covered by the native PHP, which is `Option::map()`, and here is a > > > real-world example: > > > ``` > > > return $repository->getById($idFromHttpRequest) > > > ->map($serializer->serializeToJson(...)) // only executes when the > > > Option is Some, not None > > > ->map(fn (string $json) => new Response(status: 200, content: > $json)) > > > ->getOrElse(new Response(status: 404)); > > > ``` > > > > Ehm, wouldn't that be the same as a Pipe class that's configured to > > stop on null? > > > > public function getThing($id) { > > return new Pipe( > > $this->getData(...), > > $this->serializeData(...), > > $this->mapToResponse(...) > > ) > > ->stopOnEmpty() > > ->from($id) > > ->run(); > > } > > > > Wait, are you using map() for arrays or not? Looks like not. > > > > Olle > > > > -- > > PHP Internals - PHP Runtime Development Mailing List > > To unsubscribe, visit: https://www.php.net/unsub.php > > > > I might be venting, but, I wish the operators RFC had passed... > I don't think I will re-propose it with the current set of voters tbh. The main people who contribute to the Zend folder (the core engine/compiler parts) were highly skeptical of it, with at least two telling me flat out that they would vote no even on a hypothetical perfect feature design. Very few contributors actually touch large parts of that area of the engine, so most voters tend to take the opinions of those 5-6 voters very seriously on such proposals. As I don't think it's possible for me to convince those 5-6 people, I don't think it would be a good idea to re-propose, because even if I did get a 2/3 vote on it, I feel like the people most responsible for helping me maintain the feature would not be very happy/willing to do so, and that would probably harm the PHP project in other ways. Jordan
Re: [PHP-DEV] pipes, scalar objects and on?
On Wed, Jul 19, 2023, at 12:08 PM, Olle Härstedt wrote: > 2023-07-18 18:50 GMT+02:00, Larry Garfield : >> On Tue, Jul 18, 2023, at 4:47 PM, Olle Härstedt wrote: >> >>> Any comment on a pipe (or piped process) as a first-class value? When >>> you use |> the functions are immediately applied, which might not be >>> what you want. You can lazify it by wrapping it in a lambda, but I >>> think that decreases the value of the pipe concept in itself. One >>> strength is the ability to split the decision about what to glue >>> together from the decision on how to execute it. You kinda get some >>> light-weight metaprogramming ability that way. >>> >>> Well i guess such a pipe-concept is pretty far removed from the simple >>> pipe operator. :) And also already possible with existing OOP >>> concepts, callable classes, and now the (...) syntax. >> >> That's the function concat operator I have been mentioning. Concat can be >> implemented in terms of pipe, and pipe can be implemented in terms of >> concat, but I'd rather have both natively. >> >> For more on my thoughts there, see: >> https://peakd.com/hive-168588/@crell/aoc2021-review > > Right, I think I was thinking more of the pipeline design pattern than > the pipe operator. The concat operator will tell you THAT two > functions have been glued together, but you have no way to affect HOW > they are glued together. With the pipeline design pattern, you do: For > example, you could add a logger that logs each input and output in the > Pipe class without much hassle. > > The pipeline design pattern could still greatly benefit from some of > these RFCs tho, especially partial function application, I think. > > Olle OK, terminology mismatch. What you're calling "pipeline design pattern" I'm calling "that's literally what a monad is." :-) (More precisely, monads are the mathematical rules that a "fancy function concatenation" operation has to follow in order to still be composable cleanly. You could make pipeline-like things that don't follow those rules, but they'd be less useful.) Your logging example is literally the "writer monad," one of the standard monad examples. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
2023-07-18 18:50 GMT+02:00, Larry Garfield : > On Tue, Jul 18, 2023, at 4:47 PM, Olle Härstedt wrote: > >> Any comment on a pipe (or piped process) as a first-class value? When >> you use |> the functions are immediately applied, which might not be >> what you want. You can lazify it by wrapping it in a lambda, but I >> think that decreases the value of the pipe concept in itself. One >> strength is the ability to split the decision about what to glue >> together from the decision on how to execute it. You kinda get some >> light-weight metaprogramming ability that way. >> >> Well i guess such a pipe-concept is pretty far removed from the simple >> pipe operator. :) And also already possible with existing OOP >> concepts, callable classes, and now the (...) syntax. > > That's the function concat operator I have been mentioning. Concat can be > implemented in terms of pipe, and pipe can be implemented in terms of > concat, but I'd rather have both natively. > > For more on my thoughts there, see: > https://peakd.com/hive-168588/@crell/aoc2021-review Right, I think I was thinking more of the pipeline design pattern than the pipe operator. The concat operator will tell you THAT two functions have been glued together, but you have no way to affect HOW they are glued together. With the pipeline design pattern, you do: For example, you could add a logger that logs each input and output in the Pipe class without much hassle. The pipeline design pattern could still greatly benefit from some of these RFCs tho, especially partial function application, I think. Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
2023-07-18 21:44 GMT+02:00, Deleu : > https://wiki.php.net/rfc/short-functions >> https://wiki.php.net/rfc/auto-capture-closure >> https://wiki.php.net/rfc/partial_function_application >> https://wiki.php.net/rfc/pipe-operator-v2 > > > The only thing I can think of is if we gather a team of ~20 ppl and come up > with a plan on collectively getting Voting Karma so that we can have these > awesomeness revisited. Or, we gather the main concern(s) of the no-voters and try to approach those? :) Put them in a sheet (Google or Excel) and try to make sense out of it, if there's a way forward. Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
https://wiki.php.net/rfc/short-functions > https://wiki.php.net/rfc/auto-capture-closure > https://wiki.php.net/rfc/partial_function_application > https://wiki.php.net/rfc/pipe-operator-v2 The only thing I can think of is if we gather a team of ~20 ppl and come up with a plan on collectively getting Voting Karma so that we can have these awesomeness revisited. -- Marco Deleu
Re: [PHP-DEV] pipes, scalar objects and on?
2023-07-18 20:08 GMT+02:00, Larry Garfield : > On Tue, Jul 18, 2023, at 5:08 PM, Karoly Negyesi wrote: >> My favorite pipeline is Elixir, where "The pipe operator |> passes the >> result of an expression as the first parameter of another expression".. >> But >> it works there because unlike with PHP, it's almost always the first >> argument you want. If it's not the first argument you needed to do some >> tricks which was only cleaned up in 2021 so now they do: >> >> 5 >> |> then((1..10, &1)) >> |> Enum.reverse() >> >> but I digress. >> >> My problem here is... we actually need something that passes the RFC >> vote. >> >> What flexibility is missing here? > > Please don't top post. > > The main flexibility for callables is the ability to build a closure on the > fly. For example, using $$ (which Hack does, and I insist on calling > T_BLING) means that for array and string functions you still need to worry > about parameter order. With a callable, you can effectively emulate > Elixir's behavior if you want. > > For example, my FP library has a whole bunch of higher order functions that > just return pipe-ready functions: > > https://github.com/Crell/fp/blob/master/src/array.php > > Which, with a pipe operator, would allow for: > > $result = $arr > |> amap(trim(...)) > |> afilter(is_int(...)) > |> reduce(0, $fn) > |> trim(...) // At this point it's a string and trim() is already unary, > so we can just use it. > ; > > Which is pretty nice, IMO. It "flows" nicely, supports both higher order > functions and direct calls equally well, and allows for all kinds of further > expansion that I haven't thought of yet. > > The Hack style would require thinking about the fact that array_map() and > array_filter() take their arguments in reverse order from each other, which > is just silly. This way, that problem goes away entirely. > > It also allows a pipe to be used as a quasi alternative to scalar methods, > because (if we set aside visibility for the moment) a method is just a > function with an implicit $this parameter. Callables and higher order > functions make that a lot cleaner. > > The caveat is that it does add an extra step to use many of the existing > array or string stdlib functions. However, that's work that can be done > once. The link above is under 500 lines, heavily documented, and covers > every array use case I've run into so far. > > Related improvements: > > * Writing a higher order function right now is rather cumbersome. There > were two previous RFCs that would have made that vastly nicer > (short-functions and auto-capture closures), but neither passed. They would > have allowed for: > > function amap(callable $c) => fn (iterable $it): array { > if (is_array($it)) { > return array_map($c, $it); > } > $result = []; > foreach ($it as $k => $v) { > $result[$k] = $c($v); > } > return $result; > }; > > Which I think is pretty nice. > > * PFA would give us the best of both worlds, as if you wanted you could do: > > $result = $arr > |> array_map(trim(...), ?) > |> array_filter(?, is_int(...)) > |> array_reduce(?, $fn, 0) > |> trim(...) > ; Damn, that PFA RFC would _really_ help with removing noise, instead of wrapping with fn ($x) => ... everywhere. Shame it didn't pass. :/ 29 vs 20 votes. Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
On Tue, Jul 18, 2023, at 5:08 PM, Karoly Negyesi wrote: > My favorite pipeline is Elixir, where "The pipe operator |> passes the > result of an expression as the first parameter of another expression".. But > it works there because unlike with PHP, it's almost always the first > argument you want. If it's not the first argument you needed to do some > tricks which was only cleaned up in 2021 so now they do: > > 5 > |> then((1..10, &1)) > |> Enum.reverse() > > but I digress. > > My problem here is... we actually need something that passes the RFC vote. > > What flexibility is missing here? Please don't top post. The main flexibility for callables is the ability to build a closure on the fly. For example, using $$ (which Hack does, and I insist on calling T_BLING) means that for array and string functions you still need to worry about parameter order. With a callable, you can effectively emulate Elixir's behavior if you want. For example, my FP library has a whole bunch of higher order functions that just return pipe-ready functions: https://github.com/Crell/fp/blob/master/src/array.php Which, with a pipe operator, would allow for: $result = $arr |> amap(trim(...)) |> afilter(is_int(...)) |> reduce(0, $fn) |> trim(...) // At this point it's a string and trim() is already unary, so we can just use it. ; Which is pretty nice, IMO. It "flows" nicely, supports both higher order functions and direct calls equally well, and allows for all kinds of further expansion that I haven't thought of yet. The Hack style would require thinking about the fact that array_map() and array_filter() take their arguments in reverse order from each other, which is just silly. This way, that problem goes away entirely. It also allows a pipe to be used as a quasi alternative to scalar methods, because (if we set aside visibility for the moment) a method is just a function with an implicit $this parameter. Callables and higher order functions make that a lot cleaner. The caveat is that it does add an extra step to use many of the existing array or string stdlib functions. However, that's work that can be done once. The link above is under 500 lines, heavily documented, and covers every array use case I've run into so far. Related improvements: * Writing a higher order function right now is rather cumbersome. There were two previous RFCs that would have made that vastly nicer (short-functions and auto-capture closures), but neither passed. They would have allowed for: function amap(callable $c) => fn (iterable $it): array { if (is_array($it)) { return array_map($c, $it); } $result = []; foreach ($it as $k => $v) { $result[$k] = $c($v); } return $result; }; Which I think is pretty nice. * PFA would give us the best of both worlds, as if you wanted you could do: $result = $arr |> array_map(trim(...), ?) |> array_filter(?, is_int(...)) |> array_reduce(?, $fn, 0) |> trim(...) ; So with PFA and callable pipes, we get both options. If pipe was just Hack-style, there would be no way to use higher order functions with it. So IMO, the ideal experience that gets almost everyone what they want would be if all four of the following had passed: https://wiki.php.net/rfc/short-functions https://wiki.php.net/rfc/auto-capture-closure https://wiki.php.net/rfc/partial_function_application https://wiki.php.net/rfc/pipe-operator-v2 They are all mutually-complementary, but also useful on their own, and were designed that way deliberately. Sadly, all four were declined. So yeah, it's great that there's renewed interest in pipes, but I've already sunk a ton of time into this space (as have many other people that helped with those RFCs) with nothing to show for it. Unless there's indication from a notable number of voters that they'd support it now, I'm reluctant to sink much more of my time (or anyone else's time) into something that has so far just run into brick walls. If any of the above has convinced someone that we should try any of these features again, please speak up. I seriously do want this functionality, but OSS spec work is not my favorite way to spend time. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
My favorite pipeline is Elixir, where "The pipe operator |> passes the result of an expression as the first parameter of another expression".. But it works there because unlike with PHP, it's almost always the first argument you want. If it's not the first argument you needed to do some tricks which was only cleaned up in 2021 so now they do: 5 |> then((1..10, &1)) |> Enum.reverse() but I digress. My problem here is... we actually need something that passes the RFC vote. What flexibility is missing here? On Tue, Jul 18, 2023 at 6:48 PM Larry Garfield wrote: > On Tue, Jul 18, 2023, at 4:41 PM, Karoly Negyesi wrote: > > So. Let's get back to pipelines. > > > > I wrote this email because I was manipulating a robots meta tag string: > > > > $robots_array = explode(', ', $robots_string); > > $robots_array = array_diff($robots_array, $remove); > > $robots_string = implode(', ', $robots_array); > > > > Very pipeline-ish. > > > > You could write a userspace pipeline > > https://gist.github.com/chx/6638aba76d8b414ffedc7e5af78fb479 but this > has > > the advantage of being spectacularly ugly and slow as well. > > > > Just converting it into a pipeline with > > > > $robots_string > > |> fn ($x) => explode(', ', $x) > > |> fn ($x) => array_diff($x, $remove) > > |> fn ($x) => implode(', ', $x) > > > > has the same characteristics. What I would love to see: > > > > $robots_string > > |> explode(', ', $) > > |> array_diff($, $remove) > > |> implode(', ', $) > > > > While that does look like partial function application, it does not need > to > > be. It could be just syntactic sugar. Namely, in the expression following > > |> a $ is replaced by the entire expression before the |>. Step by step: > > > > explode(', ', $robots_string) > > |> array_diff($, $remove) > > |> implode(', ', $) > > > > array_diff(explode(', ', $robots_string), $remove) > > |> implode(', ', $) > > > > implode(', ', array_diff(explode(', ', $robots_string), $remove)) > > > > We could use any other symbol but I liked the $ sign here because the > > entire point is not needing a temporary variable between steps so the $ > > sign stands for "unnamed temporary variable". I also believe it can't > lead > > to any ambiguous situation (famous last words). > > > > What do you think of this simple version? > > That's what Hack does, and what no other language does. I dislike it as > it's actually much less flexible overall. It's also more work to implement. > > The original idea was that combining real PFA with a callable-based pipe > would give us the same net effect if we wanted it, but with greater > flexibility and more power across the whole language. Unfortunately the > PFA RFC barely didn't pass, due to its complexity. A nicer implementation, > if it could be found, would probably pass. > > --Larry Garfield >
Re: [PHP-DEV] pipes, scalar objects and on?
On Tue, Jul 18, 2023, at 4:47 PM, Olle Härstedt wrote: > Any comment on a pipe (or piped process) as a first-class value? When > you use |> the functions are immediately applied, which might not be > what you want. You can lazify it by wrapping it in a lambda, but I > think that decreases the value of the pipe concept in itself. One > strength is the ability to split the decision about what to glue > together from the decision on how to execute it. You kinda get some > light-weight metaprogramming ability that way. > > Well i guess such a pipe-concept is pretty far removed from the simple > pipe operator. :) And also already possible with existing OOP > concepts, callable classes, and now the (...) syntax. That's the function concat operator I have been mentioning. Concat can be implemented in terms of pipe, and pipe can be implemented in terms of concat, but I'd rather have both natively. For more on my thoughts there, see: https://peakd.com/hive-168588/@crell/aoc2021-review --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
On Tue, Jul 18, 2023, at 4:41 PM, Karoly Negyesi wrote: > So. Let's get back to pipelines. > > I wrote this email because I was manipulating a robots meta tag string: > > $robots_array = explode(', ', $robots_string); > $robots_array = array_diff($robots_array, $remove); > $robots_string = implode(', ', $robots_array); > > Very pipeline-ish. > > You could write a userspace pipeline > https://gist.github.com/chx/6638aba76d8b414ffedc7e5af78fb479 but this has > the advantage of being spectacularly ugly and slow as well. > > Just converting it into a pipeline with > > $robots_string > |> fn ($x) => explode(', ', $x) > |> fn ($x) => array_diff($x, $remove) > |> fn ($x) => implode(', ', $x) > > has the same characteristics. What I would love to see: > > $robots_string > |> explode(', ', $) > |> array_diff($, $remove) > |> implode(', ', $) > > While that does look like partial function application, it does not need to > be. It could be just syntactic sugar. Namely, in the expression following > |> a $ is replaced by the entire expression before the |>. Step by step: > > explode(', ', $robots_string) > |> array_diff($, $remove) > |> implode(', ', $) > > array_diff(explode(', ', $robots_string), $remove) > |> implode(', ', $) > > implode(', ', array_diff(explode(', ', $robots_string), $remove)) > > We could use any other symbol but I liked the $ sign here because the > entire point is not needing a temporary variable between steps so the $ > sign stands for "unnamed temporary variable". I also believe it can't lead > to any ambiguous situation (famous last words). > > What do you think of this simple version? That's what Hack does, and what no other language does. I dislike it as it's actually much less flexible overall. It's also more work to implement. The original idea was that combining real PFA with a callable-based pipe would give us the same net effect if we wanted it, but with greater flexibility and more power across the whole language. Unfortunately the PFA RFC barely didn't pass, due to its complexity. A nicer implementation, if it could be found, would probably pass. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
2023-07-18 17:13 GMT+02:00, Larry Garfield : > On Tue, Jul 18, 2023, at 1:05 PM, Olle Härstedt wrote: >> 2023-07-18 14:48 GMT+02:00, someniatko : >>> I am glad this topic arose! I was also planning to write on this topic >>> to >>> the internals mailing list, but have abandoned this idea, because I feel >>> it >>> might be inconvenient for the real active PHP developers on the list to >>> receive too many emails from the people which don't actively participate >>> in >>> the development itself. >>> >>> My interest in the pipe operator might seem a little non-standard - >>> basically what I'd really want to see is a **nullable** pipe operator! >>> >>> There is a popular library github.com/schmittjoh/php-option, which has >>> 250 >>> MILLION installations. Basically what it provides is a class-wrapper of >>> a >>> value of lack thereof: it's either `Some` or `None`. >> >> I'd just like to mention that the Option type comes from FP and it's >> not necessarily needed in PHP-land where we have flow-sensitive type >> checkers like Psalm (a nullable type `?int` or such is refined to just >> `int` after a null check). Flow-sensitive type-checking was not >> invented when the Option type was first created, so adding it to PHP >> is basically stepping back in time, from my point of view. > > As I've written before[1], there's a lot of overlap in different > error-flow-control options. PHP at the moment leans heavily on the "null is > error and build tooling around that" approach, which has its pros (mainly > simplicity) and cons (lack of information). That mostly obviates the need > for a Maybe type, but not entirely. Right now, there is no "null pipeline" > option in the language like someniako is describing. > > In some sense, that's also trivial to do in user-space[2], which leads > easily to > > $foo > |> maybe(bar(...)) > |> maybe(baz(...)) > |> maybe(beep(...)); > > Which isn't terrible, but also isn't ideal. I don't think I'd oppose a > nullsafe pipe if there's interest (though again, we need interest in pipes > in general first). > > However, that runs into the related problem that Maybe is... the weaker way > of handling error context. In most cases I prefer a Result/Either type, > which doesn't map cleanly to null handling. That could be done as a > user-space monad (as above, with just a class and method or a magic method > and dedicated operator). Doing it more natively would require deeper > language hooks. For instance, Rust has the ? suffix on any expression, > which means "if this evaluates to an Error case Result, just return that > Result." That wouldn't fit well in PHP, though. > > As I noted in [1], one option would be to allow an object to flag itself as > an error object, and then null-check operators would treat that as null. So > given $result = foo($a)->bar(), if foo() returns an error object then > $result is assigned to that error object and bar() is never called. I'm > still not sure if I like that approach myself, but am open to hear what > others think. > > To get back on topic, I do think a pipe operator and concat operator are > valuable in their own right, and have ample use cases even without mixing in > monads or nullables or things like that. We should add them. We can > consider adding more robust branching options as well, (be that >>=, ?|>, or > something else), but be aware that beyond the very trivial case that will > necessarily involve user-space code for many use cases and we'll need to > support that. (Which basically comes down to >>= and making monadic classes > easier to work with, but also runs into the generics problem, and that's its > own mess.) > > [1] https://peakd.com/hive-168588/@crell/much-ado-about-null > [2] https://github.com/Crell/fp/blob/master/src/composition.php#L39 > > --Larry Garfield > Any comment on a pipe (or piped process) as a first-class value? When you use |> the functions are immediately applied, which might not be what you want. You can lazify it by wrapping it in a lambda, but I think that decreases the value of the pipe concept in itself. One strength is the ability to split the decision about what to glue together from the decision on how to execute it. You kinda get some light-weight metaprogramming ability that way. Well i guess such a pipe-concept is pretty far removed from the simple pipe operator. :) And also already possible with existing OOP concepts, callable classes, and now the (...) syntax. Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
So. Let's get back to pipelines. I wrote this email because I was manipulating a robots meta tag string: $robots_array = explode(', ', $robots_string); $robots_array = array_diff($robots_array, $remove); $robots_string = implode(', ', $robots_array); Very pipeline-ish. You could write a userspace pipeline https://gist.github.com/chx/6638aba76d8b414ffedc7e5af78fb479 but this has the advantage of being spectacularly ugly and slow as well. Just converting it into a pipeline with $robots_string |> fn ($x) => explode(', ', $x) |> fn ($x) => array_diff($x, $remove) |> fn ($x) => implode(', ', $x) has the same characteristics. What I would love to see: $robots_string |> explode(', ', $) |> array_diff($, $remove) |> implode(', ', $) While that does look like partial function application, it does not need to be. It could be just syntactic sugar. Namely, in the expression following |> a $ is replaced by the entire expression before the |>. Step by step: explode(', ', $robots_string) |> array_diff($, $remove) |> implode(', ', $) array_diff(explode(', ', $robots_string), $remove) |> implode(', ', $) implode(', ', array_diff(explode(', ', $robots_string), $remove)) We could use any other symbol but I liked the $ sign here because the entire point is not needing a temporary variable between steps so the $ sign stands for "unnamed temporary variable". I also believe it can't lead to any ambiguous situation (famous last words). What do you think of this simple version? On Tue, Jul 18, 2023 at 2:57 PM Olle Härstedt wrote: > 2023-07-17 21:57 GMT+02:00, Larry Garfield : > > On Mon, Jul 17, 2023, at 7:07 PM, Olle Härstedt wrote: > >> 2023-07-17 18:58 GMT+02:00, Larry Garfield : > >>> On Mon, Jul 17, 2023, at 2:57 PM, Olle Härstedt wrote: > 2023-07-17 14:25 GMT+02:00, Karoly Negyesi : > > Hi, > > > > I tried to read on why the pipe RFC failed but by and large I also > > failed. > > > > The discussion on https://github.com/php/php-src/pull/7214 is very > > short. > > > > https://externals.io/message/114770 is not so short but it seems not > > to > > cover the latest version which uses first class functions? > > > > Could someone please give me a summary why it failed? I really would > > like > > to see it succeed :) I am writing code if not daily but certainly > > weekly > > that certainly looks like a pipeline. > > The pipe RFC was kinda forced in before a deadline, no? > > My own two cents: > > * It's trivial to implement a pipe() function or a Pipe class > * A Pipe class is better than both a function and built-in operator, > since it can be configured with custom behaviour, e.g. stop or throw > on empty payload, or repeat on a collection, or even with parallelism > or concurrency > * If I had voting rights, I'd vote in favor in a pipe operator :) > >>> > >>> From my recollection, there were a couple of things involved. > >>> > >>> 1. It was intended to pair with the PFA RFC, which didn't pass, which > >>> made > >>> it a bit less compelling. > >>> 2. It was close to the RFC deadline, and it seems people get squeamish > >>> around that. > >>> 3. Some folks wanted Hack-style pipes instead of the pipes used by > every > >>> other language with pipes. I've written before on why that's a worse > >>> design. > >>> 4. Arguments that it can be done in user space, which is not true, as I > >>> have > >>> a user-space implementation and it's comparatively cumbersome and > >>> definitely > >>> slower than a native operator would be. > >>> 5. General "meh" attitude on FP features in general from some people. > >>> > >>> Side note to Olle: If you want a customizable pipe, you've just > described > >>> a > >>> Monad. :-) It's literally "contextually-sensitive func concatenation." > >>> A > >>> monadic bind operator would be harder to do with PHP's weaker type > >>> system, > >>> but there are ways it could be done. > >> > >> Mm I don't really agree with that, I think monads make sense only in > >> languages which support them syntactically. A Pipe class is a very > >> straight-forward construction, and the blog posts I've read about > >> monads in PHP don't look pretty at all; lots of syntactic noise going > >> on. But that's another discussion... :) > > > > At its most basic: > > > > class Foo { > > public function __construct(public readonly mixed $val) {} > > > > public __bind(callable $c) { > > return $c($this->val); > > } > > } > > > > new Foo('beep') >>= func(...); > > > > Where >>= is the operator that translates to "Call __bind() on the LHS > > object with the callable on the RHS." Poof, we now have a monad > operator. > > This one is effectively the same as |> as it doesn't do anything, but you > > can do whatever you want in the __bind() method. > > 1. You also want syntactic sugar around this to "flatten" monadic > usage; in OCaml it's `let*`. > > 2. This way you won't
Re: [PHP-DEV] pipes, scalar objects and on?
On 18 Jul 2023, at 16:13, Larry Garfield wrote: > PHP at the moment leans heavily on the "null is error and build tooling > around that" approach Yep, you should never use NULL in your code, the following is catastrophically bad... $search = ($_GET['q'] ?? NULL); $search = (isset($_GET['q']) ? $_GET['q'] : NULL); // Pre PHP 7 $search = filter_input(INPUT_GET, 'q'); $search = $request->input('q'); // Laravel $search = $request->get('q'); // Symfony $search = $this->request->getQuery('q'); // CakePHP $search = $request->getGet('q'); // CodeIgniter $search = json_decode('{"q":null}'); And all fields in the database must be set to NOT NULL, never use things like LEFT JOIN, etc... :-( Craig -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
On Tue, Jul 18, 2023, at 1:05 PM, Olle Härstedt wrote: > 2023-07-18 14:48 GMT+02:00, someniatko : >> I am glad this topic arose! I was also planning to write on this topic to >> the internals mailing list, but have abandoned this idea, because I feel it >> might be inconvenient for the real active PHP developers on the list to >> receive too many emails from the people which don't actively participate in >> the development itself. >> >> My interest in the pipe operator might seem a little non-standard - >> basically what I'd really want to see is a **nullable** pipe operator! >> >> There is a popular library github.com/schmittjoh/php-option, which has 250 >> MILLION installations. Basically what it provides is a class-wrapper of a >> value of lack thereof: it's either `Some` or `None`. > > I'd just like to mention that the Option type comes from FP and it's > not necessarily needed in PHP-land where we have flow-sensitive type > checkers like Psalm (a nullable type `?int` or such is refined to just > `int` after a null check). Flow-sensitive type-checking was not > invented when the Option type was first created, so adding it to PHP > is basically stepping back in time, from my point of view. As I've written before[1], there's a lot of overlap in different error-flow-control options. PHP at the moment leans heavily on the "null is error and build tooling around that" approach, which has its pros (mainly simplicity) and cons (lack of information). That mostly obviates the need for a Maybe type, but not entirely. Right now, there is no "null pipeline" option in the language like someniako is describing. In some sense, that's also trivial to do in user-space[2], which leads easily to $foo |> maybe(bar(...)) |> maybe(baz(...)) |> maybe(beep(...)); Which isn't terrible, but also isn't ideal. I don't think I'd oppose a nullsafe pipe if there's interest (though again, we need interest in pipes in general first). However, that runs into the related problem that Maybe is... the weaker way of handling error context. In most cases I prefer a Result/Either type, which doesn't map cleanly to null handling. That could be done as a user-space monad (as above, with just a class and method or a magic method and dedicated operator). Doing it more natively would require deeper language hooks. For instance, Rust has the ? suffix on any expression, which means "if this evaluates to an Error case Result, just return that Result." That wouldn't fit well in PHP, though. As I noted in [1], one option would be to allow an object to flag itself as an error object, and then null-check operators would treat that as null. So given $result = foo($a)->bar(), if foo() returns an error object then $result is assigned to that error object and bar() is never called. I'm still not sure if I like that approach myself, but am open to hear what others think. To get back on topic, I do think a pipe operator and concat operator are valuable in their own right, and have ample use cases even without mixing in monads or nullables or things like that. We should add them. We can consider adding more robust branching options as well, (be that >>=, ?|>, or something else), but be aware that beyond the very trivial case that will necessarily involve user-space code for many use cases and we'll need to support that. (Which basically comes down to >>= and making monadic classes easier to work with, but also runs into the generics problem, and that's its own mess.) [1] https://peakd.com/hive-168588/@crell/much-ado-about-null [2] https://github.com/Crell/fp/blob/master/src/composition.php#L39 --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
On Tue, Jul 18, 2023 at 3:18 PM Olle Härstedt wrote: > > 2023-07-18 14:48 GMT+02:00, someniatko : > > I am glad this topic arose! I was also planning to write on this topic to > > the internals mailing list, but have abandoned this idea, because I feel it > > might be inconvenient for the real active PHP developers on the list to > > receive too many emails from the people which don't actively participate in > > the development itself. > > > > My interest in the pipe operator might seem a little non-standard - > > basically what I'd really want to see is a **nullable** pipe operator! > > > > There is a popular library github.com/schmittjoh/php-option, which has 250 > > MILLION installations. Basically what it provides is a class-wrapper of a > > value of lack thereof: it's either `Some` or `None`. I also maintain > > a similar library https://packagist.org/packages/someniatko/result-type > > which fixes some shortcomings of the original one related to the static > > analysis, but this is another story. Basically what the stats tell us is > > that such stuff is popular among the PHP community. > > > > In my eyes, it is actually semantically equivalent to the nullable PHP > > types: `?Type`. And some operations provided by the lib, are actually > > covered by PHP itself, which has multiple null-friendly operators: > > `$option->getOrElse($defaultVal)` --> `$nullable ?? $defaultVal` > > `$option->isEmpty()` --> `$nullable === null` > > `$option->getOrThrow(new \Exception('blah'))` --> `$nullable ?? throw new > > \Exception('blah')` > > > > I'd like to use the arguably "more idiomatic" native PHP nullables, rather > > than a foreign-feeling userspace construct, if they were more convenient. > > > > But there is a very important operation, `map()`, which is unfortunately > > not covered by the native PHP, which is `Option::map()`, and here is a > > real-world example: > > ``` > > return $repository->getById($idFromHttpRequest) > > ->map($serializer->serializeToJson(...)) // only executes when the > > Option is Some, not None > > ->map(fn (string $json) => new Response(status: 200, content: $json)) > > ->getOrElse(new Response(status: 404)); > > ``` > > Ehm, wouldn't that be the same as a Pipe class that's configured to > stop on null? > > public function getThing($id) { > return new Pipe( > $this->getData(...), > $this->serializeData(...), > $this->mapToResponse(...) > ) > ->stopOnEmpty() > ->from($id) > ->run(); > } > > Wait, are you using map() for arrays or not? Looks like not. > > Olle > > -- > PHP Internals - PHP Runtime Development Mailing List > To unsubscribe, visit: https://www.php.net/unsub.php > I might be venting, but, I wish the operators RFC had passed... -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
2023-07-18 14:48 GMT+02:00, someniatko : > I am glad this topic arose! I was also planning to write on this topic to > the internals mailing list, but have abandoned this idea, because I feel it > might be inconvenient for the real active PHP developers on the list to > receive too many emails from the people which don't actively participate in > the development itself. > > My interest in the pipe operator might seem a little non-standard - > basically what I'd really want to see is a **nullable** pipe operator! > > There is a popular library github.com/schmittjoh/php-option, which has 250 > MILLION installations. Basically what it provides is a class-wrapper of a > value of lack thereof: it's either `Some` or `None`. I also maintain > a similar library https://packagist.org/packages/someniatko/result-type > which fixes some shortcomings of the original one related to the static > analysis, but this is another story. Basically what the stats tell us is > that such stuff is popular among the PHP community. > > In my eyes, it is actually semantically equivalent to the nullable PHP > types: `?Type`. And some operations provided by the lib, are actually > covered by PHP itself, which has multiple null-friendly operators: > `$option->getOrElse($defaultVal)` --> `$nullable ?? $defaultVal` > `$option->isEmpty()` --> `$nullable === null` > `$option->getOrThrow(new \Exception('blah'))` --> `$nullable ?? throw new > \Exception('blah')` > > I'd like to use the arguably "more idiomatic" native PHP nullables, rather > than a foreign-feeling userspace construct, if they were more convenient. > > But there is a very important operation, `map()`, which is unfortunately > not covered by the native PHP, which is `Option::map()`, and here is a > real-world example: > ``` > return $repository->getById($idFromHttpRequest) > ->map($serializer->serializeToJson(...)) // only executes when the > Option is Some, not None > ->map(fn (string $json) => new Response(status: 200, content: $json)) > ->getOrElse(new Response(status: 404)); > ``` Ehm, wouldn't that be the same as a Pipe class that's configured to stop on null? public function getThing($id) { return new Pipe( $this->getData(...), $this->serializeData(...), $this->mapToResponse(...) ) ->stopOnEmpty() ->from($id) ->run(); } Wait, are you using map() for arrays or not? Looks like not. Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
2023-07-18 14:48 GMT+02:00, someniatko : > I am glad this topic arose! I was also planning to write on this topic to > the internals mailing list, but have abandoned this idea, because I feel it > might be inconvenient for the real active PHP developers on the list to > receive too many emails from the people which don't actively participate in > the development itself. > > My interest in the pipe operator might seem a little non-standard - > basically what I'd really want to see is a **nullable** pipe operator! > > There is a popular library github.com/schmittjoh/php-option, which has 250 > MILLION installations. Basically what it provides is a class-wrapper of a > value of lack thereof: it's either `Some` or `None`. I'd just like to mention that the Option type comes from FP and it's not necessarily needed in PHP-land where we have flow-sensitive type checkers like Psalm (a nullable type `?int` or such is refined to just `int` after a null check). Flow-sensitive type-checking was not invented when the Option type was first created, so adding it to PHP is basically stepping back in time, from my point of view. Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
2023-07-17 21:57 GMT+02:00, Larry Garfield : > On Mon, Jul 17, 2023, at 7:07 PM, Olle Härstedt wrote: >> 2023-07-17 18:58 GMT+02:00, Larry Garfield : >>> On Mon, Jul 17, 2023, at 2:57 PM, Olle Härstedt wrote: 2023-07-17 14:25 GMT+02:00, Karoly Negyesi : > Hi, > > I tried to read on why the pipe RFC failed but by and large I also > failed. > > The discussion on https://github.com/php/php-src/pull/7214 is very > short. > > https://externals.io/message/114770 is not so short but it seems not > to > cover the latest version which uses first class functions? > > Could someone please give me a summary why it failed? I really would > like > to see it succeed :) I am writing code if not daily but certainly > weekly > that certainly looks like a pipeline. The pipe RFC was kinda forced in before a deadline, no? My own two cents: * It's trivial to implement a pipe() function or a Pipe class * A Pipe class is better than both a function and built-in operator, since it can be configured with custom behaviour, e.g. stop or throw on empty payload, or repeat on a collection, or even with parallelism or concurrency * If I had voting rights, I'd vote in favor in a pipe operator :) >>> >>> From my recollection, there were a couple of things involved. >>> >>> 1. It was intended to pair with the PFA RFC, which didn't pass, which >>> made >>> it a bit less compelling. >>> 2. It was close to the RFC deadline, and it seems people get squeamish >>> around that. >>> 3. Some folks wanted Hack-style pipes instead of the pipes used by every >>> other language with pipes. I've written before on why that's a worse >>> design. >>> 4. Arguments that it can be done in user space, which is not true, as I >>> have >>> a user-space implementation and it's comparatively cumbersome and >>> definitely >>> slower than a native operator would be. >>> 5. General "meh" attitude on FP features in general from some people. >>> >>> Side note to Olle: If you want a customizable pipe, you've just described >>> a >>> Monad. :-) It's literally "contextually-sensitive func concatenation." >>> A >>> monadic bind operator would be harder to do with PHP's weaker type >>> system, >>> but there are ways it could be done. >> >> Mm I don't really agree with that, I think monads make sense only in >> languages which support them syntactically. A Pipe class is a very >> straight-forward construction, and the blog posts I've read about >> monads in PHP don't look pretty at all; lots of syntactic noise going >> on. But that's another discussion... :) > > At its most basic: > > class Foo { > public function __construct(public readonly mixed $val) {} > > public __bind(callable $c) { > return $c($this->val); > } > } > > new Foo('beep') >>= func(...); > > Where >>= is the operator that translates to "Call __bind() on the LHS > object with the callable on the RHS." Poof, we now have a monad operator. > This one is effectively the same as |> as it doesn't do anything, but you > can do whatever you want in the __bind() method. 1. You also want syntactic sugar around this to "flatten" monadic usage; in OCaml it's `let*`. 2. This way you won't get read-process-write pipelines as first-class values, which you can do if you just make a Pipe class instead. I think. Correct me if I'm wrong. :) Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
I am glad this topic arose! I was also planning to write on this topic to the internals mailing list, but have abandoned this idea, because I feel it might be inconvenient for the real active PHP developers on the list to receive too many emails from the people which don't actively participate in the development itself. My interest in the pipe operator might seem a little non-standard - basically what I'd really want to see is a **nullable** pipe operator! There is a popular library github.com/schmittjoh/php-option, which has 250 MILLION installations. Basically what it provides is a class-wrapper of a value of lack thereof: it's either `Some` or `None`. I also maintain a similar library https://packagist.org/packages/someniatko/result-type which fixes some shortcomings of the original one related to the static analysis, but this is another story. Basically what the stats tell us is that such stuff is popular among the PHP community. In my eyes, it is actually semantically equivalent to the nullable PHP types: `?Type`. And some operations provided by the lib, are actually covered by PHP itself, which has multiple null-friendly operators: `$option->getOrElse($defaultVal)` --> `$nullable ?? $defaultVal` `$option->isEmpty()` --> `$nullable === null` `$option->getOrThrow(new \Exception('blah'))` --> `$nullable ?? throw new \Exception('blah')` I'd like to use the arguably "more idiomatic" native PHP nullables, rather than a foreign-feeling userspace construct, if they were more convenient. But there is a very important operation, `map()`, which is unfortunately not covered by the native PHP, which is `Option::map()`, and here is a real-world example: ``` return $repository->getById($idFromHttpRequest) ->map($serializer->serializeToJson(...)) // only executes when the Option is Some, not None ->map(fn (string $json) => new Response(status: 200, content: $json)) ->getOrElse(new Response(status: 404)); ``` I'd really like to write such code in a native way: ``` return $repository->getById($idFromHttpRequest) ?|> $serializer->serializeToJson($$) ?|> new Response(status: 200, content: $$) ?? new Response(status: 404); ``` Notice I use the old syntax here, using `$$` as a "piped" intermediate result variable, mostly because I'd like to use arbitrary PHP expressions, instead of piping functions only. I feel this is more natural for the PHP than the more functional-oriented way. I am okay with using functions too like this: ``` return $repository->getById($idFromHttpRequest) ?|> $serializer->serializeToJson(...) ?|> fn (string $json) => new Response(status: 200, content: $json) ?? new Response(status: 404); ``` but that feels less "clean", and also note the inconsistency with `?? new Response(status: 404)` part. Regards, Illia / someniatko
Re: [PHP-DEV] pipes, scalar objects and on?
On Mon, Jul 17, 2023, at 7:07 PM, Olle Härstedt wrote: > 2023-07-17 18:58 GMT+02:00, Larry Garfield : >> On Mon, Jul 17, 2023, at 2:57 PM, Olle Härstedt wrote: >>> 2023-07-17 14:25 GMT+02:00, Karoly Negyesi : Hi, I tried to read on why the pipe RFC failed but by and large I also failed. The discussion on https://github.com/php/php-src/pull/7214 is very short. https://externals.io/message/114770 is not so short but it seems not to cover the latest version which uses first class functions? Could someone please give me a summary why it failed? I really would like to see it succeed :) I am writing code if not daily but certainly weekly that certainly looks like a pipeline. >>> >>> The pipe RFC was kinda forced in before a deadline, no? >>> >>> My own two cents: >>> >>> * It's trivial to implement a pipe() function or a Pipe class >>> * A Pipe class is better than both a function and built-in operator, >>> since it can be configured with custom behaviour, e.g. stop or throw >>> on empty payload, or repeat on a collection, or even with parallelism >>> or concurrency >>> * If I had voting rights, I'd vote in favor in a pipe operator :) >> >> From my recollection, there were a couple of things involved. >> >> 1. It was intended to pair with the PFA RFC, which didn't pass, which made >> it a bit less compelling. >> 2. It was close to the RFC deadline, and it seems people get squeamish >> around that. >> 3. Some folks wanted Hack-style pipes instead of the pipes used by every >> other language with pipes. I've written before on why that's a worse >> design. >> 4. Arguments that it can be done in user space, which is not true, as I have >> a user-space implementation and it's comparatively cumbersome and definitely >> slower than a native operator would be. >> 5. General "meh" attitude on FP features in general from some people. >> >> Side note to Olle: If you want a customizable pipe, you've just described a >> Monad. :-) It's literally "contextually-sensitive func concatenation." A >> monadic bind operator would be harder to do with PHP's weaker type system, >> but there are ways it could be done. > > Mm I don't really agree with that, I think monads make sense only in > languages which support them syntactically. A Pipe class is a very > straight-forward construction, and the blog posts I've read about > monads in PHP don't look pretty at all; lots of syntactic noise going > on. But that's another discussion... :) At its most basic: class Foo { public function __construct(public readonly mixed $val) {} public __bind(callable $c) { return $c($this->val); } } new Foo('beep') >>= func(...); Where >>= is the operator that translates to "Call __bind() on the LHS object with the callable on the RHS." Poof, we now have a monad operator. This one is effectively the same as |> as it doesn't do anything, but you can do whatever you want in the __bind() method. But that's a separate operation from |> or func concat. (Unless we wanted to implement it as an operator override for |> that an object can do, which... is an option. I don't know if I like that option, but is an option.) The implementation for all of this is fairly trivial. It's agreeing to do it that is the challenge. --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
2023-07-17 18:58 GMT+02:00, Larry Garfield : > On Mon, Jul 17, 2023, at 2:57 PM, Olle Härstedt wrote: >> 2023-07-17 14:25 GMT+02:00, Karoly Negyesi : >>> Hi, >>> >>> I tried to read on why the pipe RFC failed but by and large I also >>> failed. >>> >>> The discussion on https://github.com/php/php-src/pull/7214 is very >>> short. >>> >>> https://externals.io/message/114770 is not so short but it seems not to >>> cover the latest version which uses first class functions? >>> >>> Could someone please give me a summary why it failed? I really would >>> like >>> to see it succeed :) I am writing code if not daily but certainly weekly >>> that certainly looks like a pipeline. >> >> The pipe RFC was kinda forced in before a deadline, no? >> >> My own two cents: >> >> * It's trivial to implement a pipe() function or a Pipe class >> * A Pipe class is better than both a function and built-in operator, >> since it can be configured with custom behaviour, e.g. stop or throw >> on empty payload, or repeat on a collection, or even with parallelism >> or concurrency >> * If I had voting rights, I'd vote in favor in a pipe operator :) > > From my recollection, there were a couple of things involved. > > 1. It was intended to pair with the PFA RFC, which didn't pass, which made > it a bit less compelling. > 2. It was close to the RFC deadline, and it seems people get squeamish > around that. > 3. Some folks wanted Hack-style pipes instead of the pipes used by every > other language with pipes. I've written before on why that's a worse > design. > 4. Arguments that it can be done in user space, which is not true, as I have > a user-space implementation and it's comparatively cumbersome and definitely > slower than a native operator would be. > 5. General "meh" attitude on FP features in general from some people. > > Side note to Olle: If you want a customizable pipe, you've just described a > Monad. :-) It's literally "contextually-sensitive func concatenation." A > monadic bind operator would be harder to do with PHP's weaker type system, > but there are ways it could be done. Mm I don't really agree with that, I think monads make sense only in languages which support them syntactically. A Pipe class is a very straight-forward construction, and the blog posts I've read about monads in PHP don't look pretty at all; lots of syntactic noise going on. But that's another discussion... :) Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
On Mon, Jul 17, 2023, at 2:57 PM, Olle Härstedt wrote: > 2023-07-17 14:25 GMT+02:00, Karoly Negyesi : >> Hi, >> >> I tried to read on why the pipe RFC failed but by and large I also failed. >> >> The discussion on https://github.com/php/php-src/pull/7214 is very short. >> >> https://externals.io/message/114770 is not so short but it seems not to >> cover the latest version which uses first class functions? >> >> Could someone please give me a summary why it failed? I really would like >> to see it succeed :) I am writing code if not daily but certainly weekly >> that certainly looks like a pipeline. > > The pipe RFC was kinda forced in before a deadline, no? > > My own two cents: > > * It's trivial to implement a pipe() function or a Pipe class > * A Pipe class is better than both a function and built-in operator, > since it can be configured with custom behaviour, e.g. stop or throw > on empty payload, or repeat on a collection, or even with parallelism > or concurrency > * If I had voting rights, I'd vote in favor in a pipe operator :) >From my recollection, there were a couple of things involved. 1. It was intended to pair with the PFA RFC, which didn't pass, which made it a bit less compelling. 2. It was close to the RFC deadline, and it seems people get squeamish around that. 3. Some folks wanted Hack-style pipes instead of the pipes used by every other language with pipes. I've written before on why that's a worse design. 4. Arguments that it can be done in user space, which is not true, as I have a user-space implementation and it's comparatively cumbersome and definitely slower than a native operator would be. 5. General "meh" attitude on FP features in general from some people. Side note to Olle: If you want a customizable pipe, you've just described a Monad. :-) It's literally "contextually-sensitive func concatenation." A monadic bind operator would be harder to do with PHP's weaker type system, but there are ways it could be done. I'd like to bring the Pipes RFC back if I thought there was a reasonable potential for it to pass this time. I would use the crap out of it myself. Though I've also since decided that we do need a straight up func concat operator as well. (I previously thought one would be sufficient, but in practice I think we do want both.) --Larry Garfield -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] pipes, scalar objects and on?
2023-07-17 14:25 GMT+02:00, Karoly Negyesi : > Hi, > > I tried to read on why the pipe RFC failed but by and large I also failed. > > The discussion on https://github.com/php/php-src/pull/7214 is very short. > > https://externals.io/message/114770 is not so short but it seems not to > cover the latest version which uses first class functions? > > Could someone please give me a summary why it failed? I really would like > to see it succeed :) I am writing code if not daily but certainly weekly > that certainly looks like a pipeline. The pipe RFC was kinda forced in before a deadline, no? My own two cents: * It's trivial to implement a pipe() function or a Pipe class * A Pipe class is better than both a function and built-in operator, since it can be configured with custom behaviour, e.g. stop or throw on empty payload, or repeat on a collection, or even with parallelism or concurrency * If I had voting rights, I'd vote in favor in a pipe operator :) Olle -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php