Re: Re: "TryX" idom for Enumerations
| From: | Larry Garfield | Date: | Mon, 11 Jan 2021 02:09:54 +0000 |
| Subject: | Re: Re: "TryX" idom for Enumerations | ||
| References: | 1 2 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-112840@lists.php.net to get a copy of this message | ||
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