Hello
Here is the latest Caml Weekly News, for the week of November 20 to 27, 2007.
Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/2260d2c1f91dc3c1#99b988e98f8d4d6a
Daniel de Rauglaudre announced:New release of Camlp5: 5.03 Main changes: * Added commands mkcamlp5 and mkcamlp5.opt to build camlp5 executables. * Some small improvements and bug fixes. For changes of all versions, see file CHANGES in Camlp5 site. Download the sources and the documentation at: http://pauillac.inria.fr/~ddr/camlp5/David Teller asked and Daniel de Rauglaudre answered:
> By quickly browsing the documentation, I haven't been able to understand > the core of the difference between camlp4 and camlp5. I mean, there's a > Pcaml module which seems to have disappared from camlp4 in 3.10, but I > assume that's not where it ends. Could you tell us a bit more about it ? Camlp5 is the continuation of the classical Camlp4. At OCaml 3.10, Camlp4 was changed, with some incompatible features, sometimes implying many changes in user programs. A solution is to use Camlp5. Some softwares, e.g. "Coq", adopted this solution.Richard Jones also answered:
Camlp4 was extensively changed for the 3.10 release, in many ways not for the better (it's much bigger now for a start, and not backwards compatible, and has almost no documentation, and I have problems with it and findlib). Camlp5 is the camlp4 from 3.09.3 (before the changes / fork), and with some ongoing maintenance. 3.09 3.10 -------+----/\/----+---------> "new" camlp4 (distributed with OCaml) | \ --------------------> camlp5 (now distributed separately) If you had a package which depends on camlp4 in 3.09.3, you need to modify it so it compiles with OCaml 3.10. An alternative which doesn't involve modifying your package is to install camlp5. You can install both in parallel no problem. Debian ships both. Fedora will soon as well.
Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/f85425f2099921d3#dc2694c20eafb6b0
Stephanie Weirich announced:Tutorial Announcement and Call for Participation Using Proof Assistants for Programming Language Research Or: How to Write Your Next POPL Paper in Coq San Francisco, CA, 8 Jan 2008 Co-located with POPL 2008 Sponsored by ACM SIGPLAN http://plclub.org/popl08-tutorial/ ======================================================================= The University of Pennsylvania PLClub invites you to participate in a tutorial on using the Coq proof assistant to formalize programming language metatheory. This tutorial will be tailored to people who are familiar with syntactic proofs of programming language metatheory (type soundness, etc.), but have never used a proof assistant. At the end of the day, participants will have a reading knowledge of Coq and a running start on using Coq in their own work. This tutorial will be hands-on, with breaks for exercises; participants are strongly encouraged to bring a laptop running Coq 8.1 (or a later release) and either Proof General or CoqIDE. Tutorial topics - Defining language semantics in Coq - Abstract syntax - Inductively-defined relations - Derivations - Proving simple results - Fundamental tactics - Automation - Forward and backward reasoning - Scaling up to POPLmark - Semantic functions and conversion - Sets and environments - Representing binding - Locally nameless representation - Freshness through cofinite quantification - Syntactic type soundness Registration will be through the POPL 2008 registration site: http://www.regmaster.com/conf/popl2008.html The tutorial is organized and presented by members of the University of Pennsylvania PLClub: Brian Aydemir, Aaron Bohannon, Benjamin Pierce, Jeffrey Vaughan, Dimitrios Vytiniotis, Stephanie Weirich, and Steve Zdancewic. Questions can be sent to Stephanie Weirich (sweirich@cis.upenn.edu).
Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/fbfe88f193572aa8#3ac9d5e0e18ab0c9
François Thomasset announced:As I could not find easily informations on the use of labltk, I took a PerlTk tutorial with nice pedagogic qualities, and adapted it to labltk: http://www-rocq.inria.fr/~thomasse/Labltk/Tutoriel_FT/ I know this is still far from being a complete tutorial: a number of features are not described, explanations are a bit terse. I may try to improve it some day. Meanwhile I hope this batch of examples can be useful to other people than myself. Please warn me about any mistakes or imprecision.
Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/5293f5244e787a94#70cfd4be024478bd
Thomas Fischbacher announced:I thought I should mention this to keep people informed about large projects done in OCaml. Micromagnetism is a rather hot topic these days. There are a number of packages around that allow one to do physical simulations of sub-micron scale magnetic systems, but there is one around (ours) which is written mostly in ocaml. (The user interface is python, though.) The rationale for using ocaml was that we needed both speed and enough flexibility to do symbolic manipulations. Actually, this micromagnetism package is just a library on top of a much more generic multiphysics simulation system that was designed to deal with a very broad class of generalized reaction-diffusion systems, whose ultimate goal is to automatically compile an abstract problem specification (containing differential operators and equations of motion in symbolic form) down to some numerical finite element code. The first beta-release (still a bit wobbly) is at: http://nmag.soton.ac.ukAndrej Bauer asked and Thomas Fischbacher answered:
> I have suspected for a while that writing the computational part in > ocaml and the user interface in python is a good combination. What is > your experience? Are there any drawbacks? Would you do it again? We use a modified variant of Art (arty) Yerkes' old "pycaml" module. Essentially, I had to re-write quite a bit of it, as both reference counting on the Python side and Gc management on the OCaml side were broken. One impotant issue is that the pycaml module (which also is part of Debian) does not recognize properly that python library primitives often differ in their behaviour concerning whether they increase the reference count of a return value or not. Also, we added a lot of extra stuff and goodies which allows us to interface ML to python quite smoothly. When I call a ML-function from python, dynamic type-checking of all the arguments is automatic and generates appropriate python exceptions. Here is an example for a python-wrapped ML function that uses our extended pycaml module: let _py_raw_cvode_advance = python_pre_interfaced_function [|CamlpillType; (* the cvode *) CamlpillType; (* the result vector *) FloatType; (* target time *) IntType; (* max nr_steps, -1 for "no limit" *) |] (fun args -> let cvode = cvode_from_ocamlpill args.(0) in let FEM_field (_,_,v_result) = field_from_ocamlpill args.(1) in let target_time = pyfloat_asdouble args.(2) in let max_steps = pyint_asint args.(3) in let result_time = Sundials.cvode_advance cvode target_time v_result max_steps in pyfloat_fromdouble result_time) ;; It is nice to be able to implement other high-level python/caml interface abstractions through functional tricks -- such as a caml function constructing and accessing a higher-rank nested-list python tensor. How does it feel? If I had a need for some specific fast low-level extension to python, I would prefer using python+ocaml a thousand times over python+C. It is just so much nicer not having to worry about reference counting issues. Even if you feel you can do it right, there is always a bit of doubt. Doubly so if you are not the sole developer. I would not let our PhD students write C extensions to python, but I have no problems whatsoever letting them extend python via ocaml functions. One sort-of limitation is that we use our own python interpreter. (I.e. the main program is written in OCaml and eventually provides a python prompt or runs a python script.) This is necessary in our situation as we also want to support running in parallel under MPI control, and the MPI libraries do some nasty arg-passing things that upset an unmodified python interpreter. So, we do not load some object-code module containing all the ML runtime environment system into a standard python interpreter; technically, that should be possible as well on many platforms, but it is not relevant in our particular case here. On the other hand, of course, if one can completely avoid such inter-language interfaces, the better. In principle, both Python and OCaml are widely loved because of flexibility they both derive from LISP. So, some situations, one may be better off using e.g. the Gambit Scheme Compiler instead (which has, by the way, a terrific C interface!) It depends a lot on your constraints. If you want to build something that can be easily integrated with lots of data processing libraries that are readily available and accessible to casual programmers (engineers, physicists, etc.), providing python support seems to be a very good choice to me. It is rather popular among engineers these days, which I consider mostly a good thing. Also, if you want your PhD students to be productive at writing code that has to run fast, and if they are spoilt enough from previous exposure to imperative languages that you cannot really teach them Lisp/Scheme within a short amount of time ;-), then ocaml certainly is a very good choice. (In terms of what we teach our students about caml, this is not much more than the core ML language plus a bit about the C interface. They usually pick that up in less than 3 months. With C++, they never could be productive after such a short amount of time.) So, I would say: in an ideal computing world, we would all be expert Scheme hackers, but in the real world, python+ocaml can be an extremely productive and powerful combination. I have used and combined many systems in the past, but I would have difficulty naming anything else I played with that appeared even remotely as powerful. I know that in the longer run, we certainly should split nmag and ship our new and improved pycaml module separately (after brushing it up a bit) -- and a few other modules as well. But for now, we are busy dealing with other issues. (We are, after all, physicists studying real physical systems, so all this symbolic mumbo-jumbo in nmag/nsim is just a tool to us.)
Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/9fbd8b6b789533cb#52277cf02782bc2c
Dave Benjamin announced:I have released XmlRpc-Light 0.6. XmlRpc-Light is an XmlRpc client and server library written in OCaml. It requires Xml-Light and Ocamlnet 2. http://code.google.com/p/xmlrpc-light/ This release introduces a new module, XmlRpcDateTime, which provides a date time type (still a tuple of integers), time-zone-aware equality and comparison, XmlRpc-flavored iso-8601 parsing and generation, time zone adjustment, and conversion functions to- and from- Unix float and Unix.tm for both local and UTC times. There is also a handy "now()" function to build a time stamp for the current time. The Unix conversion functions follow the same naming convention as Julien Signoles' calendar library to ease integration with that package. I have written a suite of unit tests, based on Maas-Maarten Zeeman's oUnit framework, which you can run by typing "make test". These tests cover parsing and generation of XmlRpc values and messages, date-time parsing and arithmetic, and the server's function call and error handling behavior. The WordPress example library has been updated to support WordPress 2.3, which now provides UTC date-time values. The interface has been kept mostly the same. It now uses XmlRpcDateTime.t instead of defining a "datetime" type, but this shouldn't break any code since due to structural typing. The one thing that doesn't work the same is the "suggest_categories" method, since WordPress has completely changed the structure of its results. Rather than attempt to make any sense of the new result format, which is rather odd, I decided to punt here and just return an XmlRpc.value (variant). Finally, I have added support for the somewhat controversial "nil" type. Not all servers support this type, and Dave Winer has been known to be adamantly opposed to it, but it has become a de-facto standard and quite a few XmlRpc libraries support it now. If you don't like it, don't use it. =)
Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/1c777227f8efb204#2b201480b60a879d
Basile STARYNKEVITCH said:As some might probably know, the LLVM compiler http://llvm.org/ has (at least in its latest SVN snapshot) a binding for Ocaml. This means that one could code in Ocaml some stuff (eg a JIT-ing compiler) which uses (and links with) LLVM libraries. http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-November/011481.html http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-November/011507.html However, to generate code with LLVM for Ocamlopt, this is not enough, since while LLVM does have hooks to support garbage collection http://www.llvm.org/docs/GarbageCollection.html I don't know of any actual hooks to fit into the needs of Ocamlopt garbage colector (which AFAIK require some specific frame descriptors in the code, in some hashtables, which details are tricky and known to very few implementors, perhaps only Xavier Leroy & Damien Doligez). So is there any code to fit the Ocaml GC requirements into LLVM abilities, ie to use LLVM to generate (eg JIT) code which respect Ocaml GC requirements. Of course, I do know that there are some typing issues and theoritical points which I deliberately ignore here. I'm supposing the guy wanting to LLVM for Ocaml is knowing that he seeks trouble. And Metaocaml is (unfortunately) nearly dead: future (in ocaml 3.11 or 3.12) dynamic libraries ability is not a full replacement! Even if one might generate Ocaml code and compile & dlopen it in a future version of Ocaml.Gordon Henriksen then said:
To avoid cross-posting, my followups to this thread will be on llvmdev. http://lists.cs.uiuc.edu/pipermail/llvmdev/2007-November/011527.html
Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/8ba2204855fc5e46#5aee553df34548e2
Jon Harrop announced:I recently rediscovered the Low-Level Virtual Machine (LLVM) project that has since been adopted by Apple: http://llvm.org This is a library (with OCaml bindings!) that allows you to write a compiler that generates their RISC-like intermediate language (IL) that can then be compiled to native code. LLVM even supports JIT compilation. I went through the usual steps in trying this and was extremely impressed with the results. After only two days I was able to create an optimizing native-code compiler for a subset of CAML large enough to represent the following Fibonacci program: let rec fib n = if n <= 2 then 1 else fib(n-1) + fib(n-2) do fib 40 The compiler is written entirely in OCaml, using camlp4 for lexing and parsing, and the whole thing is only ~100 lines of code! I'll detail exactly how you can use LLVM from OCaml in a future OCaml Journal article: http://www.ffconsultancy.com/products/ocaml_journal/?ol Meanwhile here's my latest source: type expr = | Int of int | Var of string | BinOp of [ `Add | `Sub | `Leq ] * expr * expr | If of expr * expr * expr | Apply of expr * expr type defn = | LetRec of string * string * expr open Camlp4.PreCast let expr = Gram.Entry.mk "expr" let defn = Gram.Entry.mk "defn" let prog = Gram.Entry.mk "prog" EXTEND Gram expr: [ [ "if"; p = expr; "then"; t = expr; "else"; f = expr -> If(p, t, f) ] | [ e1 = expr; "<="; e2 = expr -> BinOp(`Leq, e1, e2) ] | [ e1 = expr; "+"; e2 = expr -> BinOp(`Add, e1, e2) | e1 = expr; "-"; e2 = expr -> BinOp(`Sub, e1, e2) ] | [ f = expr; x = expr -> Apply(f, x) ] | [ v = LIDENT -> Var v | n = INT -> Int(int_of_string n) | "("; e = expr; ")" -> e ] ]; defn: [ [ "let"; "rec"; f = LIDENT; x = LIDENT; "="; body = expr -> LetRec(f, x, body) ] ]; prog: [ [ defns = LIST0 defn; "do"; run = expr -> defns, run ] ]; END open Printf let program, run = try Gram.parse prog Loc.ghost (Stream.of_channel stdin) with | Loc.Exc_located(loc, e) -> printf "%s at line %d\n" (Printexc.to_string e) (Loc.start_line loc); exit 1 open Llvm let ty = i64_type let ( |> ) x f = f x type state = { fn: llvalue; blk: llbasicblock; vars: (string * llvalue) list } let bb state = builder_at_end state.blk let new_block state name = append_block name state.fn let find state v = try List.assoc v state.vars with Not_found -> eprintf "Unknown variable %s\n" v; raise Not_found let cont (v, state) dest_blk = build_br dest_blk (bb state) |> ignore; v, state let rec expr state = function | Int n -> const_int ty n, state | Var x -> find state x, state | BinOp(op, f, g) -> let f, state = expr state f in let g, state = expr state g in let build, name = match op with | `Add -> build_add, "add" | `Sub -> build_sub, "sub" | `Leq -> build_icmp Icmp_sle, "leq" in build f g name (bb state), state | If(p, t, f) -> let t_blk = new_block state "pass" in let f_blk = new_block state "fail" in let k_blk = new_block state "cont" in let cond, state = expr state p in build_cond_br cond t_blk f_blk (bb state) |> ignore; let t, state = cont (expr { state with blk = t_blk } t) k_blk in let f, state = cont (expr { state with blk = f_blk } f) k_blk in build_phi [t, t_blk; f, f_blk] "join" (bb state), state | Apply(f, arg) -> let f, state = expr state f in let arg, state = expr state arg in build_call f [|arg|] "apply" (bb state), state let defn m vars = function | LetRec(f, arg, body) -> let ty = function_type ty [| ty |] in let fn = define_function f ty m in let vars' = (arg, param fn 0) :: (f, fn) :: vars in let body, state = expr { fn = fn; blk = entry_block fn; vars = vars' } body in build_ret body (bb state) |> ignore; (f, fn) :: vars let int n = const_int ty n let main filename = let m = create_module filename in let string = pointer_type i8_type in let print = declare_function "printf" (var_arg_function_type ty [|string|]) m in let main = define_function "main" (function_type ty [| |]) m in let blk = entry_block main in let bb = builder_at_end blk in let str s = define_global "buf" (const_stringz s) m in let int_spec = build_gep (str "%d\n") [| int 0; int 0 |] "int_spec" bb in let vars = List.fold_left (defn m) [] program in let n, _ = expr { fn = main; blk = blk; vars = vars } run in build_call print [| int_spec; n |] "" bb |> ignore; build_ret (int 0) bb |> ignore; if not (Llvm_bitwriter.write_bitcode_file m filename) then exit 1; dispose_module m let () = match Sys.argv with | [|_; filename|] -> main filename | _ as a -> Printf.eprintf "Usage: %s <file>\n" a.(0) To use it, simply download and install the latest SVN version of LLVM (which even builds and installs the OCaml bindings for you!) and then do: $ ocamlc -g -dtypes -pp camlp4oof -I +camlp4 dynlink.cma camlp4lib.cma -cc g++ llvm.cma llvm_bitwriter.cma minml.ml -o minml $ ./minml run.bc <fib.ml $ llc -f run.bc -o run.s $ gcc run.s -o run $ ./run 102334155 $ You can look at the generated intermediate representation with: $ llvm-dis -f run.bc $ cat run.ll If anyone improves upon this I'd love to hear about it! :-)
Archive: http://groups.google.com/group/fa.caml/browse_frm/thread/4f8c5ef33e53a7b0#2264589aa36e105f
Jon Harrop announced:We just updated the Smoke vector graphics pages with native Mac OS X executables of all three demos: http://www.ffconsultancy.com/products/smoke_vector_graphics/?ol We'll be adding more demos and functionality to this library (including the free bytecode edition) in the new year.
Here is a quick trick to help you read this CWN if you are viewing it using vim (version 6 or greater).
:set foldmethod=expr
:set foldexpr=getline(v:lnum)=~'^=\\{78}$'?'<1':1
zM
If you know of a better way, please let me know.
If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a look at the archive or the RSS feed of the archives.
If you also wish to receive it every week by mail, you may subscribe online.