Zulip Chat Archive
Stream: new members
Topic: In what sense is Option.or strict in the second argument?
Kevin Cheung (Oct 28 2024 at 14:16):
From the documentation:
def Option.or {α : Type u_1} : Option α → Option α → Option α
If the first argument issome a
, returnssome a
, otherwise returns the second
argument. This is similar to<|>/orElse
, but it is strict in the second argument.
In what sense is it "strict" in the second argument? When I ran the following, both lines at the end printed only "left":
def left := some (dbgTrace "left" fun _ => 0)
def right := some (dbgTrace "right" fun _ => 1)
#eval Option.or left right -- why isn't right evaluated?
#eval left <|> right
Any help is greatly appreciated.
Markus Himmel (Oct 28 2024 at 14:37):
The behavior you're seeing is due to the compiler inlining Option.or
. You can observe the difference if you hide or
and orElse
behind definitions:
def left := some (dbgTrace "left" fun _ => 0)
def right := some (dbgTrace "right" fun _ => 1)
def a (left right : Option Nat) := Option.or left right
def b (left : Option Nat) (right : Unit → Option Nat) := left.orElse right
#eval a left right
#eval b left (fun _ => right)
Kevin Cheung (Oct 28 2024 at 14:38):
Thank you. Is there a way to just turn off inlining?
Markus Himmel (Oct 28 2024 at 14:55):
In general, inlining is crucial to the performance of Lean code because often the compiler needs to "see" how a definition uses its input in order to perform destructive updates. I'm not aware of a way to turn off inlining for imported functions that are marked to be inlined. If you care about "observable effects" of the code like your dbgTrace
, then working in a monad like IO
is likely a better option.
Kevin Cheung (Oct 28 2024 at 14:59):
I see. Thank you.
Last updated: May 02 2025 at 03:31 UTC