Proposal: Fix a "bug" in the layout interpretation algorithm in Section 10.3 of Report 2010
Mario Blažević
mblazevic at stilo.com
Mon Apr 29 17:55:33 UTC 2019
On 2019-04-29 3:54 a.m., 佐藤玄基 wrote:
> Hello,
>
> I found that the layout interpretation algorithm in Section 10.3 of
> Report 2010
> produces parse-error when applied to the following code snippet:
>
> [Snippet 1 : The code that fails to be parsed by Report]
> main = print t where { t = s where s = 1 :: Int }
> [/Snippet 1]
>
> GHC 8.4.4 and GHC 8.6.4 accept this code, which is a good behavior in my
> opinion.
It's worth noting that the snippet is accepted by GHC even with
-XAlternativeLayoutRule. Overall, I think I'd rather just have the
concrete AlternativeLayoutRule algorithm in the specification than tweak
the current broken and vague pseudo-code.
> If we regard the behavior of those current GHCs as correct,
> this "bug" in the Report lies in the following lines in the definition
> of the function L:
>
> [Snippet 2 : A part of the layout interpretation algorithm in the Report]
> L (} : ts) (0 : ms) = } : L ts ms (Note 3)
> L (} : ts) ms = parse-error (Note 3)
> [/Snippet 2]
>
> I suggest this be modified to what follows:
>
> [Snippet 3 : A Suggested modification to Snippet 2]
> L (} : ts) (m : ms)
> | m == 0 = } : L ts ms
> | m > 0 = } : L (} : ts) ms
> L (} : ts) [] = parse-error
> [/Snippet 3]
>
>
>
> Let me explain in detail.
> First of all, how is Snippet 1 refused by the Report 2010 algorithm?
> Let us emulate it by hand. Firstly pre-process Snippet 1:
>
> [Snippet 4 : Pre-processed Snippet 1]
> {1} main = print t where { t = s where {36} s = 1 :: Int }
> [/Snippet 4]
>
> I assumed that Snippet 1 is the only line in a file.
> We may compute:
>
> [Computation 5 : Apply L to Snippet 4]
> L <Snippet 4> []
> = "{ main = print t where { t = s where { s = 1 :: Int"
> ++ L "}" [36,0,1]
> [/Computation 5]
>
> Wait here. What does L do next?
> Looking from top to bottom, we hit the second line in Snippet 2,
> which leads us to parse-error.
> Now you might expect that the line
>
> [Snippet 6 : Another part of the Report algorithm]
> L (t : ts) (m : ms) = } : (L (t : ts) ms) if m /= 0 and parse-error(t)
> (Note 5)
> [/Snippet 6]
>
> would help, but unfortunately it doesn't work.
> Even if we put aside the fact that Snippet 6 is lower in the text than
> Snippet 2
> and has lower priority of execution according to the usual Haskell
> matching rule,
> this line in L won't be triggered by this parse error at all,
> since *parse-error('}') is false!*
> Let us go back to the definition of parse-error(t).
>
> [Quotation 7 : Note 5 in the Report algorithm]
> The side condition parse-error(t) is to be interpreted as follows:
> if the tokens generated so far by L together with the next token t
> represent an invalid prefix of the Haskell grammar,
> and the tokens generated so far by L followed by the token "}"
> represent a valid prefix of the Haskell grammar, then parse-error(t) is
> true.
> [/Quotation 7]
>
> Now, this is the point.
> In this case, "the tokens generated so far by L together with the next
> token t" is:
>
> [Snippet 8]
> { main = print t where { t = s where { s = 1 :: Int }
> [/Snippet 8]
>
> This is a *valid prefix of the Haskell grammar*, and hence
> parse-error('}') is false.
>
>
>
> Therefore, any Haskell2010-compliant compiler should reject Snippet 1,
> and this doesn't seem to be any sensible choice of specification.
> Speaking generally, I guess the Report 2010's authors wanted
> the case where a inner implicit brace and a outer explicit brace is
> closed at the same time
> to be processed by the rule in Snippet 6,
> but it doesn't work since Snippet 2 is before Snippet 6 in the
> definition of L
> and parse-error(t) is always false if t = '}'.
>
> The fix of this problem is easy: replace Snippet 2 with Snippet 3.
> The added case of m > 0 is doing almost the same thing as Snippet 6, but
> parse-error(t) is removed.
> If we distinguish implicit close-braces and explicit close-braces,
> the condition m > 0 fully does the job of parse-error('}'),
> so I expect there will be no problem with this modification.
>
>
>
> I apologize you if this long text has exhausted your eyes.
> I hope this suggestion would help.
>
> Sincerely yours,
> Genki SATO
>
> _______________________________________________
> Haskell-prime mailing list
> Haskell-prime at haskell.org
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-prime
>
More information about the Haskell-prime
mailing list