Do ? inside lambda functions

When we put a lambda function inside a do ? block, e.g. Array.filter<T>(arr, func(ele) { ... }), the compiler doesn’t let use a ! inside the lambda because there’s no enclosing do ?.

That makes it hard to use some library functions inside a do ? block.

Is there an easy way around this I’m missing?

That’s right, you cannot access a do? block from inside an inner function (in the same way you cannot jump to an outer label or return from an outer function).

If this was allowed, the ! could escape the do? block, because you could write examples like the following:

var f : ?Nat -> Nat = func(x : ?Nat) { 0 };  // dummy initialiser
let o = do? {
  f := func(x : ?Nat) { x! };
};
f(null);  // what now?

and various other variations.

So we cannot allow it. There is no easy workaround, I’m afraid – do? blocks are convenient, but do not always apply.

1 Like

Ah I see, so the issue lies in the difference in where a function is defined and where it is called. Thanks for clarifying.

Just to follow up on this, it seems like the Motoko compiler is totally fine with trapping (i.e. assert false) inside a lambda (i.e. inner function), and that will trap the executing canister method as expected. Can you confirm if that’s OK to do?

Yes, a trap can potentially occur at any point during execution (in Motoko or otherwise), and it aborts the current canister method.

2 Likes