ocaml / oloop

Evaluate code through the OCaml toploop for inclusion in educational material.
ISC License
12 stars 5 forks source link

failure with async code #28

Open agarwal opened 9 years ago

agarwal commented 9 years ago
$ cat async.topscript 
#use "topfind";;    
#thread;;
#camlp4o;;
#require "core";;
#require "core.syntax";;
#require "async";;
open Core.Std;;
open Async.Std;;

let maybe_raise =
  let should_fail = ref false in
  fun () ->
    let will_fail = !should_fail in
    should_fail := not will_fail;
    after (Time.Span.of_sec 0.5)
    >>= fun () ->
    if will_fail then raise Exit else return ()
;;

maybe_raise ();;
maybe_raise ();;
$ oloop async.topscript -silent-directives -determine-deferred
(* part 0 *)
# #use "topfind";;  

# #thread;;

# #camlp4o;;

# #require "core";;

# #require "core.syntax";;

# #require "async";;

# open Core.Std;;

# open Async.Std;;

# let maybe_raise =
  let should_fail = ref false in
  fun () ->
    let will_fail = !should_fail in
    should_fail := not will_fail;
    after (Time.Span.of_sec 0.5)
    >>= fun () ->
    if will_fail then raise Exit else return ()
;;
val maybe_raise : unit -> unit Async_kernel.Deferred.t = <fun>

# maybe_raise ();;
- : unit = ()

# maybe_raise ();;
(Invalid_argument "output_value: abstract value (outside heap)")
oloop-top: sending the phrase eval outcome failed because: output_value: abstract value (outside heap)

Simplifying the example doesn't give the error. For instance, if you just always raise Exit, then you don't see this error.

Chris00 commented 9 years ago

I guess the problem is with Exception of (exn * serializable_out_value), in this case the exn (the one coming from Async) carrying a closure. There is unfortunately no general way around it except to “degenerate” the exception if the serialization fails... :-(

agarwal commented 9 years ago

"Degenerate" in what sense? Will it be somewhat of a general solution? I want to get to the point where oloop's behavior doesn't forever depend on the specific OCaml code being run. Ideally, the specific OCaml code should be irrelevant to oloop.

Chris00 commented 9 years ago

The only way I see of "degenerating" an exception in a generic way is to convert it to a string. Given that there is no way of reconstructing the exception from that, one needs to add a case to the possible outcomes.

Chris00 commented 9 years ago

Note that commit 1ef5c56 is also part of the solution.

If you have some time, you may want to track why using the compiler way of printing exceptions leads breaks the printing in a "funny" way.