fix: Option.getD eagerly evaluates dflt (#3043)

Reported [on
Zulip](https://leanprover.zulipchat.com/#narrow/stream/348111-std4/topic/Panics.20in.20Std.2EHashMap.2Efind!/near/406872395).
The `dflt` argument of `Option.getD` is not evaluated lazily, as the
documentation says, because even after `macro_inline` the expression
```lean
match opt, dflt with
| some x, _ => x
| none, e => e
```
still has the semantics of evaluating `dflt` when `opt` is `some x`.
This commit is contained in:
Mario Carneiro 2023-12-11 02:07:30 -08:00 committed by GitHub
parent e6c0484074
commit 178ab8ef2e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 20 additions and 6 deletions

View file

@ -2213,9 +2213,10 @@ returns `a` if `opt = some a` and `dflt` otherwise.
This function is `@[macro_inline]`, so `dflt` will not be evaluated unless
`opt` turns out to be `none`.
-/
@[macro_inline] def Option.getD : Option ααα
| some x, _ => x
| none, e => e
@[macro_inline] def Option.getD (opt : Option α) (dflt : α) : α :=
match opt with
| some x => x
| none => dflt
/--
Map a function over an `Option` by applying the function to the contained

View file

@ -0,0 +1,12 @@
import Lean.Data.HashMap
def test (m : Lean.HashMap Nat Nat) : IO (Nat × Nat) := do
let start := 1
let mut i := start
let mut count := 0
while i != 0 do
i := (m.find? i).getD (panic! "key is not in the map")
count := count + 1
return (i, count)
#eval test (.ofList [(1,3),(3,2),(2,0)])

View file

@ -0,0 +1 @@
(0, 3)

View file

@ -1,4 +1,4 @@
42
[Meta.debug] r: match x, 0 with
| some x, x_1 => x
| none, e => e
[Meta.debug] r: match x with
| some x => x
| none => 0