1
votes

I am using ocaml_plugin to write calculator which is able to evaluate OCaml expressions at run time.

This is my plugin interface.

open Ocaml_plugin.Std

module type S = sig
  val f : unit -> float
end

let univ_constr : (module S) Ocaml_dynloader.Univ_constr.t =
  Ocaml_dynloader.Univ_constr.create ()

I am able to load functions with the signature unit -> float, for example,

let f () = 3.14159
let f () = 1.5 *. 1.5 *. 3.

and call f () in the main program to evaluate the expression in the function body. However, it supports float type only.

What should I do if I want it to support int? Time.t? Or any arbitrary OCaml type in Pervasive?

let f () = List.length [1;2;3]  (* int *)
let f () = Time.now ()          (* Time.t *)
let f () = "hello world!!!"     (* string *)

In order to evaluate at run time, ocaml_plugin seems to be the only way to go. However, in order to let the loader/compiler know what is loaded dynamically, I have to write an interface. How should I change the interface file so that it supports other types?

1
Why arbitrary types? Surely the f in your main program has an expected result type?Bergi
The calculator wants to display the calculation result. All types in pervasive can be printed out as a string.Yixing Liu
GADT might be a way to add support for a few types.Yixing Liu

1 Answers

2
votes

GADT (Generalized Algebraic Data Type) to rescue.

Although GADT exists for a long time, it is a relatively new topic in OCaml. It helps a lot in writing generic libraries in OCaml safely.

module Value = struct
   type 'a t

   module Packed = struct
     type 'a unpacked = 'a t
     type t = T : 'a unpacked -> t
   end

end

Value.Packed.t is a packed data type that we want. Theotically any data type 'a can be packed.