Zulip Chat Archive
Stream: lean4
Topic: nested return in do-notation
Marcus Rossel (Sep 04 2025 at 11:31):
I think this is might be a known issue, but here's a quiz: What does Lean do in the following four examples?
def a : Id String := do
let x ← return "Lean"
def b : Id String := do
let _ ← return "Lean"
def c : Id String := do
let x ← (return "Lean")
def d : Id String := do
let x ← pure "Lean"
Solution
Examples c and d feel reasonable to me, but I find a and b rather strange. Would it be possible for the linter to give an unused variable warning on a?
Marcus Rossel (Sep 04 2025 at 11:33):
For context, I ran into an example of a when looking at Grind.realizeEqProof:
private partial def realizeEqProof (lhs rhs : Expr) (h : Expr) (flipped : Bool) (heq : Bool) : GoalM Expr := do
let h ← if h == congrPlaceholderProof then
mkCongrProof lhs rhs heq
else
flipProof h flipped heq
... where I was unsure if the let h ← can just be omitted.
Aaron Liu (Sep 04 2025 at 12:16):
that's a bit strance
Robin Arnez (Sep 04 2025 at 13:48):
Honestly, I don't find any of a, b, c, d particularly strange; I find
example : Id String := do
let a ← if true then pure "uhh" else pure "what"
very strange though.
Eric Wieser (Sep 06 2025 at 08:10):
def foo : Id String := do
let a := ← if true then pure "uhh" else pure "what"
behaves correctly at least
Last updated: Dec 20 2025 at 21:32 UTC