Re: [PHP-DEV] Re: "TryX" idom for Enumerations
On 10/01/2021 22:40, Mark Randall wrote: 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, ...) Funnily enough, I just wrote an aide that a language could provide this in a discussion of indicating errors via throw vs return. [1] My contention being that exceptions make it easier to express "do these steps in order and abort the whole sequence on the first error", but harder to express "combine these results, but if this one errors substitute this value", because an exception always implies a jump in control flow. Larry makes a good point that the capture of a stack trace for exceptions makes them unnecessarily expensive in cases where you're immediately handling them, though. I don't know if there's a way around that, without re-designing exceptions completely. [1] https://softwareengineering.stackexchange.com/a/421004/96713 Regards, -- Rowan Tommins [IMSoP] -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php
Re: [PHP-DEV] Re: "TryX" idom for Enumerations
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: > > ( 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
[PHP-DEV] Re: "TryX" idom for Enumerations
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 -- PHP Internals - PHP Runtime Development Mailing List To unsubscribe, visit: https://www.php.net/unsub.php