In the new frontend, ```lean @[macroInline] def or : Bool → Bool → Bool | true, _ => true | false, b => b ``` is compiled as ```lean def or (x y : Bool) : Bool := or.match_1 _ x y (fun _ => true) (fun b => b) ``` Thus, the `[macroInline]` attribute does not guarantee that `y` is evalutated only when `x` is `false`. The new definition does. This issue was not exposed before because the compiler has an optimization that float let-decls when they are used in a single branch. @Kha We have talked about removing `macroInline`, and defining functions such as `or` as ```lean @[inline] def or (x : Bool) (y : Unit -> Bool) : Bool := match x with | true => true | false => y () ``` and define `x || y` as notation for `or x (fun _ => y)`. I think this is the way to go for polymorphic operators such as `<|>`, but I am not sure about `or`. New users will probably be puzzled by it. In particular when they are writing proofs.
21 lines
420 B
Text
21 lines
420 B
Text
@[noinline] def c1 (x : Nat) : Bool :=
|
|
dbgTrace! "executed c1"
|
|
x == 0
|
|
|
|
@[noinline] def c2 (x : Nat) : Bool :=
|
|
dbgTrace! "executed c2"
|
|
x == 0
|
|
|
|
@[noinline] def c3 (x : Nat) : Bool :=
|
|
dbgTrace! "executed c3"
|
|
x > 0
|
|
|
|
@[noinline] def f (x : Nat) := x + 1
|
|
|
|
def tst (x : Nat) : Nat := do
|
|
let x := if !c1 x || (!c2 x && c3 x) then f x else f (x+2)
|
|
match x with
|
|
| 0 => f (x+1)
|
|
| y+1 => f (y+3)
|
|
|
|
#eval tst 10
|