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<Type>` 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

Reply via email to