agda / agda

Agda is a dependently typed programming language / interactive theorem prover.

Home Page:https://wiki.portal.chalmers.se/agda/pmwiki.php

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Agda prints hidden function type in hidden argument as `{{...` and then fails to parse it

andreasabel opened this issue · comments

Agda prints hidden function type in hidden argument as {{... and then fails to parse it. Example: f {{x : A} -> B}.

This is dual to the existing problem f {record {x = a}} for which we have already workaround:

-- When looking for a double closed brace, we accept either a single token '}}'
-- (which is what the unicode character "RIGHT WHITE CURLY BRACKET" is
-- postprocessed into in LexActions.hs), but also two consecutive tokens '}'
-- (which a string '}}' is lexed to). This small hack allows us to keep
-- "record { a = record { }}" working. In the second case, we check that the two
-- tokens '}' are immediately consecutive.
DoubleCloseBrace :: { Range }
DoubleCloseBrace
: '}}' { getRange $1 }
| '}' '}' {%
if posPos (fromJust (rEnd' (getRange $2))) -
posPos (fromJust (rStart' (getRange $1))) > 2
then parseErrorRange $2 "Expecting '}}', found separated '}'s."
else return $ getRange ($1, $2)
}

Rant about the syntax for instance arguments:

In hindsight, we shouldn't have allowed syntax {{...}} for instance arguments, as it necessitates these parser hacks.
Except for parsing, the other conceptual shortcoming is that the lack of visible instance metas, because we tie instanceness in with hiding. This is issue #2172.
After having introduced attributes, we could now untangle instanceness from hiding and support (@instance x : A) -> B and {@instance x : A} -> B, deprecating {{x : A}} -> B.

I tried to duplicate the DoubleCloseBrace trick into a symmetric DoubleOpenBrace, but it does not work, due to the bias in LR parser (left-to-right).
Consider (1) f {{x y}} vs f {{x y : A} -> B}. If the parse stack looks like Id '{' '{' Id Id after y we can never reduce (1) correctly, but if it looks Id DoubleOpenBrace Id Id we fail to parse (2). (LR parsers cannot reduce inside the stack, only the top of the stack.)

So a systematic solution would be to drop both DoubleCloseBrace and DoubleOpenBrace from the parser and do the construction of instance arguments and instance abstractions in a post-processing step. The parser would then only make sure that bracketing{...} is balanced.

More radically, simplify Parser.y drastically so that e.g. -> and : are just expression constructors, and then have a post-parse step that constructs the dependent function space.