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   foo false/no-exception
17   foo true/raise-exception
18 ]
19 
20 # example showing exception handling
21 def foo raise-exception?:bool [
22   local-scope
23   load-inputs
24   # To run an instruction of the form:
25   #   try f ...
26   # write this:
27   #   call-with-continuation-mark 999/exception-tag, f, ...
28   # By convention we reserve tag 999 for exceptions.
29   #
30   # The other inputs and outputs to 'call-with-continuation-mark' depend on
31   # the function it is called with.
32   _, result:error-or:num <- call-with-continuation-mark 999/exception-tag, f, raise-exception?
33   {
34     val:num, normal-exit?:bool <- maybe-convert result, value:variant
35     break-unless normal-exit?
36     $print [normal exit; result ] val 10/newline
37   }
38   {
39     err:text, error-exit?:bool <- maybe-convert result, error:variant
40     break-unless error-exit?
41     $print [error caught: ] err 10/newline
42   }
43 ]
44 
45 # Callee function that we catch exceptions in must always return using a
46 # continuation.
47 def f raise-exception?:bool -> result:error-or:num [
48   local-scope
49   load-inputs
50   {
51     break-unless raise-exception?
52     # throw/raise
53     result <- merge 0/error, [error will robinson!]
54     return-continuation-until-mark 999/exception-tag, result
55   }
56   # 'normal' return; still uses the continuation mark
57   result <- merge 1/value, 34
58   return-continuation-until-mark 999/exception-tag, result
59   # dead code just to avoid errors
60   result <- merge 1/value, 0
61   return result
62 ]