Previous week Up Next week

Hello

Here is the latest OCaml Weekly News, for the week of August 12 to 19, 2014.

  1. Best way to generate OCaml code
  2. llpp v20
  3. OPAM 1.2 public beta
  4. tgls 0.8.2
  5. Camlhighlight 3.0
  6. Unix file descriptors vs. in/out channels
  7. Other OCaml News

Best way to generate OCaml code

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-08/msg00055.html

Christoph Höger asked and Jeremie Dimino replied:
> what is the state-of-the-art way to generate (programmatically)
> and
> pretty-print a valid OCaml AST? Should I use camlp4 or is there a
> standalone-library?

Camlp4 is being deprecated and will be distributed as a separate
package starting with OCaml 4.02. You should now use the compiler
libraries which export the same AST used by the compiler [1] as well
as pretty-printers [2]. These are available through the findlib
package
compiler-libs.common. To help produce the AST you can use ppx_tools
[3].

[1] https://github.com/ocaml/ocaml/blob/trunk/parsing/parsetree.mli
[2] https://github.com/ocaml/ocaml/blob/trunk/parsing/pprintast.mli
[3] https://github.com/alainfrisch/ppx_tools
      

llpp v20

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-08/msg00061.html

av1474 announced:
New version of llpp (tagged v20) 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
 * Ability to collect garbage from history (-gc + misc/gc.py)
 * Ability to embedd into another window
 * Some more documentation tidbits
 * Internal reogranizations
 * llppac can now show fonts (either font files or something
   that local fontconfig is aware of)
 * Switched internal build system to ninja
      

OPAM 1.2 public beta

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-08/msg00063.html

Louis Gesbert announced:
On behalf of the Platform Team, I am pleased to announce the public
beta of OPAM 1.2.

See all the details on the Platform Blog announcement [1].

Any comments and feedback welcome to the platform mailing list [2]

[1] http://opam.ocaml.org/blog/opam-1-2-0-beta4/

[2] http://lists.ocaml.org/listinfo/platform
      

tgls 0.8.2

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-08/msg00064.html

Daniel Bünzli announced:
Since OpenGL 4.5 was announced on monday, I'd like to announce the
release of tgls 0.8.2 which should be available shortly in opam.

It now provides support to program with OpenGL 4.5 and OpenGL ES 3.1. Full release notes:

https://github.com/dbuenzli/tgls/blob/master/CHANGES.md

Tgls is a set of independent OCaml libraries providing thin bindings
to OpenGL Libraries. It has support for core OpenGL 3.{2,3} and
4.{0,1,2,3,4,5} and OpenGL ES 2 and 3.{0,1}.

Home page: http://erratique.ch/software/tgls

Best,

Daniel

P.S. The functions were not tested. There are 106 new entry points in OpenGL
4.5 and 68 in OpenGL ES 3.1.
      

Camlhighlight 3.0

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-08/msg00067.html

Dario Teixeira announced:
I'm happy to announce release 3.0 of Camlhighlight [1], a library offering
syntax highlighting and pretty-printing facilities for displaying code samples
in Ocsigen applications. The library works by interfacing with the library
portion of GNU Source-highlight [2], a popular application supporting the
most common programming and markup languages.

This version features a smaller dependency set, now requiring Tyxml instead of
also depending on Eliom. However, full compatibility with Eliom applications
is maintained (please see the examples shipped in the tarball).

The package should be hitting the OPAM repository soon. Eliom users should
beware that Camlhighlight requires Tyxml >= 3.2, whereas Eliom 4.0.0 requires
Tyxml < 3.2. Therefore, should you want to use Camlhighlight in an Eliom
application, you are advised to install the development version of Eliom
(please see http://ocsigen.org/install for instructions regarding Ocsigen's
development repo for OPAM).

Best regards,
Dario Teixeira

[1] http://camlhighlight.forge.ocamlcore.org/
[2] http://www.gnu.org/software/src-highlite/
      

Unix file descriptors vs. in/out channels

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-08/msg00068.html

Thomas Braibant asked:
[summary] I would like to open a file in read-write mode, and use it
(mainly) to stream a big data-structure in it and (sometime) reading
the content of this data-structure.

[problem] I am a bit puzzled w.r.t. the interplay between Pervasives
functions that operate on in/out channels and the Unix function that
operate on file descriptors. From the documentation, I assume that it
is not possible to close an (input) channel that was created using
Unix.in_channel_of_descr without closing the associated file
descriptor. Therefore, I assume that I cannot use
Unix.in_channel_of_descr and Unix.out_channel_of_descr more that once
for my file-descriptor (because otherwise, these channels would not be
reclaimed). But, is is safe to use both kind of channels?

Btw, while playing with this problem, I found the following strange
behavior: if I uncomment the second line in debug (see below), I can
read data from the input channel, while if the debug line is comment,
reading from the channel yields an End_of_file exception. Is this
expected?

let debug msg i o =
  Printf.printf "[%s] posi:%i poso:%o\n%!" msg (pos_in i) (pos_out o);
  (* Printf.printf "[%s] leni:%i leno:%o\n%!" msg (in_channel_length
i) (out_channel_length o);*)
  ()

let test =
  let open Unix in
  let fd = openfile "foo.bar" [O_RDWR; O_TRUNC; O_CREAT] 0o640 in
  Printf.printf "openfile\n%!";
  let o = out_channel_of_descr fd in
  Printf.printf "out_channel_of_descr\n%!";
  let i = in_channel_of_descr fd in
  Printf.printf "in_channel_of_descr\n%!";
  debug "1" i o;
  let _ = Printf.fprintf o "test1\n%!" in
  debug "2" i o;
  assert (write fd "test2" 0 5 = 5);
  debug "3" i o;
  let _ = input_char i  in
  debug "4" i o;
  let _ = close_out o in
  Printf.printf "closeout\n%!";
  try
    ignore (write fd "test3" 0 5);
    close fd;
    Printf.printf "success\n%!"
  with
    _ -> Printf.printf "fail\n%!"
      
Adrien Nader replied:
You cannot safely mix buffered (in/out_channel) and un-buffered
(file_descr) uses of the same underlying resource.

IIRC an in_channel or out_channel has a buffer in OCaml memory. 
If you close the underlying file_descr of an out_channel with
functions operating on file desriptors directly, it is possible that
some data will still be buffered.
If you read alternatively through file_descr and in_channel, you might
skip some data if reading with the in_channel reads more than just "n
chars" (it could read 4K for instance, I'm not completely sure).

As for using in/out_channel_of_descr more than once, I don't know
offhand: if it creates new buffers each time (likely), it will be an
issue.
      
Xavier Leroy also replied:
> [problem] I am a bit puzzled w.r.t. the interplay between Pervasives
> functions that operate on in/out channels and the Unix function that
> operate on file descriptors. From the documentation, I assume that it
> is not possible to close an (input) channel that was created using
> Unix.in_channel_of_descr without closing the associated file
> descriptor. 

Correct.

> Therefore, I assume that I cannot use
> Unix.in_channel_of_descr and Unix.out_channel_of_descr more that once
> for my file-descriptor (because otherwise, these channels would not be
> reclaimed). 

I don't quite understand your remark.  You need to close (explicitly
and at once) all in_channels and out_channels associated with your
file_descr, once you're done with it.  The first close_in/close_out
will close the underlying FD, and the others will ignore the fact that
the FD is already closed.

> But, is is safe to use both kind of channels?

Sometimes :-)  An example is Unix.open_connection, which gives you a
pair of in/out channels on the same socket.  The only caveat is that
writes on out_channels are buffered, so you need to flush explicitly
to make sure the data is actually sent over the socket.

> [summary] I would like to open a file in read-write mode, and use it
> (mainly) to stream a big data-structure in it and (sometime) reading
> the content of this data-structure.

For a file opened in RW mode, the problem is that reads through
the in_channel may not see the data written through the out_channel,
even if you religiously flush the out_channel before reading anything.
The reason is that in_channels are also buffered, and may hold stale
data corresponding to the state of the file before recent writes.  And
there is no flush operation for in_channels...

> Btw, while playing with this problem, I found the following strange
> behavior: if I uncomment the second line in debug (see below), I can
> read data from the input channel, while if the debug line is comment,
> reading from the channel yields an End_of_file exception. Is this
> expected?

This is another gotcha :-)  in_channels and out_channels maintain
(their idea of) the current position in the file.  This helps avoiding
unnecessary "lseek" operations to determine current position and
length.  However, if you share a FD between two channels, the
channels's idea of the current position is inconsistent with the
actual position of the FD.

Bottom line: for your intended application, it's better to use Unix
functions exclusively.  The trick with an (in_channel, out_channel) pair
does work pretty well for sockets, named pipes and terminals, though.
      
Thomas Braibant then asked and Xavier Leroy replied:
> Well, I was thinking about the following situation
> 
>   let open Unix in
>   let fd = openfile "foo.bar" [O_RDWR; O_TRUNC; O_CREAT] 0o640 in
>   let o = out_channel_of_descr fd in
>   let i = in_channel_of_descr fd in
>   let i2 = in_channel_of_descr fd in
>   Printf.printf "1\n%!";
>   close_in i;
>   Printf.printf "2\n%!";
>   close_in i2;
>   Printf.printf "3\n%!";
>   close_out o;
>   Printf.printf "Ok\n%!"
> 
> that raises the fatal error: exception Sys_error("Bad file
> descriptor"), and now, I do not understand your remark either :(.

I said "close all your channels at once when you're done with the
underlying file descriptor".  What you observe is that after the first
close_in, all the other channels are unusable, because the underlying
FD is closed.
      

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/.

Full Time: Software Engineer for Complex Web Applications at Emcien in Atlanta, GA:
  http://jobs.github.com/positions/69efd4de-26ff-11e4-824c-30410e3f8f2d

Camlhighlight 3.0 released:
  https://forge.ocamlcore.org/forum/forum.php?forum_id=908

OPAM 1.2.0 public beta released:
  http://ocaml.org/
      

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