• Andrei Paskevich's avatar
    Mlw: labels can act as local exceptions · cda6d915
    Andrei Paskevich authored
    Useful to break out of the loops:
      label Break in
      while ... do
        label Continue in
        ... raise Break ...
        ... raise Continue ...
    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.