Ocaml 5 Effects tutorial doesn't seem to work
andrewray opened this issue · 6 comments
I was trying to work through the Ocaml 5.0 effects tutorial at https://github.com/ocaml-multicore/ocaml-effects-tutorial#1-algebraic-effects-and-handlers however, the first example doesn't work in utop - the effect is not caught, though the handler is run.
Not sure if this is a known issue - I couldn't find anything related.
I don't have any issue with running the first example in utop
.
How did you run the example?
I was mucking around in the top level and defined things multiple times. If you paste the whole example in a second time, it doesn't work (or at least doesn't for me...).
I've tried to come up with something simpler but couldn't yet.
I could reproduce. The issue is with example 1.2:
open Effect
open Effect.Deep
type _ Effect.t += Conversion_failure : string -> int Effect.t
let int_of_string l =
try int_of_string l with
| Failure _ -> perform (Conversion_failure l)
let rec sum_up acc =
let l = input_line stdin in
acc := !acc + int_of_string l;
sum_up acc
let _ =
Printf.printf "Starting up. Please input:\n%!";
let r = ref 0 in
match_with sum_up r
{ effc = (fun (type c) (eff: c Effect.t) ->
match eff with
| Conversion_failure s -> Some (fun (k: (c,_) continuation) ->
Printf.fprintf stderr "Conversion failure \"%s\"\n%!" s;
continue k 0)
| _ -> None
);
exnc = (function
| End_of_file -> Printf.printf "Sum is %d\n" !r
| e -> raise e
);
(* Shouldn't reach here, means sum_up returned a value *)
retc = fun _ -> failwith "Impossible, sum_up shouldn't return"
}
Running it the second twice shows an error:
Starting up. Please input:
10
20
MM
Exception: Stdlib.Effect.Unhandled(Conversion_failure("MM"))
Called from Topeval.load_lambda in file "toplevel/byte/topeval.ml", line 89, characters 4-14
Is this the issue you were seeing?
The issue is with the repeated definition of int_of_string
:
let int_of_string l =
try int_of_string l with
| Failure _ -> perform (Conversion_failure l)
type _ Effect.t += Conversion_failure : string -> int Effect.t
let int_of_string l =
try int_of_string l with
| Failure _ -> perform (Conversion_failure l)
where the second definition of int_of_string
calls the first one which raises the first version of the Conversion_failure
effect.
You can check that replacing the definition of int_of_string
to avoid this shadowing:
let int_of_string l =
try Stdlib.int_of_string l with
| Failure _ -> perform (Conversion_failure l)
fixes this issue.
Oh, great. I should have started by testing on the plain ocaml
toplevel to see if there was an issue. Thanks a lot for debugging this.
Ahh - that makes sense. Thankyou for the explanation.