Imandra_thread_util.FutOur notion of concurrency is organized around 'aFut.t, which is a value that will resolve into a 'a in the future. This is (mostly) monadic and applicative, and the use of "let operators" should make it reasonably ergonomic.
The notion of 'aFut.t is shared, but most combinators are in the functor Fut.Make which depends on an executor (to specify where the combinator code runs).
type exn_with_bt_opt = exn * backtrace optionmodule type S0 = sig ... endinclude S0val pp : 'a CCFormat.printer -> 'a t CCFormat.printerval is_done : _ t -> boolis_done fut is true iff state fut is not Fut_wait. In other words, the future has resolved to a value or an exception.
val return : 'a -> 'a tFuture that just contains a value
val fail : exn -> 'a tFuture that just contains a failure
val error :
?process:string ->
?kind:Imandra_util.Error.kind ->
loc:Imandra_util.Iloc.t ->
string ->
_ tInterface to Error.error
val errorf :
?process:string ->
?kind:Imandra_util.Error.kind ->
loc:Imandra_util.Iloc.t ->
( 'a, Stdlib.Format.formatter, unit, 'b t ) Stdlib.format4 ->
'aInterface to Error.error
val return_res : ( 'a, exn_with_bt_opt ) Stdlib.result -> 'a tval wait_block : 'a t -> 'aBlock the current thread until the future is resolved.
val wait_block_catch : 'a t -> ( 'a, exn_with_bt_opt ) Stdlib.resultBlock the current thread until the future is resolved, like wait. Catches exceptions into a result.
val wait_block_poll : 'a t -> 'aWait in an active poll, so as to still catch signals and check other things.
val ignore : _ t -> unitmodule type EXECUTOR = sig ... endmodule type S = sig ... endval unwrap_ : ( 'a, exn_with_bt_opt ) Stdlib.result -> 'aUnwrap result by raising in case of error