You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi @santinic! Once again, thank you so much for this great package that puts all of us very much closer to proper functional programming on Python.
I've been thinking a bit about what to improve in the pampy. Once again, I'm super happy doing the work of implementation myself, but I wanted to run that in an issue first. (see #35.)
I've looked mostly at the differences between pampy and pattern matching as it exists in OCaml, the purely functional programming language I'm the most familiar with. A good reference of all pattern matching functionalities of OCaml is this one, if you're curious.
1. Conditionals
Consider this OCaml function, which checks that two rationals are equal
OCaml, here, uses when as a guard that executes a conditional expression before the expression is executed. How do we do that in Python? You could do nested matching, but that can get complicated quite quickly.
I'm thinking about passing some form of data structure. I put a dict here, but it could easily be a class instance. In my example, there are two reserved variables, pattern and when, that can be put as keys in this dict to indicate the pattern and the conditional expression to be executed.
The flow would be the pattern is matched and we return (True, vars), the vars are then passed to the function defined in when, and we execute the action if when returns True. Otherwise we move on to the next pattern.
2. Negative Patterns
Consider this OCaml code, which returns the minimum of a pair of rational numbers:
letmin_ratpr=match pr with
((_,0),p2) -> p2
| (p1,(_,0)) -> p1
| ((n1,d1), (n2,d2)) ->
if (n1*d2) < (n2*d1) then (n1,d1) else (n2,d2);;
(* Console output: * val min_rat : (int * int) * (int * int) -> int * int = <fun>*)
How do we translate that to pampy? Something like this:
min_rat=lambdapair: match(pair,
((_,0),_), lambdaidc, p2: p2,
(_,(_,0)), lambdap1, idc: p1,
((_,_),(_,_)), lambdan1, d1, n2, d2: (
(n1, d1) if (n1*d2) < (n2*d1) else (n2, d2)),
) # here, idc (i don't care) refers to the parts of the variable that we will not use.
Since _ (as well as ANY, int, or Any) returns the value of the object, we can't discriminate, in the pattern, between the variables we will use for the action and the variables we will not. You have to pass to the action useless parameters, which are indicated in the code above with the idc name.
If you compare to the OCaml code, it's easy to see why. There:
_ actually refers to the values that will be dropped in the right-hand action,
and the named values are the ones that will be passed to the right-hand action.
We may want to modify panpy so as to recognize the difference. Here, I used the variable ø, which is technically allowed as a variable name in Python 3, but easy to type only on macOS. So it's obviously not a realistic choice, but it's just to show you how it could work:
min_rat=lambdapr: match(pr,
((ø,0),_), lambdap2: p2,
(_,(ø,0)), lambdap1: p1,
((_,_),(_,_)), lambdan1,d1,n2,d2: (
(n1, d1) if (n1*d2) < (n2*d1) else (n2, d2)),
) # Instead of ø, maybe we could use BYE, or _no, or _NO, whatever helps readibility.
Much more readable, I think. And, in the case of complex pattern matching, it might reduce the verbose-ness of the lambda functions significantly.
3. Pattern Warning
Look at this OCaml code:
letis_zeron=match n with0 ->true ;;
(* REPL Warning (Will be issued at compile time as well): * * Characters 17-40: * Warning: this pattern-matching is not exhaustive. * Here is an example of a value that is not matched: * 1 * val is_zero : int -> bool = <fun> *)
I'm wondering if there is a way to implement this in pampy.
There are just my ideas, and I'm probably going to try to go ahead and fork the repo. Please tell me if there are any red flags! :)
The text was updated successfully, but these errors were encountered:
Hi @santinic! Once again, thank you so much for this great package that puts all of us very much closer to proper functional programming on Python.
I've been thinking a bit about what to improve in the pampy. Once again, I'm super happy doing the work of implementation myself, but I wanted to run that in an issue first. (see #35.)
I've looked mostly at the differences between pampy and pattern matching as it exists in OCaml, the purely functional programming language I'm the most familiar with. A good reference of all pattern matching functionalities of OCaml is this one, if you're curious.
1. Conditionals
Consider this OCaml function, which checks that two rationals are equal
OCaml, here, uses
when
as a guard that executes a conditional expression before the expression is executed. How do we do that in Python? You could do nested matching, but that can get complicated quite quickly.I'm thinking about passing some form of data structure. I put a dict here, but it could easily be a class instance. In my example, there are two reserved variables,
pattern
andwhen
, that can be put as keys in this dict to indicate the pattern and the conditional expression to be executed.The flow would be the pattern is matched and we return
(True, vars)
, the vars are then passed to the function defined inwhen
, and we execute theaction
ifwhen
returns True. Otherwise we move on to the next pattern.2. Negative Patterns
Consider this OCaml code, which returns the minimum of a pair of rational numbers:
How do we translate that to pampy? Something like this:
Since
_
(as well asANY
,int
, orAny
) returns the value of the object, we can't discriminate, in the pattern, between the variables we will use for the action and the variables we will not. You have to pass to the action useless parameters, which are indicated in the code above with theidc
name.If you compare to the OCaml code, it's easy to see why. There:
_
actually refers to the values that will be dropped in the right-hand action,We may want to modify panpy so as to recognize the difference. Here, I used the variable
ø
, which is technically allowed as a variable name in Python 3, but easy to type only on macOS. So it's obviously not a realistic choice, but it's just to show you how it could work:Much more readable, I think. And, in the case of complex pattern matching, it might reduce the verbose-ness of the lambda functions significantly.
3. Pattern Warning
Look at this OCaml code:
I'm wondering if there is a way to implement this in pampy.
There are just my ideas, and I'm probably going to try to go ahead and fork the repo. Please tell me if there are any red flags! :)
The text was updated successfully, but these errors were encountered: