On Tue, Jul 18, 2023, at 1:05 PM, Olle Härstedt wrote:
> 2023-07-18 14:48 GMT+02:00, someniatko <somenia...@gmail.com>:
>> 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'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

Reply via email to