# How to avoid deeply nested switch statements?

**URL:** <https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380>\
**Category:** Language Support\
**Created:** [September 18, 2021, 9:32pm UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380 "2021-09-18T21:32:50Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [September 18, 2021, 9:32pm UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/1 "2021-09-18T21:32:50Z")

</div>

I find the code difficult to read when I’m dealing with a bunch of `Option` and `Result` values…

---

<div class="post-metadata">

**Author:** ![paulyoung](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/paulyoung/32/5251_2.png) [@paulyoung](https://forum.dfinity.org/u/paulyoung)\
**Post date:** [September 19, 2021, 1:14am UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/2 "2021-09-19T01:14:51Z")

</div>

One option is to use `chain` which represents a monadic bind and allows you to sequence operations of the same type:

> <https://github.com/dfinity/motoko-base/blob/9f6f005e39513c85d14f2e0638cdd8b090d7cc8c/src/Result.mo#L66-%23L92>

---

<div class="post-metadata">

**Author:** ![nomeata](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/nomeata/32/733_2.png) [@nomeata](https://forum.dfinity.org/u/nomeata)\
**Post date:** [September 19, 2021, 8:37am UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/3 "2021-09-19T08:37:02Z")

</div>

For option types (but, unfortunately, not result) you can use [`do ? { … }` blocks](https://sdk.dfinity.org/docs/language-guide/language-manual.html#exp-do-opt).

---

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [September 19, 2021, 6:22pm UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/4 "2021-09-19T18:22:29Z")

</div>

Yeah, the exclamation mark operator in `do ? {}` makes code way way more readable, but as you said it doesn’t support `Result` return values, which is a bummer.

I also kinda wish that after an `assert Option.isSome(val)` the variable `val` would automatically be “unwrapped” by the compiler and treated as `?val` from thenceforth, kinda like what TypeScript does.

Right now, I have to do a switch statement:

```auto
switch (caseInfo) {
  case (null) { assert false };
  case (?caseInfo) {
    // do something with caseInfo
  };
};

```

Just this adds a nested switch layer.

---

<div class="post-metadata">

**Author:** ![skilesare](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/skilesare/32/5609_2.png) [@skilesare](https://forum.dfinity.org/u/skilesare)\
**Post date:** [September 19, 2021, 9:51pm UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/5 "2021-09-19T21:51:08Z")

</div>

The null case specifically is begging for some syntactic sugar.

Something like the following would be nice for retiring something else if you hit a null and chaining unwrapped otherwise.

myMap.get(id)?(defaultValue).myproperty;

---

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [September 19, 2021, 11:39pm UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/6 "2021-09-19T23:39:54Z")

</div>

Exactly I was hoping for something like that. Or even with ! instead of ?

---

<div class="post-metadata">

**Author:** ![nomeata](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/nomeata/32/733_2.png) [@nomeata](https://forum.dfinity.org/u/nomeata)\
**Post date:** [September 20, 2021, 6:10am UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/7 "2021-09-20T06:10:12Z")

</div>

If you assert or return anyways, you can do

```auto
let caseInfo = switch (caseInfoOpt) {
  case (null) { raise Error… };
  case (?caseInfo) { caseInfo };
};
// do something with caseInfo

```

It’s annoying that `assert false` doesn’t have a suitable return type for that, but the upcoming `Debug.trap` improves that.

---

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [September 20, 2021, 7:12am UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/8 "2021-09-20T07:12:46Z")

</div>

I’m assuming you mean `throw` instead of `raise`.

This is a neat trick, but the issue is that I can’t turn it into a private helper function because `throw` only works in an async context.

Interesting about `Debug.trap`. I see it in the [docs](https://sdk.dfinity.org/docs/base-libraries/debug#trap) but I guess it still hasn’t shipped with the latest version of Motoko yet? It should work since the return type is `None`, as you suggested.

---

<div class="post-metadata">

**Author:** ![rossberg](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/rossberg/32/795_2.png) [@rossberg](https://forum.dfinity.org/u/rossberg)\
**Post date:** [September 20, 2021, 7:29am UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/9 "2021-09-20T07:29:29Z")

</div>

> [@skilesare](#):
>
> myMap.get(id)?(defaultValue).myproperty;

You could write this as

```auto
Option.get(myMap.get(id), defaultValue).myProperty

```

---

<div class="post-metadata">

**Author:** ![nomeata](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/nomeata/32/733_2.png) [@nomeata](https://forum.dfinity.org/u/nomeata)\
**Post date:** [September 20, 2021, 7:37am UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/10 "2021-09-20T07:37:46Z")

</div>

> [@jzxchiang](#):
>
> still hasn’t shipped with the latest version of Motoko yet

I think it’s in the latest Motoko release, but not yet the latest dfx release.

---

<div class="post-metadata">

**Author:** ![nomeata](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/nomeata/32/733_2.png) [@nomeata](https://forum.dfinity.org/u/nomeata)\
**Post date:** [September 20, 2021, 8:08am UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/11 "2021-09-20T08:08:49Z")

</div>

> [@jzxchiang](#):
>
> This is a neat trick, but the issue is that I can’t turn it into a private helper function because `throw` only works in an async context.

You can make the helper function `async`, and call it with `await`, can’t you? I think that’s the “official” solution for abstracting over code that `throw`s or `await`s.

---

<div class="post-metadata">

**Author:** ![jzxchiang](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/jzxchiang/32/2592_2.png) [@jzxchiang](https://forum.dfinity.org/u/jzxchiang)\
**Post date:** [September 21, 2021, 6:53am UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/12 "2021-09-21T06:53:36Z")

</div>

Yeah I suppose so, although I’d like not to incur the 2-5s wait time for updates but I guess that’s what `Debug.trap` will be for.

---

<div class="post-metadata">

**Author:** ![paulyoung](https://sea1.discourse-cdn.com/flex023/user_avatar/forum.dfinity.org/paulyoung/32/5251_2.png) [@paulyoung](https://forum.dfinity.org/u/paulyoung)\
**Post date:** [September 23, 2021, 2:16am UTC](https://forum.dfinity.org/t/how-to-avoid-deeply-nested-switch-statements/7380/13 "2021-09-23T02:16:07Z")

</div>

A while back I sketched out a version of `do` notation using a function that used `try`/`catch` under the hood.

In addition to the `async` overhead I also ran into this limitation: [Parametric polymorphism and async](https://forum.dfinity.org/t/parametric-polymorphism-and-async/1192)
