Zulip Chat Archive
Stream: lean4
Topic: possible parsing bug: invalid {...} notation
Alexander Bentkamp (Dec 17 2025 at 11:48):
Is this a bug in the parser?
----- Works:
class A
class B
where
lt (a : Nat) [A] : Bool
instance : B where
lt (a : Nat) [A] := true
----- Does not work:
class X
class Y
where
lt [X] : Bool
instance : Y where
lt [X] := true
-- invalid {...} notation, exactly one explicit source is required when using '[<index>] := <value>' update notation
Damiano Testa (Dec 17 2025 at 12:24):
Assuming that I understood what you want, it "works" with curly brackets:
instance : Y where
lt {a} := true
Damiano Testa (Dec 17 2025 at 12:25):
(or nothing at all!)
Alexander Bentkamp (Dec 17 2025 at 12:28):
Another workaround I found:
instance : Y where
lt := fun [X] => true
Damiano Testa (Dec 17 2025 at 12:29):
My second comment was very cryptic: this also works
instance : Y where
lt := true
Alexander Bentkamp (Dec 17 2025 at 12:29):
I got it, thanks!
Damiano Testa (Dec 17 2025 at 12:29):
You can see that the typeclass assumption is auto-introduced here.
Damiano Testa (Dec 17 2025 at 12:30):
I think that there is a lot of matching and assignment that it would be nice to have in that position, but not much is actually implemented (EDIT: or feasible).
Alexander Bentkamp (Dec 17 2025 at 12:31):
So, yeah, in practice this is unlikely to be a real issue. Still, the behavior is inconsistent and probably not intended.
Alexander Bentkamp (Dec 17 2025 at 12:31):
Anyway, I am happy with the workarounds you and I found.
Damiano Testa (Dec 17 2025 at 12:32):
At the very least, the error message could be more explicit about what the issue is, I think.
Kyle Miller (Dec 17 2025 at 15:57):
It's not a bug exactly, but a complication from structure notation. The where ... syntax is essentially a macro for := { ... }, and in { ... } you can use [...] to update array-like fields (internally called a "modifyOp"), like in
structure S where
xs : Array Nat
def S.change0 (s : S) (x : Nat) : S := { s with xs[0] := x }
It only works with with though, which isn't present in where syntax, so the restriction is a little pointless here.
Something that is a little counterintuitive is that in where/{...} notation, the binder lists are effectively fun binder lists. The binder list here comes from the expected type, so all you need to do is provide identifiers, not (...)/[...]/{...}/{{...}} brackets. In this case, since the X parameter is implicit, it's automatically introduced anyway:
instance : Y where
lt := true
Damiano already pointed this one out, but this is the reason for not needing to mention the parameter at all.
Kyle Miller (Dec 17 2025 at 15:58):
(One way this could be improved is to put noWs into the modifyOp parser. There's no reason to accept xs [0] := x.)
Damiano Testa (Dec 17 2025 at 16:02):
Oh, I did not realise that the error message was coming from a modifyOp!
Last updated: Dec 20 2025 at 21:32 UTC