On Sun, Jan 10, 2021, at 4:40 PM, Mark Randall wrote:
> On 10/01/2021 21:27, Larry Garfield wrote:
> > The "a method that begins with try is nullable, so watch out" idiom is 
> > present in C# and Rust, but to my knowledge has never existed in PHP.  That 
> > doesn't make it bad; it actually combines quite well with the null coalesce 
> > operator to allow for default values, making a valueOrDefault() method 
> > unnecessary.
> 
> I get the advantages of returning null, in particular WRT the null 
> coalescing operator.
> 
> However, when I see 'try' I instictively think 'exceptions' i.e. 
> try/catch when the reality is it's the opposite and it would be the 
> non-try functions which throw.
> 
> But it makes sense for those to throw.

That was my initial response as well, and my main concern.  To a PHP developer, 
the terminology seems backwards.  But it's not like we haven't adopted idioms 
and syntax from other languages before.

> However if you will permit me a tangent...
> 
> There is an alternative, of sorts. Something I tried investigating when 
> I first started looking into PHP-SRC, but lack the skill and knowledge 
> to implement myself.
> 
> A shorthand try / catch of something like the form:
> 
> <tryname>(<expr, ExceptionType => ResultExpr, ...)
> 
> At which point tryFrom becomes:
> 
> $order = attempt(SortOrder::tryFrom($input), ValueError => SortOrder::Asc);
> 
> Which would be the equivilent of:
> 
> function attempt(callable $try, array $map): mixed {
>    try {
>      return $try();
>    }
>    catch ($e) {
>      foreach ($map as $class => $expr) {
>         if (is_subclass_of($e, $class, true)) {
>            return $expr();
>         }
>      }
> 
>      throw $e;
>    }
> }
> 
> Or just allow a mixed value to be given without a mapping for catching 
> Throwable.
> 
> If added as a language construct, except each expr and $try itself would 
> be parsed closure at language construct level to avoid needing to fn() 
> them all e.g.
> 
> $foo = attempt(fn() => SortOrder::tryFrom($input), [ ValueError => fn() 
> => null ]);
> 
> Just a thought, perhaps a cleaner solution to a wider problem. A try / 
> catch combined with a match.
> 
> It avoids the need for two methods, just provide the one that throws and 
> use shorthand to assign a null if it throws.
> 
> Mark Randall

The main issue I see is that creating an exception is quite expensive.  (Or it 
was the last time I bothered benchmarking it, which admittedly has been a 
while.)  So even if you had some built in "catch and match" pseudo-function, 
you're still paying the cost of the exception, which is not cheap.

catch-and-match is an interesting idiom, but as you say it's somewhat 
tangential to the question at hand.

--Larry Garfield

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to