I prefer a slightly different algebra of patterns, which works nicely[0] as long as sets of clauses are <i>simplicial</i>[1], which is to say that if any two clauses have patterns that properly intersect, the intersection also occurs as a pattern in the set of clauses: clauses match if their pattern, and no more precise[2] patterns, do.<p><pre><code> isWeekend : Day → String
isWeekend(x) := show(x) ++ " is not on the weekend"
isWeekend(x & (Sa||Su)) := show(x) ++ " is on the weekend"
</code></pre>
In exchange for that complication on the structure of well-formed sets of clauses, we get the following simplifications: (a) <i>default</i> need not be special, but is expressed by <i>_</i>[3], and (b) the programmer need only use positive patterns[4].<p>[0] as with Dijkstra's def'ns of <i>if..fi</i> and <i>do..od</i> it's possible to extend the order-independence/commutativity to non-simplicial sets of clauses without losing runtime determinativeness but at the cost of introducing arbitrariness.<p>[1] this is not quite accurate to the geometric use; does anyone have a better adjective?<p>[2] pedantically speaking, a pattern P is more specific than a pattern Q iff P is congruent to P & Q.<p>[3] as all clauses, not just <i>default</i>, exclude more specific matches<p>[4] negative patterns might still be useful for codegen, but they needn't be part of the developer experience. I still need to look at <a href="https://lirias.kuleuven.be/retrieve/262314/" rel="nofollow">https://lirias.kuleuven.be/retrieve/262314/</a> to see how it relates to all this...