Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OCaml, extends a program a la Emacs

Tags:

ocaml

I love OCaml, I'm waiting for my copy of Real World OCaml ! I am a beginner OCaml programmer, just know the functionnal part, a little imperative, but not much about modules, functors, objects, etc...

For sort of an interpreter project, I made sort of a newbie emacs-like evaluation. I keep a list of triplet containing a list of command name bindings as strings, a string for the description, and the ocaml function to call. The main loop just look for a matching entry in the list and call the function.

Then it was really simple to add new functionnalities, you just write a function and put an entry in the list.

I like the concept of being self-extensible like Emacs, this was easily extendable, but not really self extendable.

Could I make a program self extensible with OCaml ? How would I do that ?

I know how Emacs works, it is a big virtual machine so it interpret code and modify it's runtime environment by itself, but is there a way to add functionnalities to an OCaml program with user added modules ? or something else ?

ps : Don't laugh at me if my project sounds basic to you but I'm a beginner !

Thank you

like image 651
Nicolas Scotto Di Perto Avatar asked Mar 13 '23 16:03

Nicolas Scotto Di Perto


2 Answers

Another solution might be to use Ocaml dynamic loading facilities, e.g. the Dynlink module. Each dynamically loaded shared module could for example add entries to some global hash table mapping string names to functions (of the same type), etc... This initialization -running its top level expressions- of the dynamically loaded module happens at its loading time (when you call Dynlink.loadfile), a bit like the old _init function for POSIX dlopen

For example, you could have your program emit some Ocaml code at runtime; fork a compilation of it into a loadable dynamic library using ocamlopt -shared ; then Dynlink.loadfile that library. The initializing portion of that library would register closures using some appropriate function provided in your main program.

Alternatively, write (or use) some virtual machine or interpreter in Ocaml.

You might also use some JIT library, e.g. Ollvm, and generate some C-like code (perhaps using dlopen in some C glue code of the main program).

But as Simon Shine answered, MetaOcaml could be a better way.

BTW, perhaps you want some Common Lisp implementation?


Example:

(untested code! some details could be wrong)

Your main program prog.ml would contain

let ht = Hashtbl.create 53;;
let add_name_fun (name : string) (f : int -> int) = 
   Hashtbl.add ht name f;;
(* here you might emit the 'plugin.ml' file and fork its compilation *) 
Dynlink.loadfile "plugin.cmxs";;
(* as an example we apply every added name & function to 3 *)
Hashtbl.iter ht (fun n f) -> Printf.printf "n=%s (f 3)=%d\n" n (f 3);;

Your prog.mli would contain:

  val : add_name_fun : string -> (int -> int) -> unit;;

Your plugin.ml would contain

  Prog.add_name_fun "foo" (fun x -> x+3);;

But I did not test the code.

PS. On POSIX systems, you can do similar things in C with dlopen & dlsym. My GCC MELT is doing that. See also this.

NB: If you are fond of meta-programming approaches, read J.Pitrat's blog and books.

like image 106
Basile Starynkevitch Avatar answered Mar 21 '23 04:03

Basile Starynkevitch


Could I make a program self extendable with OCaml?

Yes, you could make a self-extensible interpreter.

Is there a way to add functionnalities to an OCaml program with user added modules?

Yes, but. The OCaml interactive prompt is such an extensible program. MetaOCaml is a multi-stage programming extension of OCaml enabling incremental compiling of new machine code during runtime. [Wikipedia] Unless you piggy-back on one of these, you are looking at a non-trivial engineering task.

How would I do that?

Depending on exactly what it is you want to do, you could also look at OCaml as Scheme or Scheme interpreter in Standard ML. Then you would basically have to build a read-eval-print loop that parses an input language and modifies your three-tuple accordingly. But not with OCaml directly.

like image 42
sshine Avatar answered Mar 21 '23 03:03

sshine