Mlw: labels can act as local exceptions
Useful to break out of the loops: label Break in while ... do label Continue in ... raise Break ... ... raise Continue ... done When a label is put over a non-unit expression, raise acts as return: label Return in if ... then raise Return 42; 0 Also, "return <expr>" returns from the innermost function. This includes abstract blocks, too, so if you want to return across an abstract block, you should rather use a label at the top of the main function. TODO/FIXME: maybe we should let "return" pass across abstract blocks by default, to avoid surprises? One shortcoming of the labels-as-exceptions is that they cannot be used to transmit tuples with ghost elements, nor return ghost values from non-ghost expressions. A local exception with an explicit mask should be used instead. Similarly, to return a partially ghost value from a function, it must have have its mask explicitly written (which is a good practice anyway). We cannot know the mask of an expr before we construct it, but in order to construct it, we need to create the local exceptions first. Another caveat is that while it is possible to catch an exception generated by a label, you should avoid to do so. We only declare the local exception if the expression under the label _raises_ the exception, and thus the following code will not typecheck: label X in (try raise X with X -> () end) Indeed, the expression in the parentheses does not raise X, and so we do not declare a local exception X for this label, and so the program contains an undeclared exception symbol.
Showing with 88 additions and 48 deletions