Hello
Here is the latest Caml Weekly News, for the week of November 23 to 30, 2010.
Archive: http://groups.google.com/group/fa.caml/browse_thread/thread/4f5b086a068ed1bd#
Thomas Gazagnaire announced:I am happy to announce the first official release of HTCaML[1] and CaSS[2], two small libraries which make the writing of static web pages easy in OCaml. HTCaML enables the embedding of XHTML fragments in your OCaml program (the EDSL translates directly to Xmlm) using quotations. It also allows you to auto-generate boilerplate XHTML fragments from type definitions. In the same way, CaSS enables the embedding of CSS fragments in your OCaml program using quotations. A quick example: module Box = struct type t = { title: string; date: string; contents: Html.t } with html let css fg bg = <:css< color: $fg$; background-color: $bg$; $Css.rounded$; .title { color: $bg$; background-color: $fg$; } >> end let my_html boxes = Html.to_string <:html< <html> <body> <div class="boxes"> $list:List.map Box.html_of_t boxes$ </div> </body> </html> >> let my_css = Css.to_string <:css< .boxes { $Box.css <:css< blue >> <:css< white >> $ } >> You can find a quick introduction to HTCaML (and maybe soon to CaSS) on the mirage blog[3]. Cheers, Thomas [1] https://github.com/samoht/htcaml [2] https://github.com/samoht/cass [3] http://www.openmirage.org/blog/introduction-to-htcamlGerd Stolpmann asked and Thomas Gazagnaire replied:
> Have you seen that there is a preprocessor for PXP that allows you to > embed XML in ocaml? > > http://projects.camlcity.org/projects/dl/pxp-1.2.1/doc/manual/html/ref/Intro_preprocessor.html No, I didn't know about that. And there is also a syntax extension in Eliom to do the same kind of things. However, the two things I am really happy with HTCaML (and apparently it is not possible to do the same thing in PXP nor Eliom) are : i) you can easily mix auto-generated and hand-crafted code to create XHTML fragments (no more tedious conversion functions); and ii) you can write in the same part of your file (ie. in the same module) the css and xhtml generator for a given type definition. That means that you can do web-programming as you are used to : think about type definitions first, and then write your code to reason by induction on these defintions. for example, you can have: type foo = (* some random type *) let html_of_foo : foo -> Html.t = (* some random code of type Html.t = (`a Xml.frag as `a) Xmlm.frag list *) let foo_css = (* some random, possibly nested, CSS *) and : type bar = { foo : foo; complex types } with html let bar_css = <:css< .foo { $foo_css$; ... } >> In the later case, you don't have to write manually the code for html_of_bar as it will be done automatically by HTCaML, by looking at the structure of bar; and it will pick your own definition of html_of_foo. Also, nested declarations in bar_css will be automatically unrolled to generate valid CSS fragments. > I'm happily using this for dynamic web pages. The syntax is more > light-weight, though, e.g. you write > > <div> [ ... ] > > instead of <div>...</div>, and there is a distinction in the syntax > between node and list of nodes, e.g. > > <div> list > > but > > <div> [ node1 node2 ... ] I don't really call this dynamic web pages, but yea, that's the same idea :-)
Archive: http://groups.google.com/group/fa.caml/browse_thread/thread/15f9b2b19dfe1f22#
Gerd Stolpmann announced:A new version of ocamlnet (3.1) is ready for download and installation. This is mostly a bug fix release (see ChangeLog), but there is also a little extension in Netsys_mem: a function that creates a deep copy of an arbitrary value (copy_value). Download: http://download.camlcity.org/download/ocamlnet-3.1.tar.gz Manual: http://projects.camlcity.org/projects/dl/ocamlnet-3.1/doc/html-main/index.html Please report problems to gerd@gerd-stolpmann.de GODI users: ocamlnet-3.1 is only provided for Ocaml 3.12, and in the ocamlnet3 overlay for Ocaml 3.11.
Archive: http://groups.google.com/group/fa.caml/browse_thread/thread/2faf94e3f0ad193a#
Thomas Moniot announced:I'm happy to announce a new release of MLcov, a code coverage tool for OCaml programs. The principle is pretty simple: 1. instrument your source code 2. run tests 3. generate HTML reports to analyze the code coverage. More specifically, MLcov allows measuring MC/DC, the criterion used in the DO-178B standard to ensure that safety-critical software is tested adequately. The tool is actually used by Esterel Technologies as a verification tool for the certification of a DO-178B level A code generator written in Objective Caml. It currently works only on a subset of OCaml (core + module language) which is yet sufficient to instrument large programs, like the OCaml compiler for instance. The new version is mainly a port to OCaml 3.12.0, but also adds (experimental) support for labels and optional arguments. More information on the website: http://www.algo-prog.info/mlcov/
Archive: http://groups.google.com/group/fa.caml/browse_thread/thread/c2fca4cc9e42d78d#
Deep in this 100+ messages thread, Gerd Stolpmann said:Don't know what Fabrice is referring to, but at least I work on a multicore-enabling library: https://godirepo.camlcity.org/svn/lib-ocamlnet2/trunk/code/src/netmulticore/ This is work in progress and highly experimental. What's currently available: - managing processes and resources like files, shared memory objects etc. - support for message passing via Netcamlbox (another library) - low-level only so far: shared memory, including copying Ocaml values to and from shm - low-level only so far: kernel semaphores - a Netmulticore process is also a Netplex container, so mixing with Netplex-managed servers is possible. Also, the Netplex plugins are available (semaphores, mutexes, global variables), but these are relatively slow I've also written a few examples: https://godirepo.camlcity.org/svn/lib-ocamlnet2/trunk/code/examples/multicore/ Don't expect wonders, though. For instance, the port of the chameneos game is based on message passing, but this is by design slower than direct use of shared memory (and this game mostly consists of synchronization, and there is not any computation involved where multicore would be an advantage). The further direction is the addition of more primitives, especially for managing shared memory. The difficult here is that there is not any support in the core language, and I have to work around that. This is based on val Netsys_mem.init_value ?targetaddr:nativeint -> ?target_custom_ops:(string * custom_ops) list -> memory -> int -> 'a -> init_value_flag list -> (int * int) where type memory = (char,Bigarray.int8_unsigned_elt,Bigarray.c_layout) Bigarray.Array1.t This means shared memory is handled just as a bigarray of chars that is mapped into the address spaces of several processes. The init_value function copies an arbitrary Ocaml value to such a bigarray - in the same way as Marshal.to_string - only that it is "to_bigarray", and that the same representation is used as for normal values (so you can access the copied values directly). This copying is quite time-consuming: you have to create the Ocaml value in normal memory first, and then to use a quite expensive generic copying machinery to get it to shared memory. It would be more elegant if there was a way to instruct ocamlopt so that code is emitted that creates the value directly in a user-supplied memory area. The arguments targetaddr and target_custom_ops point to another difficulty: For certain uses of shared memory you cannot ensure that all processes map the area to the same address. Because of this, there is support for filling bigarrays so that the addresses are offset for a different final mapping address. Netcamlbox uses this feature - the sending process can map the shared bigarray to any address, and nevertheless format a message with addresses that are right for the receiving process. In general, shared memory is difficult to add in an add-on library. However, some lessons can be learned, and maybe this results in some "plot" for adding better support in the core language.
Archive: http://groups.google.com/group/fa.caml/browse_thread/thread/3ab9a82a174d0aa0#
Martin DeMello asked:What are the actively developed options for writing desktop GUI apps in OCaml? Anything other than lablgtk2 (which, at least from a brief look through the examples, looks rather ugly, codewise, compared to, say, vala or ruby/gtk)? I'll use lablgtk2 in a pinch, but I'm curious as to whether anyone has been experimenting with toolkit bindings with an eye towards better syntax and APIs. (Note that I don't care about a native look and feel, I'm more interested in how the code looks.)Jacques Garrigue:
I'm not sure which examples you looked at for lablgtk2. The goals of lablgtk are: * be as close as possible to the spirit of Gtk+ * while providing type and memory safety * and allow comfortable use through objects and optional arguments This resulted in a 2-layer implementation, with a lower layer that just wraps basic Gtk+ calls, and an object layer on top of it. Some examples mix the two layers, which may look strange, but I think that when you use only the upper layer, this is clean enough. (The lower layer is not dirty, but converting between the two may be verbose and look clumsy). The obvious alternative to lablgtk2 is of course labltk. I personally think that labltk is still the easiest way to build a GUI, but many do not like Tk's look&feel. I'm not aware of other GUI toolkits for ocaml, but I think there are also web-based UIs.Martin DeMello then asked and Michael Ekstrand replied:
> That might be the problem, then. I was looking at the examples in the > translation of the gtk tutorial, and a lot of it seemed like C code > translated to OCaml. Could you point me to some example of code > written using the high level API? The LablGTK tutorial I am aware of[1] uses the high-level API. The high-level API isn't notably higher-level than the base API in terms of what calls are necessary, but it wraps everything up in objects and makes the data structures nicer. The API call sequences are roughly the same. - Michael 1. http://wwwfun.kurims.kyoto-u.ac.jp/soft/olabl/lablgtk.htmlYoann Padioleau then suggested:
In https://github.com/facebook/pfff/blob/master/commons/gui.ml I've modified slightly the lablgtk API to be more compositional.Alain Frisch suggested:
If you're under Windows, you might be interested in the CSML tool. It allows you to build quite easily your own binding to .Net libraries. The CSML distribution contains an example of a mini-binding to Windows Forms; you can also see that in screenshots: http://www.lexifi.com/csml LexiFi uses CSML to build Windows Forms application, but most of our GUIs are managed by a higher-level layer, not direct calls to Windows Forms. As a matter of fact, we generate most of the GUIs that are intended to show or edit structured values, automatically from OCaml type definitions. We have a few local extensions to the OCaml compiler that makes it easier to build nice APIs for GUI toolkits, with a functional flavor: implicit subtyping and generalized recursion. Hopefully, I'll be able to blog about these extensions and how they are used for GUI programming some day.Martin DeMello then asked and Alain Frisch replied:
> No, I'm on linux, but CSML does look very interesting. Does it work > well with Mono? Yes, CSML itself has been adapted to work with Mono and I did a few tests (some of screenshots show Windows Forms GUIs controlled by OCaml code, under Linux with Mono). External users reported successful uses as well. At some point, we tried to run our main application under Mono (the application is mostly OCaml, plus a very small amount of C#, and a lot of CSML to make big parts of .Net libraries available to OCaml). We quickly realized that some widgets which we use a lot in our application simply don't work very well under Mono. For instance, the WebBrowser control is quite broken under Mono. This really has nothing to do with CSML, it's just that relying on Mono only to get nice GUIs under Linux might not be optimal. > I'd love to read that when you do. I was surprised not to see much > interest in GUI DSLs in OCaml. What is generalised recursion? Being able to write things like: lazy let rec button1 = button ~click:(fun () -> button2 # disable) "Button1" and button2 = button ~click:(fun () -> button1 # disable) "Button2" in ... As the lazy keyword suggests, we rely on lazy evaluation to evaluate such recursive definitions. The code above is equivalent to: let rec button1 = lazy (button ~click:(fun () -> (Lazy.force button2) # disable) "Button1") and button2 = lazy (button ~click:(fun () -> (Lazy.force button1) # disable) "Button2" in ... (also replacing any instance of button1, resp. button2 in ... by Lazy.force button1, resp. Lazy.force button1). The little extension makes it easier to define in a single big recursive definition several widgets with associated callbacks and mutual interactions. Without the feature, the natural thing to do is to create widgets first and then bind events, which looks less functional (and less local).Hezekiah M. Carty also suggested:
It's not complete or a full-blown DSL, but I started a small Gtk-light module a while ago. I haven't had the time to complete it, but it shouldn't be too difficult to modify for your needs: http://0ok.org/cgit/cgit.cgi/gtk-light/ Here is a brief example (uses the "open Module in" syntax extension): http://0ok.org/cgit/cgit.cgi/gtk-light/tree/basic_gui_test.ml With OCaml 3.12 the "open Module in" could be replaced by the new "let open Module in" or Module.(...) syntax.bluestorm then said and Hezekiah M. Carty replied:
> There was also a project by Chris King to develop a GUI based on lablgtk in > a Functional Reactive Programming style. > http://lambda-the-ultimate.org/node/1918 Chris King's project was a major influence in the syntax I chose. I started trying to mix in some FRP with the React module, but never completed the work. I moved Gtk-light to the forge if anyone is interested in working with the code: http://gtk-light.forge.ocamlcore.org/ Thanks to the thelema folks for allowing me to use some of the Batteries code for the index page.Adrien Nader also suggested:
As Jacques said, lablgtk's api is close to gtk's one. I also believe that was the best solution/approach. Binding that many C functions to ocaml is already hard enough (not that it could be made easier, the difficulty lies in the number of functions). The drawback is of course that writing code using lablgtk is almost as verbose as writing it directly in C with gtk. Something nice would probably be to share more extensions and wrappers around lablgtk. I've noticed Maxence Guesdon had made some available as stand-alone libraries but I'm not aware of others. Or maybe they're scattered around and it's hard to find them. As far as I'm concerned I've started experimenting with the concept of "tiling" (as used by tiling window managers) and zippers of horizontal and vertical boxes. That's pretty much what xmonad (window manager written in haskell) does. The zipper allows to nicely track the "current" widget. Next in my plans is a wrapper around treeviews/listviews and gtknotebook to map a set of widgets to a list or tabs. And, a last (long) point, a few months ago, I asked on this list about lablgtk and FRP; I ended up doing something myself. It turned out that my "lablgtk-react" is something like 50 lines of code. It's really small and there wasn't much work, once you knew the guts of lablgtk and gtk that is. GTK defines properties and signals. Signals are regular "something happened"-messages and properties are values stored inside objets. Each property also defines a "${prop_name}::notify" signal that is emitted each time the property is modified. This is unfortunately not exposed through lablgtk but the connect_by_name function is enough. Now, you may wonder whether FRP is *that* nice to use. One of the nicest thing imho is the ability to use "fold": let zipper = React.E.fold (zipper x config t) Zipper.empty tabs in This means it's possible to move away from imperative data structures with all their disadvantages. There is currently one issue however: the API is quite bad. install_sgn_event Entry.S.activate address_bar.as_e Signal.apply1 address_bar.activate (* Entry.S.activate is emitted by a text entry upon pressing Return * address_bar.as_e(ntry) returns the 'Gtk.entry Gtk.obj' because * its's not possible (yet) to use the object layer here * address_bar.activate is a potential previous signal handler for * active, we'd uninstall it before install another one *) Ideally, it'll become something like: address_bar#react#activate#event If you want to have a look at the module, I've put it on vpaste.net[1]. It's a bit old and several things have been changed but it still shows how things are done. [1] http://vpaste.net/Vrukn?
Archive: http://groups.google.com/group/fa.caml/browse_thread/thread/6aff6222b6f0cdb8#
Benedikt Meurer announced:I did some final work on OCamlJIT2, and compared the result to OCamlJIT. The performance measures are presented in the following tech report (skip straight to section 4 for the performance results): http://arxiv.org/abs/1011.6223 In short: Performance measured on a P4 "Northwood" (no long mode, plain x86) 2.4GHz. OCamlJIT2 beats OCamlJIT by a factor of 1.1 to 2.0 in every benchmark, and - rather surprising - was even able to beat ocamlopt in the number crunching benchmark (probably an issue with the x86 backend of ocamlopt). As mentioned by Xavier Leroy and others previously, we probably went as far as we could go in the direction of JITting the byte-code virtual machine, while preserving its general stack-based nature and instruction set. Moving even further means translating the byte-code to some intermediate form suitable for use with standard compilation techniques; but as we saw earlier, in an LLVM-based prototype, the compilation overhead increases dramatically and the benefit of JIT compilation vanishes. Therefore, as suggested earlier, I'll try to get my hands on the native top-level now (already contacted Alain for the emitter code). Additionally, the linear scan register allocation will be implemented by a student as part of his diploma thesis.
Thanks to Alp Mestan, we now include in the Caml Weekly News the links to the recent posts from the ocamlcore planet blog at http://planet.ocamlcore.org/. Gtk-light: https://forge.ocamlcore.org/projects/gtk-light/ Still here...: http://gaiustech.wordpress.com/2010/11/25/still-here/ OCaml extensions at LexiFi: overidding record labels and constructors: http://www.lexifi.com/blog/ocaml-extensions-lexifi-overidding-record-labels-and-constructors Three uses for a binary heap: http://ambassadortothecomputers.blogspot.com/2010/11/three-uses-for-binary-heap.html libguestfs examples in C, OCaml, Python and Ruby: http://rwmj.wordpress.com/2010/11/24/libguestfs-examples-in-c-ocaml-python-and-ruby/ CaSS: http://caml.inria.fr/cgi-bin/hump.cgi?contrib=751 Htcaml: http://caml.inria.fr/cgi-bin/hump.cgi?contrib=750
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.