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

Jonas Almström Duregård jonas.duregard at chalmers.se
Sat Jul 7 09:33:10 CEST 2012


Couldn't we use \\ for multi-case lambdas with layout?

If not, these are my preferences in order (all are single argument versions):
1: Omission: "case of". There seems to be some support for this but it
was not included in the summary.
2: Omission with clarification: "\case of"
3: "\of"  - but I think this is a little weird. It's nice to have
short keywords but not at the expense of intuition. The goal here is
to drop the variable name not the case keyword, right?

Regards,
Jonas

On 7 July 2012 06:08, Tyson Whitehead <twhitehead at gmail.com> wrote:
> On July 6, 2012 11:49:23 Tyson Whitehead wrote:
>> 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.
>
> I've thought some more about this and it seems to me that there are two ways
> people might intuitively think about doing grouping via indentation.
>
> 1 - the first item is on the same line and subsequent ones are lined up with it
>
>   do stmt1
>      stmt2
>
> 2 - the first item is on a new line and subsequent ones are lined up with it.
>
>   do
>     stmt1
>     stmt2
>
> The current layout engine is targeted at (1).  It appears to do (2), but it is
> not really reliable as things start to go south if the first line happened to
> open more than one grouping (precisely the problem that make '\' a group token
> would introduce in codes).  For an example, consider
>
>   let greet name = do
>     putStr "hello "
>     putStrLn name
>   in f "world"
>
> It currently translates into
>
>   let { greet name = do {} } putStr "hello " putStrLn name in f "world"
>
> This results in an unituituve "Empty 'do' construct" error message.
>
> I propose we detected (2) and make it work too.  That is, if the line ends
> with a grouping construct and the next line is indented relative to that line,
> then assume we really don't want '{}' and instead always start grouping (even
> if it isn't indented further than other possible groupings also started).
>
> In other words, translate the above into
>
>   let { greet name = do {
>     putStr "hello";
>     putStrLn name
>   }} in f "world"
>
> This would then correctly handle the problamatic case raised in wiki where
>
>   mask $ \restore -> do
>     stmt1
>     stmt2
>
> is in translated into
>
>   mask $ \ { restore -> do {} } stmt1 stmt2
>
> under the current rules if '\' is made a grouping token.
>
> The very limited scope of this (i.e., it would only apply to lines that end
> with a grouping construct where the next line is indented further than that
> line) should also address Simon's concerns regarding things like
>
>    f x y = x + y
>      where  -- I just left this where here by accident
>
>    g x = ...
>
> and
>
>    instance Exception Foo where
>    instance Exception Bar
>
> Cheers!  -Tyson
>
> PS:  To be fully precise, the modified layout decoder in 9.3 would be
>
>   L (<n>:ts)     i (m:ms) = ; : (L ts n (m:ms))   if m = n
>                           = } : (L (<n>:ts) n ms) if n < m
>   L (<n>:ts)     i ms     = L ts n ms
>   L ({n}:<n>:ts) i ms     = { : (L ts n (n:ms))   if n > i (new rule)
>   L ({n}:ts)     i (m:ms) = { : (L ts i (n:m:ms)) if n > m  (Note 1)
>   L ({n}:ts)     i []     = { : (L ts i [n])      if n > 0  (Note 1)
>   L ({n}:ts)     i ms     = { : } : (L (<n>:ts) i ms)       (Note 2)
>   L (}:ts)       i (0:ms) = } : (L ts i ms)                 (Note 3)
>   L (}:ts)       i ms     = parse-error                     (Note 3)
>   L ({:ts)       i ms     = { : (L ts i (0:ms))             (Note 4)
>   L (t:ts)       i (m:ms) = } : (L (t:ts) i ms)   if m /= 0 and parse-error(t)
> (Note 5)
>   L (t:ts)       i ms     = t : (L ts i ms)
>   L []           i []     = []
>   L []           i (m:ms) = } : L [] i ms         if m /= 0 (Note 6)
>
>   http://www.haskell.org/onlinereport/syntax-iso.html
>
> As before, the function 'L' maps a layout-sensitive augmented token stream to
> a non-layout-sensitive token stream, where the augmented token stream includes
> '<n>' and '{n}' to, respectively, give the indentation level of the first token
> on a new line and that following a grouping token not followed by '{'.
>
> This time though, we allow the '{n}' '<n>' sequence (before it was supressed
> to just '{n}').  We also add a new state variable 'i' to track the indentation
> of the  current line.  The new rule now opens a grouping over a newline so
> long as the indentation is greater than the current line.
>
> Upon a less indented line, it will then close all currently open groups with
> an indentation less than the new line.
>
> _______________________________________________
> Glasgow-haskell-users mailing list
> Glasgow-haskell-users at haskell.org
> http://www.haskell.org/mailman/listinfo/glasgow-haskell-users



More information about the Glasgow-haskell-users mailing list