Hi Brian

On 05/03/2021 23:11, Brian Goetz wrote:
I have long had a nagging feeling that this will eventually be desirable.  Let's say we have P & g & Q & h; under what conditions can we commute g and Q without regret?  I can think of four potential sources of regret:

 - g declares bindings that are inputs to Q
 - the cost model of Q is such that we'd like to run g first, and short-circuit
 - Q might throw an exception when g does not hold
 - Q might have side-effects that we don't want to run if g does not hold

You are right to point out that swapping guards with patterns is not free - that said, if a guard doesn't introduce any additional bindings, then the first point also is not a concern. Why am I focusing on guards that do not introduce new bindings? Simply because, IMHO, a guard after a pattern is meant to add extra "imperative" conditions on one or more of the bindings that have already been extracted. Sure, you can (in principle) also use it to declare additional binding which you can use elsewhere - but I'm less sure that this is a use of a guard I would agree with.

It seems to me that if you want to use the guard to add extra bindings, you can get there by nesting a pattern - e.g.

Point(var x, var y) when pred(x) && pred(y)

vs

Point(pred(var x), pred(var y))

Maurizio




Reply via email to