
On 30 January 2006 12:32, John Hughes wrote:
I don't really agree that ~ adds complexity to the language design, given that we need SOME mechanism for lazy pattern matching. If you write a denotational semantics of pattern matching, then ~ fits in naturally. It has a simple, compositional semantics. Where I see complexity is that a pattern means different things in a let or in a case, so I have to remember, for each construct, whether it's a strict-matching or lazy-matching construct. Quick, when I write do (x,y)<-e... is that pair matched strictly, like case, or lazily, like let? If strictly, then why? There's no choice to be made here, so why not wait until x or y is used before matching? I expect you know the answer to this question off-hand, but it's an obstacle to learning the language--I'll bet there are many quite experienced Haskell programmers who are uncertain. If only pattern matching was *always* strict, unless a ~ appeared, then the language would be more regular and easier to learn.
For what it's worth, I agree with this point. I'd be quite happy for pattern matching to be strict by default in let and where. I can imagine it might still be confusing to some, though, because let x = fac 99 does not evaluate 'fac 99', but let (x,y) = quotRem a b does evaluate 'quotRem a b'. Still, I suppose it's no more confusing than the current situation. If pattern matching in where was strict, I imagine I'd use ~ a lot more. A common practice is to throw a bunch of bindings into a where clause, with no regard for whether they get evaluated or not - variable bindings and pattern bindings alike. If the pattern bindings are strict, I have to add ~ to each one to get the same effect. On the other hand, if pattern bindings were strict by default, I bet there would be a lot fewer accidental space leaks. Cheers, Simon