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
>

Reply via email to