
On Thu, Jul 27, 2006 at 10:22:31AM +0100, Jon Fairbairn wrote:
On 2006-07-27 at 01:33EDT Paul Hudak wrote:
Thanks for asking about this -- it probably should be in the paper. Dan Doel's answer is closest to the truth:
I imagine the answer is that having the syntax for it looks nicer/is clearer. "if a b c" could be more cryptic than "if a then b else c" for some values of a, b and c.
except that there was also the simple desire to conform to convention here (I don't recall fewer parentheses being a reason for the choice).
In a sense, it explicitly wasn't: I suggested "if _ then _ else _ fi" -- something I was long used to from Algol68 -- but it was rejected on the ground that there wasn't a dangling else problem in Haskell.
But because if-then-else is an expression, there is another problem. Consider: (if True then 0 else 1) + 2 --> 2 if True then 0 else 1 + 2 --> 0 let cond a b c = if a then b else c cond True 0 1 + 2 --> 2 -- different from if-then-else withouth parentheses It's quite easy to fall in this trap. I think it happened to me at least twice. It goes like this: first I have an expression that doesn't involve if-then-else, eg. a + b Then I realize that "a" has to be changed in some situations, so I replace it with a conditional expression: if c then a else a' + b or if c then f a else g a + b But now " + b" gets under the "else" branch. If I used a "cond" function, or if if-then-else had a different priority, it would be easier to avoid such a mistake. There is no problem with the first version: cond c a a' + b For an experienced Haskell programmer it's obvious that function application has a higher precendence than addition. In the second version, it would be clear that parentheses have to be added: cond c (f a) (g a) + b Could the "cond" function encourage other kinds of bugs? I think it's less likely, because it's a normal function. Also, after a few years of Haskell programming, I am still not sure how to indent if-then-else. Perhaps in Haskell' we could have some lightweight case-of version with no pattern matching, guards only ("cond" could be a good name). I think it was even discussed before. The usual case-of looks like this: case x of Left err | isEOFError e -> ... Left err -> ... Right result -> ... "cond" would involve no pattern matching, or only as pattern guards. cond x == 0 -> ... x == 1 -> ... otherwise -> ... currently it can be written as case () of _ | x == 0 -> ... _ | x == 1 -> ... _ | otherwise -> ... which is a bit ugly. Best regards Tomasz