Introduction: ---------------- This is the first release of ocamltarzan, a small fork of Jane Street sexplib that some people may found more convenient to use. http://aryx.kicks-ass.org/~pad/ocaml/ocamltarzan-0.1.tgz Motivations: -------------------- Sexplib and binprot by Jane Street are attractive, but they rely on camlp4. I don't like camlp4. I like the metaprogramming facility it offers but it has many disadvantages. So I've found a in-the-middle solution where I use camlp4 to generate code (via the small script ocamltarzan.ml), save the generated code in a file (e.g test/foo_sexp.ml), which allows then to completely remove the dependency to camlp4. Once the code has been generated, all dependencies to camlp4 can be removed. If tomorrow an incompatible new version of camlp4 arrives (e.g. camlp6 ...), your code will _still_ work, because it does not rely on the new behavior of this camlp4. It's just regular plain good ocaml code. Example of use: --------------- Given a file 'foo.ml' containing a type 't' which you would like to have 'sexp_of_t' and 't_of_sexp' functions, as well as 'sexp_of_tlist' and 'tlist_of_sexp', just add a comment annotation after the types as in: type t = A | B (* with sexp *) type tlist = t list (* with sexp *) Note that this is a comment, so it's backward compatible with your regular ocaml compiler. Your file stays basically the same. Then use my ocamltarzan (from its source directory) on this file $ ./ocamltarzan tests/foo.ml > tests/foo_sexp.ml The file foo_sexp.ml should now contain the 'xxx_of_sexp' and 'sexp_of_xxx' functions. To use the new services offered by those functions, you can write a use_foo.ml file such as: let x = [Foo.A;Foo.A;Foo.B;Foo.A] in let sexp = Foo_sexp.sexp_of_tlist x in let s = Sexp.to_string_hum sexp (* 'hum' mean human readable *) in print_string (s ^ "\n"); let chan = open_out "out.sexp" in output_string chan s; close_out chan; let sexp2 = Sexp.load_sexp "out.sexp" in let x2 = Foo_sexp.tlist_of_sexp sexp2 in assert (x = x2); () This should lead to this output: (A A B A) Note that once foo_sexp.ml has been generated, the only thing you really need to compile your code is the lib-sexp/ directory, which as you can see is a plain regular good ocaml library, with no camlp4 stuff involved. Even the annotation (* with sexp *) is a comment in the original file, so it is backward compatible with the regular ocaml compiler. Pro and cons of tarzan vs jane: ------------------------------- pro: - less camlp4 - less complicated to build - arguably less complicated to use, e.g. no need for the Type_conv_path stuff - better control on the code generation as can easily customize later the generated code, for instance to not display certain things in sexp (like the cocci_tag, position, etc) - can provide a path for handling different version, an evolutionnary format - easier to debug when there is a problem ... cons: - have to regenerate when change code - no Type_conv_path but have to do things manually with some module aliases - fragile if change order in .ml ? Note: ------- problem with mutually recursive polymorphic. Solution - duplicate functions :) have wrap_of_sexp, wrap_of_sexp_2, wrap_of_sexp_3, ... as much as needed Differences with original code: -------------------------------- Note that among other things, the file pa_sexp_conv.ml is not in the lib-sexp directory as I include there only the runtime library for sexp, not the camlp4 stuff. Put everything in a single package. Remove package related stuff, use only one dir. remove need for findlib remove OCamlMakefile remove use of (* pp cpp *); do it manually via special handling (fun that they use cpp whereas they claim camplp4 can do everything) remove need for -pack num -> nums dependency Cf also the modif-orig.txt files in subdirectories.