Re: layout changes in Haskell 98

Having had a bit more time to muse over this issue and discuss it with Simon
P.J., we came to the conclusion that the issue is far from concluded.  The
Haskell 98 layout rule still has some problems (shock! :-)  

This message is indended to summarise what I think are the problems with the
current rule, and to hopefully start some discussion about fixing these for
Haskell 2.


Nested layout contexts at the same indentation level
----------------------------------------------------

I came across today (in the H/Direct sources) several occurrences of code
like

   do
     ....
     f $ \x -> do
     z <- e

which is illegal according to Haskell 98: nested contexts must increase in
indentation and 'do' expressions cannot be empty.  However, this is a
perfectly natural thing to want to write - the outer 'do' context is
subsumed by the inner one, and both contexts will be closed simultaneously
when the next line indented less is encountered.  The two possible fixes to
get the code to comply with Haskell 98 are
        
        - indent the 'z <- e' and all following statements to the right
        - or don't use layout

both of which are pretty ugly.

Haskell 98 introduced the restriction on nested layout contexts because if
you write

        f = f where
        g = g

then it isn't immediately clear whether the 'g = g' declaration belongs to
the where clause, or to the top level (and the where clause is empty).  In
fact, if we changed the layout rule as Malcolm suggests in his earlier
message, the parse would unambiguously associate the declaration for g to
the where clause.  In its  favour, this change would fix the H/Direct
example above.  The disadvantages include

        - leaving a dangling 'where' on a top-level declaration would 
          eat up all the following declarations.  The current behaviour
          handles this case nicely.

        - it becomes harder to write empty where clauses with layout.

I personally think the above example "looks" like a declaration with an
empty where clause.


The 'do ... if .. then .. else' problem
---------------------------------------

Another natural expression that is disallowed is 

        do
           ...
           if p then
                ...
           else
                ...

which is rejected by Haskell 98 because the 'else' introduces an extra
semicolon.  A fix for this was proposed for Haskell 98, but it was rejected
as a non-urgent change.  The fix essentially is to turn off layout
processing between 'if' and 'else', treating these keywords as explicit
brackets.  Some other constructs can be treated similarly, eg. 'case ... of'
and '\ ... ->'.


The 'case' problem
------------------

It seems reasonable to want to write

        case e1 of (p,q) ->
        case e2 of (r,s) ->
        ...

but this is rejected by Haskell 98 (and all previous versions).  Most of the
time we end up writing

        case e1 of { (p,q) ->
        case e2 of { (r,s) ->
        ...
        }}

but this is annoying because you have to adjust the number of braces at the
end of the expression when you add or remove a case.  One way around this is

        a =: b = b a

        e1  =: \ (p,q) ->
        e2  =: \ (r,s) ->
        ...

I don't know of any fix, but I just mention this here in case anyone has any
ideas.


Cheers,
        Simon


Reply via email to