
"Cristian Baboi"
What I should have been told about upfront:
- the syntax for an expression
Since there are only declarations and expressions, the syntax of an expression involves pretty much all of the language, so it would be difficult to tell it "upfront".
- the syntax for a block
Not sure what you mean by "block". do a <- [1..10] b <- [3,4] return (a,b) is an expression... you can write that same expression as do {a <- [1..10]; b <- [3,4]; return (a,b)} too.
- the adhoc syntax rules (how to distinguish among a tuple and a pharanthesized expression
a tuple has commas in it. I'll grant that (x) not being a 1-tuple is a little ad-hoc, but there really is very little ad-hockery in Haskell (and a 1-tuple behaves very much like a plain value after all).
and how to find the start and end of a block for example )
again, I don't know what you mean by block, but if you write the above expression with the braces ({}), it's obvious, I think, and the layout rule just inserts braces as necessary when the indentation changes. do a b c -- this is less indented, so will cause the end of the do.
- the fact that lambda expressions are not the same thing as "algebraic data" values
It might help to know why you think they might be the same; the syntax is different and the name is different...
- what guarantees are made by the LANGUAGE that an IO action (such as do putStrLn "Hello world" ) is not performed twice
As has been pointed out, «do putStrLn "Hello world"» is an expression that you can bind to a variable and use as many times as you like. Incidentally, it means the same as «putStrLn "Hello World"»; do connects a sequence of bindings and expressions, so you don't need it if there's nothing to be connected to.
- the lambda expressions can be written (input) but cannot be printed (output)
This is a fundamental property of the language. A lambda expression is programme and at runtime the system doesn't know one lambda expression from another (all it can do with one is apply it to something).
The biggest problem for me, so far, is the last one.
I can't see how your example illustrates that, I'm afraid.
Here is some strange example:
What I don't understand is why I'm forced to use guards like x==aa in cc, when aa is clearly bounded (is 7) and why in function h, the bounded u and v become free variables in the case expression.
I would have liked the language design to have permitted case to pattern match against variables too, but the question is, what would the syntax be? There was a fair bit of discussion about this when the language was designed (and since), but no-one could come up with a good way of doing it. One aspect of it is this: we want f 0 = 42 f x = 3*x to work, and we want all function definitions to be translated into the core language in the same way, so you get f = \a -> case a of 0 -> 42 x -> 3*x and given that, you can't have a variable on the LHS of -> do anything other than get bound to the value of the expression in the case (a in the example). It's not just a the top level, either: f Nothing = 0 f (Just n) = n+1 just means f = \v -> case v of Nothing -> 0 Just n -> n+1 so you can't have variables inside constructors do anything but get bound at that point. -- Jón Fairbairn Jon.Fairbairn@cl.cam.ac.uk http://www.chaos.org.uk/~jf/Stuff-I-dont-want.html (updated 2007-05-07)