1 # Example program showing exceptions built out of delimited continuations.
 2 # Slightly less klunky than exception1.mu.
 3 
 4 # Since Mu is statically typed, we can't build an all-purpose higher-order
 5 # function called 'try'; it wouldn't know how many arguments the function
 6 # passed to it needs to take, what their types are, etc. Instead, until Mu
 7 # gets macros we'll directly use the continuation primitives.
 8 
 9 exclusive-container error-or:_elem [
10   error:text
11   value:_elem
12 ]
13 
14 def main [
15   local-scope
16   no-exception:bool <- copy 0/false
17   foo 0/no-exception
18   raise-exception:bool <- copy 1/true
19   foo 1/raise-exception
20 ]
21 
22 # example showing exception handling
23 def foo raise-exception?:bool [
24   local-scope
25   load-inputs
26   # To run an instruction of the form:
27   #   try f ...
28   # write this:
29   #   call-with-continuation-mark 999/exception-tag, f, ...
30   # By convention we reserve tag 999 for exceptions.
31   #
32   # The other inputs and outputs to 'call-with-continuation-mark' depend on
33   # the function it is called with.
34   _, result:error-or:num <- call-with-continuation-mark 999/exception-tag, f, raise-exception?
35   {
36     val:num, normal-exit?:bool <- maybe-convert result, value:variant
37     break-unless normal-exit?
38     $print [normal exit; result ] val 10/newline
39   }
40   {
41     err:text, error-exit?:bool <- maybe-convert result, error:variant
42     break-unless error-exit?
43     $print [error caught: ] err 10/newline
44   }
45 ]
46 
47 # Callee function that we catch exceptions in must always return using a
48 # continuation.
49 def f raise-exception?:bool -> result:error-or:num [
50   local-scope
51   load-inputs
52   {
53     break-unless raise-exception?
54     # throw/raise
55     result <- merge 0/error, [error will robinson!]
56     return-continuation-until-mark 999/exception-tag, result
57   }
58   # 'normal' return; still uses the continuation mark
59   result <- merge 1/value, 34
60   return-continuation-until-mark 999/exception-tag, result
61   # dead code just to avoid errors
62   result <- merge 1/value, 0
63   return result
64 ]