Re: [PHP-DEV] Re: "TryX" idom for Enumerations

2021-01-15 Thread Rowan Tommins

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

2021-01-10 Thread Larry Garfield
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

2021-01-10 Thread Mark Randall

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