How to exit from calculation in OCaml?

Hi there,
You can actually implement a call/cc-like behavior from @octachron’s first construct :

let callcc (type a) f =
  let exception Kont of a in
  let k x = raise (Kont x) in
  try f k with
  |  Kont x -> x

val callcc : (('a -> 'b) -> 'a) -> 'a = <fun>
callcc 
   (fun k -> 
        let n = 1 + k 50 in
        (* never reaches here *)
        n * n 
    );;
- : int = 50

However, you need to be careful not to accidentally sink the exception from within the inner function :

let f k =
    try
       (* code that may trigger a Not_found exception *) 
       k 50 
     with 
     |  _ -> 12 ;;

 callcc f
- : int = 12

Let’s suppose that no Not_found exception was raised at line 3.
The exception (Kont 50) fires at line 4 and the deepest "try … with … " handler first gets the chance to match it.
Since the wildcard “_” matches any exception, (Kont 50) gets replaced by the value 12 and callcc is left under the impression that no exception has ever occured !

That’s why you should restrict that wildcard use and be more specific when catching an exception :

let f k =
    try 
      (* code that may trigger a Not_found exception *) 
       k 50 
     with 
    | Not_found -> 12 ;;

 callcc f;;
- : int = 50

Here, the exception (Kont 50) is not matched by the local handler.
Callcc’s handler is next in line to process it : there is a match and (Kont 50) is then caught and eventually replaced with 50

I do avoid handling exceptions whenever possible. In most usecases, you can use the “result monad” instead, a nice pattern that both composes well and yields more readable code :
exception vs. monad on Ocaml discuss
result monad in action

Nota :
If f needs additional arguments, you can slightly change the definition of callcc :

let callcc1 (type a) f arg =
   let exception Kont of a in
   let k x = raise (Kont x) in
   try f k arg with
    |  Kont x -> x

val callcc1 : (('a -> 'b) -> 'c -> 'a) -> 'c -> 'a = <fun>