Compiling the following module (with ghc) fails with error message "parse error (possibly incorrect indentation)", pointing to the let statement. The error goes away when I indent the lines marked "--*". But I don't understand how what I've written could be ambiguous. If I am inside a parenthesized expression, then I can't possibly start another let-clause. The fact that the compiler won't acknowledge this fact ends up causing a lot of my code to be squished up against the right margin when it seems like it shouldn't have to be. module Main where main :: IO () main = do let a = (map (\x-> x+1) --* [0..9]) --* print a return () Is there a reason for this behavior or is it just a shortcoming of the compiler? Frederik
That's how it is defined in the Haskell definition. But there is a reason. The offside rule (or whatever yoy want to call it) is there to give visual cues. If you were allowed to override these easily just because it's parsable in principle then your code would no longer have these visual cues that make Haskell code fairly easy to read. -- Lennart Frederik Eaton wrote:
Compiling the following module (with ghc) fails with error message "parse error (possibly incorrect indentation)", pointing to the let statement. The error goes away when I indent the lines marked "--*".
But I don't understand how what I've written could be ambiguous. If I am inside a parenthesized expression, then I can't possibly start another let-clause. The fact that the compiler won't acknowledge this fact ends up causing a lot of my code to be squished up against the right margin when it seems like it shouldn't have to be.
module Main where
main :: IO () main = do let a = (map (\x-> x+1) --* [0..9]) --* print a return ()
Is there a reason for this behavior or is it just a shortcoming of the compiler?
Frederik _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
Huh, that seems patronizing. Well at least I can override it with {}. Thanks, Frederik On Thu, Jul 14, 2005 at 02:42:53AM +0200, Lennart Augustsson wrote:
That's how it is defined in the Haskell definition.
But there is a reason. The offside rule (or whatever yoy want to call it) is there to give visual cues. If you were allowed to override these easily just because it's parsable in principle then your code would no longer have these visual cues that make Haskell code fairly easy to read.
-- Lennart
Frederik Eaton wrote:
Compiling the following module (with ghc) fails with error message "parse error (possibly incorrect indentation)", pointing to the let statement. The error goes away when I indent the lines marked "--*".
But I don't understand how what I've written could be ambiguous. If I am inside a parenthesized expression, then I can't possibly start another let-clause. The fact that the compiler won't acknowledge this fact ends up causing a lot of my code to be squished up against the right margin when it seems like it shouldn't have to be.
module Main where
main :: IO () main = do let a = (map (\x-> x+1) --* [0..9]) --* print a return ()
Is there a reason for this behavior or is it just a shortcoming of the compiler?
Frederik _______________________________________________ Haskell mailing list Haskell@haskell.org http://www.haskell.org/mailman/listinfo/haskell
The offside rule is patronizing. :) It tries to force you to lay out your program in a certain way. If you like that way, good. If you don't like that way, you can use {;} as you say. -- Lennart Frederik Eaton wrote:
Huh, that seems patronizing. Well at least I can override it with {}.
Thanks,
Frederik
On Thu, Jul 14, 2005 at 02:42:53AM +0200, Lennart Augustsson wrote:
That's how it is defined in the Haskell definition.
But there is a reason. The offside rule (or whatever yoy want to call it) is there to give visual cues. If you were allowed to override these easily just because it's parsable in principle then your code would no longer have these visual cues that make Haskell code fairly easy to read.
-- Lennart
On Thu, Jul 14, 2005 at 03:15:32AM +0200, Lennart Augustsson wrote:
The offside rule is patronizing. :) It tries to force you to lay out your program in a certain way. If you like that way, good.
I disagree. The offside rule in general makes a more concise syntax available to the programmer, who would probably choose a similar indentation style anyway. The issue that I brought up is a case where the programmer is *prevented* from using a certain syntax, for the sole reason that, if what you say is correct, someone has determined that the prohibition is "good for him". I dislike such design rationales because they always end up hurting advanced users, who may have atypical needs, but who should ideally play an important role in promoting the language to others; it makes it seem like the plan is instead to hype the language to managers with the intent that they force it on their subordinates as a "regimen" rather than as a flexible tool. I don't really think that this example is such a big deal, since it is so easy to work around, I just wanted to say what I meant by "patronizing". You'll find a great deal of better bad examples in "The Design and Evolution of C++". :) Frederik
If you don't like that way, you can use {;} as you say.
-- Lennart
Frederik Eaton wrote:
Huh, that seems patronizing. Well at least I can override it with {}.
Thanks,
Frederik
On Thu, Jul 14, 2005 at 02:42:53AM +0200, Lennart Augustsson wrote:
That's how it is defined in the Haskell definition.
But there is a reason. The offside rule (or whatever yoy want to call it) is there to give visual cues. If you were allowed to override these easily just because it's parsable in principle then your code would no longer have these visual cues that make Haskell code fairly easy to read.
-- Lennart
On 7/14/05, Frederik Eaton <frederik@a5.repetae.net> wrote:
On Thu, Jul 14, 2005 at 03:15:32AM +0200, Lennart Augustsson wrote:
The offside rule is patronizing. :) It tries to force you to lay out your program in a certain way. If you like that way, good.
I disagree. The offside rule in general makes a more concise syntax available to the programmer, who would probably choose a similar indentation style anyway. The issue that I brought up is a case where the programmer is *prevented* from using a certain syntax, for the sole reason that, if what you say is correct, someone has determined that the prohibition is "good for him". I dislike such design rationales because they always end up hurting advanced users, who may have atypical needs, but who should ideally play an important role in promoting the language to others; it makes it seem like the plan is
I don't understand how a rule that requires one to prefer easier-to-read layout over more-difficult-to-read layout is bad, if each alternative is of equal verbosity (as is the case here). The offsides rule makes code written by you, an advanced user, easier to read by me, a novice user. As a novice, I assume code will be pretty simple and easy to read when it uses the layout rules. But, when I see a brace, then I automatically think "Oh my god--this guy is about to blow my mind." The easier it is for me to read your advanced code, the easier it is for me to write the simple, mundane, boring parts of the program for you. Thus, the offsides rule helps you, the advanced user, by allowing you to delegate boring responsibilities to novice users like me*. When I write this simple, boring code, you will probably have to debug it when I make my inevitable mistakes. Here, the offsides rule helps the advanced users again by ensuring that my simple-but-wrong code is easier for you guys to read and correct. IMO, the bad think about Haskell's layout rules is not that they are too restrictive, but rather that they are not always intuitive. This is also the problem with Haskell's comment syntax. For example, "--*" is not a comment, but rather an identifier. This is something that even advanced users could overlook. ;) - Brian (undergraduate student) * Haskell Communities and Activities Report http://www.haskell.org/communities/05-2005/html/report.html "Be lazy – get students to do your work for you."
Brian, On Thu, 2005-07-14 at 19:58 -0500, Brian Smith wrote:
On 7/14/05, Frederik Eaton <frederik@a5.repetae.net> wrote:
On Thu, Jul 14, 2005 at 03:15:32AM +0200, Lennart Augustsson wrote:
The offside rule is patronizing. :) It tries to force you to lay out your program in a certain way. If you like that way, good.
I disagree. The offside rule in general makes a more concise syntax available to the programmer, who would probably choose a similar indentation style anyway. The issue that I brought up is a case where the programmer is *prevented* from using a certain syntax, for the sole reason that, if what you say is correct, someone has determined that the prohibition is "good for him". I dislike such design rationales because they always end up hurting advanced users, who may have atypical needs, but who should ideally play an important role in promoting the language to others; it makes it seem like the plan is
I don't understand how a rule that requires one to prefer easier-to-read layout over more-difficult-to-read layout is bad, if each alternative is of equal verbosity (as is the case here).
I agree with Frederik since I've been bitten by that rule before. Defining a single function like so: let a very long definition of "a" = and the body has to be here is a very long application to "and" and using long arguments like definition is a pain in is harder to read and might force you to use shorter, less descriptive variable names. let an even longer definition of a function called "an" = is much easer to read I think in It is up to the programmer to write easy to write programs, not the language. I changed the 'a' to '"a"' afterwards which also forced me to indent the whole rhs as well. It's not a good feature IMHO. That said, I don't know if it's easy to change of if there are other ambiguities popping up. Axel.
On Fri, Jul 15, 2005 at 09:10:16AM +0100, Axel Simon wrote:
I agree with Frederik since I've been bitten by that rule before. Defining a single function like so:
let a very long definition of "a" = and the body has to be here is a very long application to "and" and using long arguments like definition is a pain in
is harder to read and might force you to use shorter, less descriptive variable names.
But you can format it this way: let a very long definition of "a" = and the body has to be here is a very long application to "and" but using long arguments like definition is not that bad in or this way: let a very long definition of "a" = and the body has to be here is a very long application to "and" but using long arguments like definition is not that bad in Best regards Tomasz
On 2005-07-15 at 10:49+0200 Tomasz Zielonka wrote:
But you can format it this way:
let a very long definition of "a" = and the body has to be here is a very long application to "and" but using long arguments like definition is not that bad in
or
let a very long definition of "a" = and the body has to be here is a very long application to "and" but using long arguments like definition is not that bad in
Though I happen to think that the offside rule isn't exactly right; you can probably find something I've said about this in the archive. -- Jón Fairbairn Jon.Fairbairn at cl.cam.ac.uk
Frederik Eaton wrote:
main = do let a = (map (\x-> x+1) --* [0..9]) --* print a
seeing this, I wonder if do-statements (and qualifiers in list comprehensions) could be easily extended by an alternative for simple declarations (without mutual recursion and type signatures) qual -> pat <- exp | "let" decls | exp | (funlhs | pat0) rhs stmt -> exp ; | pat <- exp ; let decls ; | (funlhs | pat0) rhs ; | ; These simple declarations could be easily recognised by an equal "=" or guard "|" sign and distinguished from the "pat <- exp" binding. It would avoid the above extra indentation! main = do a = ... print a Has this ever been considered before (and was rejected for some reason)? Cheers Christian
Hello Frederik, Thursday, July 14, 2005, 4:09:02 AM, you wrote: FE> But I don't understand how what I've written could be ambiguous. If I FE> am inside a parenthesized expression, then I can't possibly start FE> another let-clause. f = let a = (let b=1 in b) in a FE> The fact that the compiler won't acknowledge this FE> fact ends up causing a lot of my code to be squished up against the FE> right margin when it seems like it shouldn't have to be. give us real examples of such code. there is several tricks to do this. for example: read_file _ (startFile, correctTotals, receiveBuf, sendBuf) _ (DiskFile old_fi) = do whenJustM (tryOpen$ diskName old_fi) $ \file -> do whenJustM (rereadFileInfo old_fi file) $ \fi -> do correctTotals$ fiSize fi - fiSize old_fi ... parseCmdline cmdline = (`mapMaybeM` split ";" cmdline) $ \one_command -> do if one_command==[] then do putStr aHELP return Nothing else do let options = takeWhile (/="--") one_command no_configs = "-cfg-" `elem` options || "--config-" `elem` options ... -- Best regards, Bulat mailto:bulatz@HotPOP.com
participants (8)
-
Axel Simon -
Brian Smith -
Bulat Ziganshin -
Christian Maeder -
Frederik Eaton -
Jon Fairbairn -
Lennart Augustsson -
Tomasz Zielonka