Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:112839 Return-Path: Delivered-To: mailing list internals@lists.php.net Received: (qmail 68387 invoked from network); 10 Jan 2021 23:02:28 -0000 Received: from unknown (HELO localhost.localdomain) (76.75.200.58) by pb1.pair.com with SMTP; 10 Jan 2021 23:02:28 -0000 To: internals@lists.php.net References: Date: Sun, 10 Jan 2021 22:40:00 +0000 User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:78.0) Gecko/20100101 Thunderbird/78.6.0 MIME-Version: 1.0 In-Reply-To: Content-Type: text/plain; charset=utf-8; format=flowed Content-Language: en-GB Content-Transfer-Encoding: 7bit X-Posted-By: 87.81.129.66 Subject: Re: "TryX" idom for Enumerations From: marandall@php.net (Mark Randall) Message-ID: 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. 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: ( 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