[erlang-questions] erlang:raise/3 considered harmful?

Jesper Louis Andersen jesper.louis.andersen@REDACTED
Mon May 16 12:40:23 CEST 2016


On Mon, May 16, 2016 at 12:19 PM, Björn Gustavsson <bjorn@REDACTED> wrote:

> erlang:raise/3 is particularly useful when you
> don't want to handle the error, but let you log
> important information about the context.
>

I think this is the key insight.

The problem is that in Erlang, an exception is not a first class value.
When an exception occurs, it either crashes the process, or it is caught by
a "catch-style" expression. When caught, the exception is turned into two
atoms, Class and Reason, and as a side-effect the VM tracks the last
stacktrace. But an exception is not a first class value, as is the case in
e.g., Standard ML.

When the exception is caught, the VM "reflects" the exception into {Class,
Reason, erlang:get_stacktrace()} which is now our representation of the
exception in our code (since we have no access to first-class exceptions).
The erlang:raise/3 function acts as a "reifier" and turns our
"proxy-representation" back into a VM exception which the VM can work with.

Any solution not involving exceptions will have to simulate them. The two
obvious ways are the process dictionary to track the state of "done" on the
socket, or a separate process for either the Fun or the Socket. Neither of
these sound desirable to me.

In Standard ML, we can write:

datatype ('a, 'b) result = Ok of 'a | Error of 'b

exception Argh of string

fun f () = raise (Argh "Some error here")

fun g () =
   Ok (f ()) handle Ex => Error Ex

fun h () =
   case g () of
       Ok v => v
     | Error ex => raise ex

Note how the function 'g' handles any exception and turns it into an error
(wrapped in the a result datatype to make the type system happy). Finally
the function 'h' can re-raise the exception in another context:

> use "z.sml";
exception Argh of string
val f = fn: unit -> 'a
val g = fn: unit -> ('a, exn) result
val h = fn: unit -> 'a
datatype ('a, 'b) result = Error of 'b | Ok of 'a
val it = (): unit
> h ();
poly: : warning: The type of (it) contains a free type variable. Setting it
to a unique
   monotype.
Exception- Argh "Some error here" raised


-- 
J.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://erlang.org/pipermail/erlang-questions/attachments/20160516/e216827f/attachment.htm>


More information about the erlang-questions mailing list