> On Jan 10, 2021, at 20:09, Larry Garfield <la...@garfieldtech.com> wrote:
> 
> 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


I have no problem introducing this idiom (or similar). In fact, I welcome it.

In userland, the same concept is often achieved with methods like 
`fromOrNull()`, and as Mark points out, the word “try” makes me think the 
method should throw an exception if it fails. I’m not advocating for 
`xOrNull()`, though, since I think that smacks of Hungarian notation, but maybe 
we can come up with something that is a more PHP-ish name. ;-)

“There are two hard things in computer science: cache invalidation, naming 
things, and off-by-one errors.” --Phil Karlton

Cheers,
Ben

Attachment: signature.asc
Description: Message signed with OpenPGP

Reply via email to