Hello

Here is the latest OCaml Weekly News, for the week of April 15 to 22, 2014.

- P3 v. 2014-04-15d
- ppc64le backend
- llpp v18
- topkg
- React 1.0.1
- Opam Dependency Solving in the Cloud
- Obj.magic for polymorphic identifiers
- Other OCaml News

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-04/msg00124.html

I'm pleased to announce a new release of the P3 combinator parser library, and parser generator. It is essentially a synthesis of Earley parsing with combinator parsing. This release is not available on opam. The github url is: https://github.com/tomjridge/p3 The main features are: * handles all context free grammars * fast (when memoized) * correct (hopefully) * simple (depending on your viewpoint) * scannerless (for simplicity), or can work with an external lexer (for performance/disambiguation) * parsers implemented via combinators can be integrated easily with the core language (OCaml in this case), allowing full use of host language features eg modules etc Current example performance figures are detailed here: https://github.com/tomjridge/p3/wiki/P3#performance There is also a large real-world grammar example (the OCaml grammar) in examples/ocamlyacc. This can parse a moderately sized (279 lines) OCaml file in about 1 second. This is notable because we are using a highly ambiguous grammar: we do not use precedence or associativity restrictions, nor take advantage of shift/shift, shift/reduce conflict resolution etc. It is also worth noting that P3 is a fully-online parser, in the sense that it processes the grammar at parse time (in order to make interactive development possible). Traditional parser generators do a significant amount of work offline, when generating the parser, and so the actual work they do at parse time is potentially much reduced.

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-04/msg00128.html

In case anyone is interested, Michel Normand wrote, and Fedora is testing, a ppc64le backend for OCaml. This might also be a good time to remind readers that Fedora is using a fixed[1] arm64 backend written by Benedikt Meurer, and a ppc64 [big endian] backend written by David Woodhouse plus some fixes by me. All of these are available here: https://git.fedorahosted.org/cgit/fedora-ocaml.git Rich. [1] The fixes are for: PR#5700 http://caml.inria.fr/mantis/view.php?id=5700 PR#6283 http://caml.inria.fr/mantis/view.php?id=6283 PR#6284 http://caml.inria.fr/mantis/view.php?id=6284 plus updated config.guess/config.sub from FSF: https://git.fedorahosted.org/cgit/fedora-ocaml.git/commit/?id=26114ba365c1ef63d9605efc719f6c220ad624eb

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-04/msg00129.html

New version of llpp (tagged v18) is now available at http://repo.or.cz/w/llpp.git Blurb: llpp a graphical PDF viewer which aims to superficially resemble less(1) Changes: * Bugfixes * Synced with mupdf 1.4 * A lot of small usability tweaks * Semblance of documentation at https://wiki.archlinux.org/index.php/Llpp (Big thanks to Daan van Rossum)

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-04/msg00132.html

> That being said with an ocaml rewrite I'd abstract the thing a little > bit more to make it more DRY (I deliberately prevented myself of doing > that in sh: possible but guaranteed to become un-rereadable once you > figured out the magic invocations) This is now done and available as topkg — the trivial OCaml package builder. https://github.com/dbuenzli/topkg The approach is extensively documented which should help packagers and package developers that wish to take the same simplistic approach if it can work for them. I also made it build system independent. Feedback welcome.

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-04/msg00151.html

> In fact it's so trivial that I managed to get it wrong (signals can't > be compared structurally, it may raise). I'll do a bug fix release in > a few days react 1.0.1 has been released to fix that. Change log: https://github.com/dbuenzli/react/blob/master/CHANGES.md

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-04/msg00138.html

we are quite happy to announce that Opam dependency solving in now available in the Cloud, bringing the benefits of efficient external dependency solvers to everybody. With the steady growth in the number of Opam packages available, the need for a fast, specialised and full fledged dependency solver has started to surface : the internal heuristics may blow up [1] and the default install/upgrade strategy may be unsatisfactory [2]. Since Opam builds on technology developed in Mancoosi [3] for solving dependencies of GNU/Linux distributions, both of these issues can be easily addressed by using one of the available external solvers: they will allow you to get blazingly fast solving speed *and* offer an extensive preference language designed to let you choose the install/upgrade strategy best suited for you [4] How can you get an external solver? For Debian/Ubuntu users, it's just a matter of typing "apt-get install aspcud", and that's it (really!). On other platforms, things get hairy, though, to the point of discouraging many potential users. Now to the good news: with the help of OcamlPro [5] and the Mancoosi team, we have setup at Irill [6] a dependency solver farm that allows anybody on any platform to access the latest external solvers in a breeze. This service has been already tested internally, and seems pretty fast and stable, so we are now opening it up in beta test to the full Opam user community in order to gather feedback, and nail down any remaining issue. To use it, just follow the quite simple instructions provided here: http://cudf-solvers.irill.org/index.html Happy dependency solving to all -- Roberto [1] see for example https://github.com/ocaml/opam/issues/1056 or https://github.com/ocaml/opam/issues/685 [2] see for example https://github.com/ocaml/opam/issues/1161 or https://github.com/ocaml/opam/issues/1334 [3] http://www.mancoosi.org [4] http://opam.ocaml.org/doc/Specifying_Solver_Preferences.html [5] http://www.ocamlpro.com [6] http://www.irill.org

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-04/msg00156.html

I'm considering using Obj.magic and as the type-checker can no longer ensure type safety, I decided to come here for advice. I want to implement the trick with GADTs where you test equality of unique identifiers, and if they match this adds an equality constraint on types. I want this code to be small and well abstracted in a module so that if this module is safe, then using this module cannot cause a seg fault. Here is the signature of my module: (************************************************************************) (** Polymorphic identifiers. *) (** The type of identifiers associated to type ['a]. *) type 'a t (** Make a new, fresh identifier. This is the only way to obtain a value of type [t]. *) val fresh: unit -> 'a t (** Type constraint which is conditioned on identifier equality. *) type (_, _) equal = | Equal: ('a, 'a) equal | Different: ('a, 'b) equal (** Equality predicate. *) val equal: 'a t -> 'b t -> ('a, 'b) equal (** Convert an identifier to an integer. The integer is guaranteed to be unique for each call to {!fresh}. *) val to_int: 'a t -> int (************************************************************************) and here is the implementation: (************************************************************************) type 'a t = int let fresh = let counter = ref (-1) in fun () -> incr counter; !counter type (_, _) equal = | Equal: ('a, 'a) equal | Different: ('a, 'b) equal let equal (type a) (type b) (a: a t) (b: b t): (a, b) equal = if a = b then (Obj.magic (Equal: (a, a) equal): (a, b) equal) else Different let to_int x = x (************************************************************************) Finally, here is a test program: (************************************************************************) open Polid let () = let x = fresh () in let y = fresh () in let eq (type a) (type b) (t: a t) (u: b t) (a: a) (b: b) = match equal t u with | Equal -> if a = b then "true" else "false" | Different -> "false" in print_endline (eq x y 5 "salut"); (* false *) print_endline (eq x x 5 5); (* true *) print_endline (eq x x 5 9); (* false *) print_endline (eq y y "test" "salut"); (* false *) print_endline (eq y y "test" "test"); (* true *) print_endline (eq y x "salut" 5); (* false *) (* print_endline (eq x x 5 "salut"); (\* type error *\) *) (* print_endline (eq y y "salut" 5); (\* type error *\) *) () (************************************************************************) It relies heavily on the fact that "fresh ()" cannot be generalized as 'a t is abstract. A typical use case is as follows: I have two heterogeneous association lists (using GADTs for existential types). As I iterate on one of those lists, I need to find the corresponding item in the other list. As I unpack the existential, the type-checker cannot prove that the existential types are equal, hence the need for a runtime check (a call to Polid.equal). Can you find any reason why this would not be safe, or any better way to implement this?

We do exactly this at Jane Street in our type_equal module: https://github.com/janestreet/core_kernel/blob/master/lib/type_equal.ml#L87 Note that using the open_types branch of ocaml [1] there is a cool way to do this: (************************************************************************) type 'a key = .. type (_, _) equal = | Equal: ('a, 'a) equal | Different: ('a, 'b) equal module type S = sig type t type 'a key += T : t key end type 'a t = (module S with type t = 'a) let fresh (type a) () = let module M = struct type t = a type 'a key += T : t key end in (module M : S with type t = a) let equal (type a) (type b) (module A : S with type t = a) (module B : S with type t = b) : (a, b) equal = match A.T with | B.T -> Equal | _ -> Different let to_int = Hashtbl.hash (************************************************************************) [1] http://caml.inria.fr/mantis/view.php?id=5584

Thanks to Alp Mestan, we now include in the OCaml Weekly News the links to the recent posts from the ocamlcore planet blog at http://planet.ocaml.org/. CUFP 2014 Call for Presentations: http://cufp.org/news/2014/cufp-2014-call-presentations Coq received ACM Software System 2013 award: http://coq.inria.fr/coq-received-acm-software-system-2013-award Typeful disjunctive normal form: http://syntaxexclamation.wordpress.com/2014/04/18/547/ The 6 parameters of ('a, 'b, 'c, 'd, 'e, 'f) format6: http://gallium.inria.fr/blog/format6 Disjunctive normal forms in big steps: http://syntaxexclamation.wordpress.com/2014/04/15/big-step-disjunctive-normal-forms/

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.