Making "match" catch exceptions

php.internals

Olle Härstedt

5 years ago
Hi, Someone mentioned that they prefer lambdas over try-catch blocks, which surprised me, since try-catch is completely idiomatic in both PHP and OCaml (Haskell I don't know). That made me think of a recent extension to OCaml which makes it possible to catch exceptions in a match-expressions (here's one blog post about it: https://blog.janestreet.com/pattern-matching-and-exception-handling-unite/). Now when PHP also has `match`, are there any plans to extend it with exception catching? So far I did not find anything about exceptions in the match RFC v2: https://wiki.php.net/rfc/match_expression_v2 Kind regards Olle

Rowan Collins

5 years ago
On 26/03/2021 16:45, Olle Härstedt wrote:
> That made me think of a recent > extension to OCaml which makes it possible to catch exceptions in a > match-expressions (here's one blog post about it: > https://blog.janestreet.com/pattern-matching-and-exception-handling-unite/).
That's an interesting idea. I wonder if it would provide a way to implement the "data-flow" or "expression context" exception handling I was discussing on a different thread recently. Looking at my previous example: try {    $foo = doSomething() + $bar; } catch ( SomeException $e ) {    $foo = $bar; } Would become something like this: $foo = match($temp = doSomething()) {    exception SomeException => 0,    default => $temp } + $bar; Hm, that's not the most elegant; even if we could avoid the $temp assignment, the "default to myself" seems superfluous for this use case. I can definitely see the feature having its use cases, though, was just kicking this around as a thought experiment. Regards,
-- Rowan Tommins [IMSoP]

Olle Härstedt

5 years ago
2021-03-26 23:00 GMT+01:00, Rowan Tommins <rowan.collins@gmail.com>:
> On 26/03/2021 16:45, Olle Härstedt wrote: >> That made me think of a recent >> extension to OCaml which makes it possible to catch exceptions in a >> match-expressions (here's one blog post about it: >> https://blog.janestreet.com/pattern-matching-and-exception-handling-unite/). > > > That's an interesting idea. I wonder if it would provide a way to > implement the "data-flow" or "expression context" exception handling I > was discussing on a different thread recently. > > Looking at my previous example: > > try { > $foo = doSomething() + $bar; > } > catch ( SomeException $e ) { > $foo = $bar; > } > > Would become something like this: > > $foo = match($temp = doSomething()) { > exception SomeException => 0, > default => $temp > } + $bar;
You can't catch the value of $temp in the match-case? $foo = $bar + match (doSomething()) { $temp => $temp, exception SomeException => 0 }; Olle

Rowan Collins

5 years ago
On 26/03/2021 22:58, Olle Härstedt wrote:
> You can't catch the value of $temp in the match-case? > > $foo = $bar + match (doSomething()) { > $temp => $temp, > exception SomeException => 0 > };
$temp doesn't have an outside value, it was an inline assignment to capture the value of doSomething(); essentially, I wanted this, but without executing doSomething() twice: $foo = $bar + match (doSomething()) { default => doSomething(), exception SomeException => 0 }; Regards,
-- Rowan Tommins [IMSoP]

Olle Härstedt

5 years ago
2021-03-27 15:30 GMT+01:00, Rowan Tommins <rowan.collins@gmail.com>:
> On 26/03/2021 22:58, Olle Härstedt wrote: >> You can't catch the value of $temp in the match-case? >> >> $foo = $bar + match (doSomething()) { >> $temp => $temp, >> exception SomeException => 0 >> }; > > > $temp doesn't have an outside value, it was an inline assignment to > capture the value of doSomething(); essentially, I wanted this, but > without executing doSomething() twice: > > $foo = $bar + match (doSomething()) { > default => doSomething(), > exception SomeException => 0 > };
Yeah, I got it. Maybe I didn't read enough about the match-expression implementation in PHP, but in OCaml it's possible to capture whatever value the match evaluated to, like: let number_as_string = match number with | 1 -> "one" | v -> "number is " ^ string_of_int v ("^" is string concatenation.) The point of using a variable name like "v" (could be anything) instead of "default" is that like in your example, you don't have to execute the method twice. You can also add guard clauses, like "v when v > 10 -> ...". If you don't plan to use the value, you can use underscore, "_", which I guess would be the corresponding functionality to "default" in the PHP implementation. Olle