# Using let-binding syntax to implement option 'or'

**URL:** <https://discuss.ocaml.org/t/using-let-binding-syntax-to-implement-option-or/4588>\
**Category:** Learning\
**Created:** [October 26, 2019, 3:11pm UTC](https://discuss.ocaml.org/t/using-let-binding-syntax-to-implement-option-or/4588 "2019-10-26T15:11:37Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [October 26, 2019, 3:11pm UTC](https://discuss.ocaml.org/t/using-let-binding-syntax-to-implement-option-or/4588/1 "2019-10-26T15:11:37Z")

</div>

I think I just stumbled on an interesting behaviour of the new let-binding syntax: it can make the binding body lazy. And this can be used to express ‘alternative’/‘or’ behaviour for various types e.g. `option`. Can someone take a look at my comment (and code) and confirm if my reasoning is correct?

> **[r/ocaml - The opposite of the Maybe monad](https://www.reddit.com/r/ocaml/comments/dlqr6m/the_opposite_of_the_maybe_monad/f5a88cb/)**
>
> 6 votes and 9 comments so far on Reddit

---

<div class="post-metadata">

**Author:** ![paurkedal](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/paurkedal/32/586_2.png) [@paurkedal](https://discuss.ocaml.org/u/paurkedal)\
**Post date:** [October 27, 2019, 9:46am UTC](https://discuss.ocaml.org/t/using-let-binding-syntax-to-implement-option-or/4588/2 "2019-10-27T09:46:31Z")

</div>

Yes. As someone pointed out a semigroup is sufficient here. The monad is “too powerful”, and you could replace the `let x =` with `let () =` in your code. As another option (semantically the same), define

```ocaml
let (||=) x f = match x with None -> f () | Some _ as y -> y

```

and compare

```ocaml
let|| () = Some 0 in let|| () = Some 1 in Some 2;;
Some 0 ||= fun () -> Some 1 ||= fun () -> Some 2;;

```

I think that’s a matter of taste. If we want something shorter:

```ocaml
let (||~) x y = match x with None -> Lazy.force y | Some _ as r -> r;;
Some 0 ||~ lazy (Some 1) ||~ lazy (Some 2);;

```

---

<div class="post-metadata">

**Author:** ![yawaramin](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/yawaramin/32/3384_2.png) [@yawaramin](https://discuss.ocaml.org/u/yawaramin)\
**Post date:** [October 28, 2019, 4:18am UTC](https://discuss.ocaml.org/t/using-let-binding-syntax-to-implement-option-or/4588/3 "2019-10-28T04:18:43Z")

</div>

Thanks for the feedback. What struck me about the let-binding approach here was that it automatically makes the binding body lazy. This is something I’ve seen before only for the intrinsic `%sequor` (i.e. `(or)` and `(||)`), oh and for `lazy` too of course.

But the let-binding is configurable, which is the really new thing. Still trying to decide whether that is cool or just too confusing compared to normal idiomatic OCaml. Guess I need to work through some more examples. At least one other comes to mind, a limited ‘if-let’, e.g.:

```ocaml
# let (let-?) option f = match option with
  | Some x -> f x
  | None -> ();;
val ( let-? ) : 'a option -> ('a -> unit) -> unit = <fun>

# let-? x = Some "1" in print_endline x;;
1
- : unit = ()

# let-? x = None in print_endline x;;
- : unit = ()

```

---

<div class="post-metadata">

**Author:** ![paurkedal](https://sea2.discourse-cdn.com/flex020/user_avatar/discuss.ocaml.org/paurkedal/32/586_2.png) [@paurkedal](https://discuss.ocaml.org/u/paurkedal)\
**Post date:** [October 28, 2019, 8:18am UTC](https://discuss.ocaml.org/t/using-let-binding-syntax-to-implement-option-or/4588/4 "2019-10-28T08:18:05Z")

</div>

Yes, or to put it in other words, this is the first user-definable binding construct. The `and` part is also interesting as it allows passing nested pairs without using nested parentheses.

The `let-?` is available as `Option.iter`, though the code becomes longer.
