
I personally think it's bad to start using "let-patterns" as a synonym for general pattern bindings when explaining these concepts. It may be true that it's all transformed into the same thing at core level, but a let expression binds a definition at the expression level, rather than at the equation level; it becomes difficult when we have guards, for example: f pat1 | pat1 == x = x | pat2 == e2 = x where Just x = ... f pat2 = ... g pat1 | pat1 == let Just x = ... in x = let Just x = ... in x | pat2 == e2 = let Just x = ... in x g pat2 = ... In theory x is lazy in f, but computed twice in g. The only way to make the two the same is to introduce a case expression within a let binding -- but then you have to start thinking about things like uncurrying g if it has multiple parameters and its implications with partial applications. Most decent compiler implementations would make a closue for x anyway (if it's a big enough expression to compute), but I think it's certainly worth making the distinction, otherwise new people are going to start thinking they need to define everything using "let" clauses rather than "wheres" for laziness. Regards, Chris. On Wed, 27 Aug 2008, Jonathan Cast wrote:
On Wed, 2008-08-27 at 20:14 +0100, C.M.Brown wrote:
Hi,
I may be wrong here, but I don't belive it's just let-patterns that have this property. I.e. what's the difference between...
(Just x) = _|_
f = x
vs.
f = let (Just x) = _|_ in x
vs.
f = x where (Just x) = _|_
I believe Haskell uses Normal Order Reduction in all these cases. Why is it just let-patterns? Can you give an example?
Those are all syntax sugar for let patterns.
jcc