Call to arms: lambda-case is stuck and needs your help

Tyson Whitehead twhitehead at gmail.com
Fri Jul 6 17:49:23 CEST 2012


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



More information about the Glasgow-haskell-users mailing list