Previous week Up Next week

Hello

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

  1. P3 v. 2014-04-15d
  2. ppc64le backend
  3. llpp v18
  4. topkg
  5. React 1.0.1
  6. Opam Dependency Solving in the Cloud
  7. Obj.magic for polymorphic identifiers
  8. Other OCaml News

P3 v. 2014-04-15d

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

Tom Ridge announced:
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.
      

ppc64le backend

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

Richard Jones announced:
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
      

llpp v18

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

malc announced:
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)
      

topkg

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

Deep in this thread, Daniel Bünzli announced:
> 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.
      

React 1.0.1

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

Continuing this thread, Daniel Bünzli announced:
> 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
      

Opam Dependency Solving in the Cloud

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

Roberto Di Cosmo announced:
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 
      

Obj.magic for polymorphic identifiers

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

Romain Bardou asked:
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?
      
Jeremie Dimino replied:
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
      

Other OCaml News

From the ocamlcore planet blog:
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/
      

Old cwn

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.


Alan Schmitt