
On July 6, 2012 05:25:15 Simon Marlow wrote:
Why not just let enclosed scopes be less indented than their outer ones?
Let me be entirely clear about what I was thinking about. The third case for the layout mapping in Section 9.3 of the report is L ({n}:ts) (m:ms) = { : (L ts (n:m:ms)) if n > m This function takes a possibly layout sensitive token stream augmented with '{n}' for the indentation level of the first token following a grouping token that doesn't have a '{' and '<n>' for the indentation level of first tokens after newlines that are not already augmented with '{n}'. The 'L' functions maps this to a non-augmented non-layout sensitive stream. The first argument is the augmented layout stream and the current stack of indentations for any groupings in effect. The rule above inserts a '{' if there isn't one after a grouping token and the next token is at a deeper level then the current grouping level. I was proposing to make it always fire on indentation (i.e., allow enclosing scopes to be less indented). L ({n}:ts) (m:ms) = { : (L ts (n:m:ms)) if n > 0 The rest of the '{' insertion rules are for starting the first '{' on any indentation after a grouping token not followed by a '{' and for inserting a '{}' in all other cases. L ({n}:ts) [] = { : (L ts [n]) if n > 0 L ({n}:ts) ms = { : } : (L (<n>:ts) ms) http://www.haskell.org/onlinereport/syntax-iso.html
I think this is undesirable. You get strange effects like
f x y = x + y where -- I just left this where here by accident
g x = ...
parses as
f x y = x + y where { -- I just left this empty where here by accident
g x = ... }
and
instance Exception Foo where instance Exception Bar
parses as
instance Exception Foo where { instance Exception Bar }
That is, layout contexts that should really be empty end up surprisingly swallowing the rest of the file.
These would be okay under the above so long as the following lines are not indented. The issue only arises with nested ones f x = ... where g y = ... where h y = ... Now the h gets sucked into the where clause as it is empty and nested. Using the metric of what would most people expect, I agree the above is not ideal (although I would hope empty nested where clauses not really in common use). By this same metric though, I also think things like where f x = do stmt1 stmt2 mask $ let x = do stmt1 stmt2 being parsed to where { f x = do {} } stmt1 stmt2 mask $ let { x = do {} stmt1 stmt2 } is also not ideal. The real underlying issue in both these cases and changing '\' to a group token seems to be what happens on single lines with multiple groupings when the last grouping actually starts on a newline indented further than the proceeding line. Currently it depends on the depth of this new level of indentation relative to all the groupings started on that line. I think most people would expect it to just apply to the last grouping though. That is where { f x = do { stmt1 stmt2 } } mask $ let { x = do { stmt1 stmt2 } } The rule in this case would be that if the grouping began on a newline that is idented farther then the previous line, the grouping is assocated with the grouping token and when it closes, it closes all those deeper than itself. Cheers! -Tyson