
On Mon, Jul 09, 2007 at 03:55:52PM +0200, Christian Maeder wrote:
Hi,
I would like haskell to accept the following (currently illegal) expressions as syntactically valid prefix applications:
f = id \ _ -> [] g = id let x = [] in x h = id case [] of [] -> [] i = id do [] j = id if True then [] else []
The rational is that expressions starting with a keyword should extend as far as possible (to the right and over several lines within their layout).
In this case the above right hand sides (rhs) are unique juxtapositions of two expressions. (This extension should of course apply to more than two expressions, i. e. "f a do []")
Furthermore the above rhs are all valid if written as infix expressions:
f = id $ \ _ -> [] g = id $ let x = [] in x h = id $ case [] of [] -> [] i = id $ do [] j = id $ if True then [] else []
False. f = runST $ do return () is a type error. f = runST (do return ()) is legal. So your proposal isn't as pointless as you think :)
(In fact, maybe for haskell-prime "$" could be changed to a keyword.)
Does this pose any problems that I haven't considered?
Not that I know of. Indeed, the status quo is a (minor) pain to parse, and in my Haskell compiler project I *wanted* to implement your proposal.
I think only more (and shorter) illegal haskell programs will become legal.
Cheers Christian
Maybe someone else can work out the details for Haskell's grammar
Not hard at all. In http://haskell.org/onlinereport/syntax-iso.html, change: exp^10 -> \ apat[1] ... apat[n] -> exp (lambda abstraction, n>=1) | let decls in exp (let expression) | if exp then exp else exp (conditional) | case exp of { alts } (case expression) | do { stmts } (do expression) | fexp fexp -> [fexp] aexp (function application) aexp -> qvar (variable) | gcon (general constructor) | literal | ( exp ) (parenthesized expression) | ( exp[1] , ... , exp[k] ) (tuple, k>=2) | [ exp[1] , ... , exp[k] ] (list, k>=1) | [ exp[1] [, exp[2]] .. [exp[3]] ] (arithmetic sequence) | [ exp | qual[1] , ... , qual[n] ] (list comprehension, n>=1) | ( exp^i+1 qop^(a,i) ) (left section) | ( lexp^i qop^(l,i) ) (left section) | ( qop^(a,i)[<->] exp^i+1 ) (right section) | ( qop^(r,i)[<->] rexp^i ) (right section) | qcon { fbind[1] , ... , fbind[n] } (labeled construction, n>=0) | aexp[<qcon>] { fbind[1] , ... , fbind[n] } (labeled update, n >= 1) to: exp^10 -> [exp^10] aexp (function application) aexp -> \ apat[1] ... apat[n] -> exp (lambda abstraction, n>=1) | let decls in exp (let expression) | if exp then exp else exp (conditional) | case exp of { alts } (case expression) | do { stmts } (do expression) | qvar (variable) | gcon (general constructor) | literal | ( exp ) (parenthesized expression) | ( exp[1] , ... , exp[k] ) (tuple, k>=2) | [ exp[1] , ... , exp[k] ] (list, k>=1) | [ exp[1] [, exp[2]] .. [exp[3]] ] (arithmetic sequence) | [ exp | qual[1] , ... , qual[n] ] (list comprehension, n>=1) | ( exp^i+1 qop^(a,i) ) (left section) | ( lexp^i qop^(l,i) ) (left section) | ( qop^(a,i)[<->] exp^i+1 ) (right section) | ( qop^(r,i)[<->] rexp^i ) (right section) | qcon { fbind[1] , ... , fbind[n] } (labeled construction, n>=0) | aexp[<qcon>] { fbind[1] , ... , fbind[n] } (labeled update, n >= 1) All new ambiguities are resolved adequately by the let/lambda meta rule.
(I've posted this message to glasgow-haskell-users before, but it applies to every Haskell implementation and should be discussed here.)
haskell-prime@haskell.org would be even better. Stefan