Lennart writes:

> Is the following legal Haskell?  (I'm sure I've asked this
> before, but i don't think there was a consensus.)
> 

> f x = g x
>     where g y = case y of
>         [] -> 0
> 

> The problem is that after where a '{' is inserted and another after of.
> The report now says that for each subsequent line if a line is
> indented less than an insert '{' then a '}' is inserted.  Since '[]'
> is indented less than 'g' a '}' is inserted, or?
> 

> Or is it only the most recent inserted '{' that counts?
> (If that is the case, I've got more questions, but they can wait.)


Since I've already got a reply to a similar question :-), as a reply
to Ian Holyer (I hope he doesn't mind that I copy part of his message
to the list), I thought I might give my small opinion on the matter.

(--------> SUMMARY, NO IT SHOULD NOT BE LEGAL.)

======================================================================

> There is one point about layout that emerges from what you said that I am not
> clear on.  The current compilers all insist that the indentation of a new
> inner block be greater than the outer block it occurs in.  I guess I took this
> as being implied by the standard. (I also think it is sensible, as it catches
> some common unintentional programming errors.)  However, the report doesn't
> say this explicitly, and I guess your point is that without it, the
> top-level-indenting rule is unnecessary. (Maybe it was the top-level-indenting
> rule that made me assume it.)  Do you have an opinion?

   The question as to whether the indentation of a new inner block must
be greater than an outer block it occurs in, has two valid answers. :-)
    Yes and no! :-) :-)
    Well, seriously it has:

1. Yes, it is implied:
        It is implied by the layout rule in the report, however indirectly.
   According to the layout rule the following three pieces of might-be-Haskell 
programs:

        a = abc where
                def = ghi where
        oops = bigslip
   and
        a = abc where
                def = ghi where
            oops = slip
   and
        a = abc where
                def = ghi where
                oops = smallerslip

   are syntactically illegal because the layout rule produces the following three 
pieces:

        a = abc where
                {def = ghi where
        };{oops = bigslip
   }
   and
        a = abc where
                {def = ghi where
            }{oops = slip
   }
   and
        a = abc where
                {def = ghi where
                ;{oops = smallerslip
   }}
   respectively, and all three of these pieces have syntax errors.  And that was
   because the indentation did not increase from outer to inner blocks.

        At least, that is how I interpret the layout rule.  I admit, it is a bit
   unclear in the text of the report.  Does the surrounding block's layout stay
   in effect after a "where"/"of" until a new layout-{ is produced?  (I have assumed: 
yes.)
   In what order should layout tokens be considered when several are produced at the
   same spot of the original program? (I have assumed: in the order they are 
"created".)
   (I have also assumed that after being layout processed once, no layout processing
   is done on the result.)
        Admittedly, this interpretation is not exactly what I have in my parser (pre-)
   implementation.  But it too rejects all of the above examples, via a slightly 
different
   route, still without directly comparing the stored indentation levels with each 
other.
   And, of course, I make no fuss with some "position -1 for module/interface 
keywords".


2. No, it is not implied:
        It is not always the case that inner "blocks" must be indented more.
   Layout and non-layout blocks "may be mixed freely".  The status of the use of
   layout *within* a block delimited by explicit {} is still unclear, although there
   was some discussion on this a few months ago.  Here is my interpretation:
        The indentation of a layout block within an explicitly braced block is
   independent of any layout block surrounding the explicitly braced block.  So when
   entering an explicitly braced block layout is turned off.  If turned on again
   by an inner layout block, the indentation for that block may be less (or equal)
   to the outer layout block's indentation.  This is in order to be able to copy
   verbatim supposed Haskell code pieces into an otherwise generated Haskell program.
   (As for instance in the "Happy" system.)

    In implementation terms, this means that in addition to the indentation stack
(or equivalent), one needs a layout on/off stack (or equivalent).  It also requires
that indentation positions need not increase if there is a non-layout block 
hierachically
"between" the layout blocks, but the indentation positions must increase if an 
explicit {
does not intervene.  Doing this "increasment" test explicitly may of course produce 
better
syntax error reports.  ((The most elegant approach is probably to join those two 
stacks.
The hacker would choose position -1 (""""column 0"""") for representing "layout 
off"...))
Notice that at top level, layout is initially off.

                        Regards
                        /kent k

PS.  I do find it worrisome that the following piece of Haskell code is syntactically 
ok:
        case a of
          c -> d
          x -> y
          +z
I.e.:
        case a of
          {c -> d
          ;x -> y
          ;}+z
after layout processing.  Your other layout horror examples:
       a = n where n = 42 ; ; b = 43               -- terminated by second `;'
       c = case x of 1->y where {y=44} where {x=1} -- ditto by second `where'
       d = case 1 of 1->44 :: Int + 1              -- ditto by `+'
are also a source of worry.  My current (test) parser does not allow the first, second,
and fourth, and I don't feel like adding the complexity required to handle them either.

                                /kn


======================================================================
> the convention about topdecls not having to be indented would no longer be an
> ugly exception, it would be more consistent with implicit main programs which
> have no introductory `where', 


The "convention about topdecls not having to be indented" can be stricken without
further ado (did I get the English right here? :-).  It would not change anything.
It is already handled by the rest of the layout rules.  In particular, the part
on if-syntactically-correct-to-insert-a-}-to-prevent-a-syntax-error...
======================================================================

                        End of my old messages on layout...
                        /kent k

Reply via email to