Zulip Chat Archive

Stream: lean4

Topic: why simple lambda notation fails?


Asei Inoue (Jul 25 2024 at 17:20):

class Plus (α β γ : Type) where
  plus : α  β  γ

infixl:65 " + " => Plus.plus

-- works
instance : Plus Nat (List Nat) (List Nat) where
  plus n ns := List.map (fun x => n + x) ns

-- why this fails?
instance : Plus Nat (List Nat) (List Nat) where
  /-
  ambiguous, possible interpretations
    n + x✝¹ : ?m.1676

    n + x✝ : Nat
  -/
  plus n ns := List.map (n + ·) ns

Kyle Miller (Jul 25 2024 at 17:29):

Make sure to include all the code in your mwe. I am guessing you are missing an infix or notation that redefines +.

Asei Inoue (Jul 25 2024 at 17:46):

@Kyle Miller Thank you!! I edited my question.

Kyle Miller (Jul 25 2024 at 17:54):

Then that's the problem, you've defined your own + notation, and it's telling you that n + · is ambiguous.

Kyle Miller (Jul 25 2024 at 17:54):

Generally you shouldn't be definining your own Plus and + when there's HAdd and + already available.

Asei Inoue (Jul 25 2024 at 18:36):

Sorry, my explanation wasn't good enough.

Asei Inoue (Jul 25 2024 at 18:37):

My question here is why writing explicit lambda expressions using fun does not result in an error, but using bracket syntax fails.

Asei Inoue (Jul 25 2024 at 18:39):

It is correct that the + sign is covered by an error, but not both. The reason for the difference is what I want to know.

Asei Inoue (Jul 25 2024 at 18:40):

If (n + ·) is a macro that expands to fun x => n + x, it seemed natural that both would have the same error.

Kyle Miller (Jul 25 2024 at 18:40):

I'm not sure why the first one works (I take that back, it works because it's able to disambiguate after trying to elaborate it both ways)

Kyle Miller (Jul 25 2024 at 18:41):

I'm not sure why these are different

Kyle Miller (Jul 25 2024 at 18:47):

On a nightly build of Lean, I'm getting a different error on (n + ·):

application type mismatch
  List.map fun x x => n + x
argument
  fun x x => n + x
has type
  ?m.1610  Nat  Nat : Type ?u.1609
but is expected to have type
  ?m.1610  Nat : Type ?u.1609

Kyle Miller (Jul 25 2024 at 18:49):

I'm not sure how it's getting two arguments.

Kyle Miller (Jul 25 2024 at 18:59):

Oh, I see... It's triggered by the ambiguous notation.

Here's some of the elaboration trace.

[Elab.app.args] args: [(Term.paren "(" (choice («term_+__1» `n "+" (Term.cdot "·")) («term_+_» `n "+" (Term.cdot "·"))) ")"), `ns]

The key is that cdot appears twice, so it gets two arguments. This is a funny oversight in how cdot expansion handles choice nodes.

Kyle Miller (Jul 25 2024 at 18:59):

What version of Lean are you using?

Kyle Miller (Jul 25 2024 at 19:00):

(And in any case, the answer is "don't overload +". There are things that won't work correctly if you do. Still, it's good that it uncovered this bug.)

Floris van Doorn (Jul 25 2024 at 19:06):

I get the same error as Asei on 4.9.0-rc3.

Kyle Miller (Jul 25 2024 at 19:23):

I see it on 4.10.0-rc2 as well. (Edit: not locally, just in the playground link for Asei's original post... Edit edit: I had commented out the first instance in testing, but it's necessary to get "ambiguous" error.)

Kyle Miller (Jul 25 2024 at 20:16):

Found the explanation for what changed recently: lean4#4596 disambiguates more strongly, removing alternatives when there are stuck metavariables.

Kyle Miller (Jul 25 2024 at 20:17):

However, the same bug with cdot notation was there even then. Something to notice is that in the error

  ambiguous, possible interpretations
    n + x✝¹ : ?m.1676

    n + x✝ : Nat

you can see both x✝¹ and x✝. There are two variables, not one.

Kyle Miller (Jul 25 2024 at 20:22):

Reported: lean4#4832


Last updated: May 02 2025 at 03:31 UTC