Explain difference raise/raise_notrace with a little more detail?


The manual explains that raise_notrace is “a faster version of raise which does not record the backtrace.”

I am not sure what this means exactly, because as an end user I do not see any difference between the two. Where does the raise function record the backtrace ? In what cases should raise be used rather than raise_notrace ?


The following show the difference:

> echo "raise Exit" > r.ml && ocamlopt -g r.ml && ./a.out
Fatal error: exception Pervasives.Exit
Raised at file "r.ml", line 1, characters 6-10

> echo "raise_notrace Exit" > r.ml && ocamlopt -g r.ml && ./a.out
Fatal error: exception Pervasives.Exit

With raise_notrace you’ll never get a stacktrace in native code with backtraces enabled (-g).

Getting backtraces has a cost, raise_notrace avoids it. It should only be ever used whenever you made sure the exception you raise will never get uncaught by your program.

This is useful for when you use exceptions for control flow rather than exceptional behaviour.


But you’ll still be able to see the backtrace if you use ocamldebug, right ?

But this is bad practice anyway, isn’t it ? Especially in OCaml where you have other tools (such as, 'a option or simply adhoc variant types) for non-exceptional damage control.


Can’t respond to this I’m not familiar with ocamldebug's internals nor ocamldebug in fact.

Absolutely not. It’s none of my business to know how you implement your algorithm. The only thing I personally don’t want is you to throw me exceptions at the interface level for non-exceptional behaviour.

But as far as I’m concerned you are allowed to use whatever you wishes internally and using exceptions in that setting can avoid allocations (e.g. avoid monadic binds for errors) and simplify implementations (e.g. killing branches in backtracking algorithms). A pattern that I’ll often use is :

  let f x = 
     .... raise_notrace (Failure msg) ...
   with Failure msg -> Error (`Msg msg) 


I think OCaml exceptions were designed to be quite fast (compared to other language implementations) for that very use-case (control flow), so I don’t think this should be viewed as bad practice.


It is not bad practice. OCaml exceptions are legendary fast. The only problem I know is if the code is translated to javascript, there exceptions are not fast.
But hey, what’s the point of writing OCaml if it is to execute javascript code in the end. Just forget that specific annoying use case, and use exceptions without stack traces as much as you want in your code for control flow. :smiley: