---
# System prepended metadata

title: orelse markers

---

# `orelse` markers

Right now, `f() orelse g()` desugars to control flow like:

```mermaid
graph LR
  Start
  A["f()"]
  B["g()"]
  End

  Start --> A
  A --failed--> B
  A --passed--> End
  B --> End
```

We can reduce that to normal code:

```ts
let t#0, t#1;
let fail#1: Boolean;

t#1 = hs(fail#1, f());
if (fail#1) {
    t#0 = g();
} else {
    t#0 = t#1;
}

t#0
```

But it'd be nice to keep information about `orelse` in the AST.

One way to do that is with marker expressions: expressions that do not affect the semantics but which are not removed by the Interpreter.

A *marker expression* is a call to a pure, zero argument functions whose semantics are:

- In *InterpMode.Full*, returns `void` with no side-effect.
- In *InterpMode.Partial*, returns *NotYet* with no side-effect.

```mermaid
graph LR
  Start
  try["<b>or_start()</b>"]
  A["f()"]
  catch["<b>orelse_xfer()</b>"]
  B["g()"]
  End

  Start --> try --> A
  A --failed--> catch --> B
  A --passed--> End
  B --> End
```

That would correspond to code like

```diff=
 let t#0, t#1;
 let fail#1: Boolean;
 
+orelse_start();
 t#1 = hs(fail#1, f());
 if (fail#1) {
+    orelse_xfer();
     t#0 = g();
 } else {
     t#0 = t#1;
 }
 
 t#0
```

Marking the end of an *orelse* would be nice too.