layout rule infelicity
Two very similar programmmes: > possible_int = do skip_blanks > fmap Just int >+++ (literal "-" `as` Nothing) > possible_int = do skip_blanks > fmap Just int > +++ (literal "-" `as` Nothing) I think this is extremely bad language design! In general I like having layout rules, but I've often thought that they ought to take note of expressions, not just things in {...} and that there ought to be "dead zones" where no programme text is allowed, so that everything starting with the second example and ending with > possible_int = do skip_blanks > fmap Just int > +++ (literal "-" `as` Nothing) should be rejected. This example clinches it for me. Can anyone more au fait with the layout rule figure out how to do it? (My past irritation was that ... if p then q else r is acceptable in some circumstances, but one has to use ... if p then q else r in others. Having programmes rejected I don't mind, but having them accepted when they are too close to right but still wrong, I really do mind) -- Jón Fairbairn [EMAIL PROTECTED] ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
At 2002-05-30 02:26, Jon Fairbairn wrote: >I think this is extremely bad language design! In general I >like having layout rules, but ... What's the deal with the whole "layout" thing anyway? I've never come across it before in another language. Is it an academic thing? It drove me nuts when I first started Haskell, until I discovered you could use semicolons/braces instead (which I always do). If I were teaching Haskell to "working programmer" types like myself, I would encourage them to always use full semicolons and braces and forget layout entirely (except a lot of available Haskell source seems to use it). Certainly I find {;} more readable, and I suspect anyone else with a C/C++/Java background (or even a Scheme/Lisp background) does too. -- Ashley Yakeley, Seattle WA ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
At 2002-05-30 02:46, I wrote: >What's the deal with the whole "layout" thing anyway? I've never come >across it before in another language. Oh, wait, there's Python and Ruby. For some reason it doesn't bother me so much with them. -- Ashley Yakeley, Seattle WA ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
Ashley Yakeley wrote: > At 2002-05-30 02:26, Jon Fairbairn wrote: > > >I think this is extremely bad language design! In general I > >like having layout rules, but > ... > > What's the deal with the whole "layout" thing anyway? I've never come > across it before in another language. Is it an academic thing? How about FORTRAN (to a very small extent) or Python? I used to dislike layout, but I must say that it didn't take long to become a supporter once you start using it. If you look at C (& offspring), it's not the {;} that makes the code readable, it's the indentation that does. So why not acknowledge that? -- Lennart ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
On Thu, 30 May 2002, Ashley Yakeley wrote: > it). Certainly I find {;} more readable, and I suspect anyone else with a > C/C++/Java background (or even a Scheme/Lisp background) does too. Just a data point: I learned Basic, Pascal, Standard ML, C, Haskell, C++, Perl, Python in that order and actively use Haskell, C++, Perl & Python at the moment, and I find the `visual noise' of braces and semi-colons in C++ and Perl to be very irritating when, as Lennart points out, to be readable by me my code has to embody these structures by layout. (It's primarily the noise of all those `fun', `val' and `end's rather than deeper language issues that put me off looking at ML again.) Indeed, I (half) there ought to be a warning on the main page of Haskell.org saying `WARNING: Using Haskell can lead to semi-colon blindness' since I relatively frequently spend ten minutes trying to figure out why C++ code isn't compiling only to realise that, whilst indented structurally the semi-colons are missing :-S I suspect using layout rule is forever destined to be controversial... ___cheers,_dave_ www.cs.bris.ac.uk/~tweed/ | `It's no good going home to practise email:[EMAIL PROTECTED] | a Special Outdoor Song which Has To Be work tel:(0117) 954-5250 | Sung In The Snow' -- Winnie the Pooh ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
At 2002-05-30 02:54, Lennart Augustsson wrote: >If you look at C (& offspring), it's not the {;} that makes the code >readable, it's the indentation that does. So why not acknowledge that? In C, the indentation is an important visual clue, but there are many different indentation styles. It's the braces that actually tell you the beginning and end of a block. I might also use indentation for non-blocks, for instance: void foo (int n) { if (n > 0) bar ( "Sproing!",// title getBounds(n), // bounds true, // bordered true, // bright false, // not transparent true, // use v2 appearance 5, // shadow size null // next ); } Equally, I always indent my braced blocks in Haskell as well as C (& o). If you're used to braces, complicated Haskell expressions with layout look confusing, since it's not immediately clear which indentation style the layout rules are trying to enforce. It's also not clear to the unlearned how best to split an expression onto two lines, or how it interacts with parentheses, etc. And then there are those nasty little infelicities... -- Ashley Yakeley, Seattle WA ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
> If you look at C (& offspring), it's not the {;} that makes the code > readable, it's the indentation that does. So why not acknowledge that? Redundancy maybe? What's wrong in having both layout and punctuation? For instance, then you can have an emacs mode that handles the layout given the punctuation. I used to believe in layout, but got converted the other way round. We used Scala, a new functional/object oriented language we design, in a course with 100+ students. Scala used to have layout rules somewhat like Haskell's. In our experience it was the single thing that confused students most. Problems were: (1) Students did not properly indent their code. (2) Students used editors that disagreed in the handling of tabs. (3) Students wrote multi-line statements that started at the same column. I came away with with the learning experience that a little redundancy in the syntax is a good thing. Cheers -- Martin ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
I like layout but I think the existing rules are too complicated. Unfortunately it's difficult to do anything with them without breaking vast swathes of existing code, so we'll just have to put up with them. The reason I think layout is better than using {'s and ,'s is that humans use the layout to group the structure anyway, which means you can have confusing situations where a structure looks alright to a human but not to a computer. ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
Martin Odersky <[EMAIL PROTECTED]> writes: > Redundancy maybe? What's wrong in having both layout and punctuation? Short answer: What's wrong with it is that humans use layout to infer the semantic meaning, compilers use punctuation. Thus it's not really redundancy. -kzm -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
> What's the deal with the whole "layout" thing anyway? I've never come > across it before in another language. Python has it as well (they stole it from Haskell?) > If I were teaching Haskell to "working programmer" types like myself, I > would encourage them to always use full semicolons and braces ... while we're at it - what's the deal with type inference? sometimes I think it is *really bad* language design if the program may contain untyped declarations of identifiers. ghc -Wall warns nicely about undeclared top-level types but what about locals? I've never came across a language that would allow them declared untyped. of course I know (some of) the `academic' background (type inference, type checking) but what about it from a software engineering point of view? \end{rant} .. I think neither the layout rule nor type inferencing are likely to disappear from Haskell .. -- -- Johannes Waldmann http://www.informatik.uni-leipzig.de/~joe/ -- -- [EMAIL PROTECTED] -- phone/fax (+49) 341 9732 204/252 -- ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
> ... layout rules somewhat > like Haskell's. In our experience it was the single thing that > confused students most. same here, for exactly these reasons. students get really confused. on the other hand, students regularily get confused by other things as well, like homework assignments on formal languages, so that alone is not enough reason to drop the subject altogether :-) -- -- Johannes Waldmann http://www.informatik.uni-leipzig.de/~joe/ -- -- [EMAIL PROTECTED] -- phone/fax (+49) 341 9732 204/252 -- ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
At 2002-05-30 04:10, Johannes Waldmann wrote: >ghc -Wall warns nicely about undeclared top-level types but what about >locals? You'd have to declare them in terms of the top-level types, i.e. other type annotations. I think GHC allows some form of this, but IIRC it's a bit tricky. If it weren't for this difficulty I'd probably type-annotate locals. -- Ashley Yakeley, Seattle WA ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
At 2002-05-30 04:19, Johannes Waldmann wrote: >same here, for exactly these reasons. students get really confused. > >on the other hand, students regularily get confused by other things as well, >like homework assignments on formal languages, >so that alone is not enough reason to drop the subject altogether :-) In the latter case, they are learning something useful. In the former case, the confusion emerges out of a useless property of the language. Let the students use {;} if it eliminates confusion, it's still perfectly good Haskell. I am certainly not proposing Haskell be modified to eliminate the layout option. I'm just curious as to why Haskell programmers choose to use it. -- Ashley Yakeley, Seattle WA ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
At 2002-05-30 03:59, Ketil Z. Malde wrote: >Short answer: What's wrong with it is that humans use layout to infer >the semantic meaning, No... layout by itself can't be trusted. It's only a clue. One needs to learn the precise Haskell-specific layout rules, and they're not obvious. -- Ashley Yakeley, Seattle WA ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
Ashley Yakeley wrote: > I am certainly not proposing Haskell be modified to eliminate the layout > option. I'm just curious as to why Haskell programmers choose to use it. Because I find programs using layout to be more readable. In Haskell (not in C) programs using {;} I've found that the indentation is often sloppy, and since layout is not enforced by the compiler I find it harder to read. I think it is largely a matter of taste. Martin's point is well taken, though. I think the redundancy can be useful for beginners. I suspect it's more the ; than the {} that makes it somewhat easier for beginners. -- Lennart ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
Hi everyone, I thought I would bring a students perspective into this discussion. Moving from a C background to Haskell, the layout wasn't very intuitive at first. This was mainly due to my hand's on approach (looking at examples and trying to code similar programs). Given that if i read up on the layout first I would have had less trouble. I did notice that the error messages generated by incorrect layout don't offer much clue to the origin of the layout error, well from a beginner's interpretation of the error messages anyway. Having said that, now that I have gotten used to the Haskell layout I simply adore it. I often remember tiredly coding in C and relying on the compiler to locate where i had left out a ';' at the end of a statement or two. With Haskell there is no such need! Tuong, a happy haskell student.. ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
> I like layout but I think the existing rules are too > complicated. Unfortunat ely it's difficult to do anything > with them without breaking vast swathes of existing code, > so we'll just have to put up with them. Well, there's two things to consider: Haskell 98, which probably shouldn't change, and extended Haskell, which probably should. Especially if we can make the rules both simpler and better. > The reason I think layout is better than using {'s and ,'s is that humans > use the layout to group the structure anyway, which means you can have > confusing situations where a structure looks alright to a human but not > to a computer. Which is exactly the problem with the programme I posted. Having thought about it a bit, it strikes me that the particular problem is the insertion of a closing brace. From the human reader's point of view, there's no visual equivalent of the closing brace in the example: > possible_int = do skip_blanks > fmap Just int > +++ (literal "-" `as` Nothing) What happens is that a semicolon is inserted because the indentation is the same as the previous line -- that's fair enough, subject to some quibbles about treating all expressions the same -- but then the +++ is a syntax error unless a closing brace is inserted. Visually, the equivalent of a closing brace is when indentation is less (to my eye it ought to be right down to where the 'do' is and inbetween be an error). What's wrong with the notion that closing braces should only be inserted when the indentation is less (or the file ends)? This would reject some programmes, but only ones where the appearance is misleading. So > possible_int = do skip_blanks > fmap Just int >+++ (literal "-" `as` Nothing) > whatever ... parses as > possible_int = do {skip_blanks > ;fmap Just int > +++ (literal "-" `as` Nothing) > } > whatever ... and > possible_int = do skip_blanks > fmap Just int > +++ (literal "-" `as` Nothing) > whatever ... parses as > possible_int = do {skip_blanks > ;fmap Just int > ;+++ (literal "-" `as` Nothing) > } > whatever ... and then gives a syntax error but > possible_int = do skip_blanks > fmap Just int > +++ (literal "-" `as` Nothing) > whatever ... parses as > possible_int = do {skip_blanks > ;fmap Just int > } > +++ (literal "-" `as` Nothing) > whatever ... Which is just about acceptable to me, because the +++ does stick out, though I'd prefer that one to be rejected too. I wasn't fit enough to follow the earlier discussions of the layout rule, so I'm not sure how this interacts with previous awkward cases. I'd be happiest if we could come up with a rule that didn't involve sticking in braces and semicolons because it won't parse otherwise. Can someone remind me why the "A close brace is also inserted whenever the syntactic category containing the layout list ends" part of the rule is there? Jón -- Jón Fairbairn [EMAIL PROTECTED] 31 Chalmers Road [EMAIL PROTECTED] Cambridge CB1 3SZ+44 1223 570179 (after 14:00 only, please!) ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
Jon Fairbairn wrote: > > I wasn't fit enough to follow the earlier discussions of the > layout rule, so I'm not sure how this interacts with > previous awkward cases. I'd be happiest if we could come up > with a rule that didn't involve sticking in braces and > semicolons because it won't parse otherwise. Can someone > remind me why the "A close brace is also inserted whenever > the syntactic category containing the layout list ends" part > of the rule is there? It's so you can write let x = 2+2 in x*x (and similar things) I think this inserting a '}' when there would otherwise have been a syntax error is a terrible mistake. It makes it almost impossible to implement correctly, and to understand. But it's with us now in H98. -- Lennart ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
> Can someone remind me why the "A close brace is also inserted whenever > the syntactic category containing the layout list ends" part > of the rule is there? x = (3, case True of True -> 4) The ')' ends the syntactic category 'tuple' Arjan ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
Jon Fairbairn wrote [snip] > Well, there's two things to consider: Haskell 98, which > probably shouldn't change, and extended Haskell, which > probably should. Especially if we can make the rules both > simpler and better. [snip] How can I resist? I proposed the following revised layout rule some time ago in a message to the Twa Simons. Note that unlike the standard Haskell layout rules it does not need to read the parser's mind. Of course the problem is that while it should work fine for the way I lay out Haskell, it might not work for other people. We represent the lines in a file in a tree like structure: data Grouped line = Grouped line [Grouped line] The meaning of Grouped A lines is a line A, followed by a list of groups, each beginning at the same deeper ind entation. So for example A B C D would go to something like Grouped A [Grouped B [Grouped C []],Grouped D []] In the code I've written A B C produces an error message, but on second thoughts I think the best behaviour wou ld be to treat it like A ++ B C though it's too late to code that now . . . The layout processor would group the lines according to this algorithm. It woul d then output the result of the grouping. When it came to Grouped first rest it would determine if the last token of first is "do", "of", "where" or "let", and rest does _not_ begin with a "{" token. If both these conditions were satis fied, it would output "{" before, ";" inbetween elements, and "}" after when outputting t he "rest" list. This seems to me to solve most of the fundamental problems, and be somewhat more intuitive than the existing algorithm. It would behave differently in that do if test then do act1 act2 else do act3 act4 is legal. But it would also be necessary to alter the context-free-syntax so th at (1) the contents of the module were not separated by ";"'s, but by each being a single item in the [Grouped line] list. (The old where {decl1 ; decl2 ; . . . ; decln} syntax would probably have to remain, for compatibility reasons). (2) single-line forms without braces, like "let a = 5 in a+a" work. This is only a first approximation, in that do if test then do act1 act2 else do act3 act4 isn't legal. Perhaps one way of fixing this is to modify the layout algorithm s o that tokens such as "then", "else", "in" and ")" before which a semicolon can't make any sense anyway, get tagged onto the previous group if that began at the same column as t hey did. I don't claim this as the perfect solution. But since layout is something which is rather confusing and at the moment seems to have distinctly rough edges, it might be wo rthwhile experimenting with something like this, to see how much code it would break ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
I wrote: > > Can someone remind me why the "A close brace is also inserted whenever > > the syntactic category containing the layout list ends" part > > of the rule is there? Lennart wrote: > It's so you can write > let x = 2+2 in x*x > (and similar things) and Arjan van IJzendoorn wrote: > x = (3, case True of > True -> 4) > > The ')' ends the syntactic category 'tuple' So we get all this misery just so that people can cram things onto fewer lines? > let x = 2+2 in x*x could be > let {x = 2+2} in x*x or > let x = 2+2 > in x*x and > x = (3, case True of > True -> 4 > ) would be fine. I'd like to see a "-fuse-simpler-layout-rule"¹ option on the compilers. . . Jón 1. Why "-f" anyway? It took me ages to work out what "-fallow-overlapping-instances" meant -- I wondered how "fallow" could apply to overlapping instances. -- Jón Fairbairn [EMAIL PROTECTED] 31 Chalmers Road [EMAIL PROTECTED] Cambridge CB1 3SZ+44 1223 570179 (after 14:00 only, please!) ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
G'day all. On Thu, May 30, 2002 at 01:10:03PM +0200, Johannes Waldmann wrote: > Python has it as well (they stole it from Haskell?) Python's layout rule looks more like Occam's than Haskell's, to my eyes. Aside: Was Occam the first language of the post-punched-card era to use layout as syntax? > while we're at it - what's the deal with type inference? > > sometimes I think it is *really bad* language design > if the program may contain untyped declarations of identifiers. Presumably you're not suggesting requiring type declarations in every pattern match too? I think it's something to do with where you draw the line. You could theoretically require type declarations: - Nowhere, unless the type inference mechanism can't cope with it. - Module interfaces. - Top-level declarations. - "where" clauses too. - "let" - Everywhere that a variable could be defined, including case-expressions, list comprehension generators and lambdas. - Every subexpression. I personally think it's wrong not to require explicit type declarations for everything exported from a module for engineering reasons. Sane separate compilation is important, IMO. Cheers, Andrew Bromage ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
Hi All, Andrew J Bromage wrote: > > G'day all. > > On Thu, May 30, 2002 at 01:10:03PM +0200, Johannes Waldmann wrote: > > > Python has it as well (they stole it from Haskell?) > > Python's layout rule looks more like Occam's than Haskell's, to my eyes. > > Aside: Was Occam the first language of the post-punched-card era to use > layout as syntax? I fuzzily recall that SICStus Prolog silently tolerated omissions of commas and dots, allowing for: p(X) :- g(X,Y) h(Y) p(X) g(Y,Z) :- ... But Haskell already existed at this point. Alexander ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell
Re: layout rule infelicity
Jon Fairbairn <[EMAIL PROTECTED]> writes: > Why "-f" anyway? It took me ages to work out what > "-fallow-overlapping-instances" meant -- I wondered how > "fallow" could apply to overlapping instances. I suppose it's a GCCism, where options starting with -f specifiy *f*lags. (Which doesn't seem to apply to GHC, unless there's a -fno-allow... (of -fdont-allow...?)) -kzm -- If I haven't seen further, it is by standing in the footprints of giants ___ Haskell mailing list [EMAIL PROTECTED] http://www.haskell.org/mailman/listinfo/haskell