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 <olleharst...@gmail.com> wrote: > 2023-07-17 21:57 GMT+02:00, Larry Garfield <la...@garfieldtech.com>: > > On Mon, Jul 17, 2023, at 7:07 PM, Olle Härstedt wrote: > >> 2023-07-17 18:58 GMT+02:00, Larry Garfield <la...@garfieldtech.com>: > >>> On Mon, Jul 17, 2023, at 2:57 PM, Olle Härstedt wrote: > >>>> 2023-07-17 14:25 GMT+02:00, Karoly Negyesi <kar...@negyesi.net>: > >>>>> 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 >