Previous week Up Next week

Hello

Here is the latest OCaml Weekly News, for the week of August 18 to 25, 2015.

  1. Destructive use of file descriptors
  2. Learning about compiler-libs
  3. POSTDOC position at NOVA LINCS Lisbon (background in Programming Languages and Tools)
  4. Gg 0.9.1
  5. PhD position announcement: Mixing Unproved and Proved sub-systems through Contracts for Correct-by-Construction system design
  6. Vg 0.8.2
  7. Ocsigen releases
  8. Albatross: A Verifying Compiler v0.2
  9. Simple exception - different behaviour between toplevel and compiled
  10. Position at Wolfram Mathcore
  11. Size of .cmo / .cmi workload of the compiler
  12. Introduction to Functional Programming in OCaml
  13. Setting Pervasive's stderr to unbuffered as default?
  14. Other OCaml News

Destructive use of file descriptors

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00058.html

Goswin von Brederlow asked:
in Python one can write:

    with open("foo") as fd:
        fd.write(str)

This involves some language magic that will open the file for the
duration of the block and close it at the end. The file descriptor is
automatically closed at a know time and not leaked or left until the
GC gets around to cleaning it up.

Has anyone constructed something like that for ocaml? Maybe with a ppx
extension?
      
Nicolas Ojeda Bar replied:
No magic needed in OCaml:

let with_open path f =
let oc = open_out path in
match f oc with
| x -> close_out_noerr oc; x
| exception e -> close_out_noerr oc; raise e

and then use it as

with_open "foo" (fun oc -> output_string oc str)
      
Malcolm Matalka then said:
The weakness with this (which I'm not sure if Python offers protection)
is returning something that references the file created.  It can lead to
some confusing error messages.
      
Goswin von Brederlow then replied and Gabriel Scherer said:
> Yeah. I was thinking that that might be avoided. Something on the line
> of putting the file descriptor into a local module so ocaml would
> complain about it escaping its scope or something.

You can use the "ST monad" trick to track escape of values or effects:
  "Region-based resource management", Oleg
  http://okmij.org/ftp/Haskell/regions.html

However, this requires writing the resource-manipulating operations in
monadic style.

module ST : sig
  type ('s, 'a) st
  val return : 'a -> ('s, 'a) st
  val bind : ('a -> ('s, 'b) st) -> ('s, 'a) st -> ('s, 'b) st

  type ('s, 'a) st_ref
  val st_ref : 'a -> ('s, ('s, 'a) st_ref) st
  val get : ('s, 'a) st_ref -> ('s, 'a) st
  val set : ('s, 'a) st_ref -> 'a -> ('s, unit) st

  type 'a secretive = { run : 's . unit -> ('s, 'a) st }
  val run_st : 'a secretive -> 'a
end = struct
  type ('s, 'a) st = 'a
  let return x = x
  let bind f m = f m

  type ('s, 'a) st_ref = 'a ref
  let st_ref, get, set = ref, (!), (:=)

  type 'a secretive = { run : 's . unit -> ('s, 'a) st }
  let run_st st = st.run ()
end

let (>>=) m f = ST.bind f m



# let test =
    ST.run_st { ST.run = fun () ->
      ST.st_ref 1 >>= fun r ->
      ST.get r >>= fun before ->
      ST.set r 2 >>= fun () ->
      ST.get r >>= fun after ->
      ST.return (before + after)
    };;
val test : int = 3

# let test_escape_1 =
    ST.run_st { ST.run = fun () ->
      ST.st_ref 1 >>= fun r ->
      ST.return r
    };;
Error: This field value has type unit -> ('a, ('a, int) ST.st_ref) ST.st
  which is less general than 'b. unit -> ('b, 'c) ST.st

# let test_escape_2 =
    let hole = ref None in
    ST.run_st { ST.run = fun () ->
      ST.st_ref 1 >>= fun r ->
      hole := Some r;
      ST.return ()
    };
    !hole;;
Error: This field value has type unit -> ('a, unit) ST.st
  which is less general than 'b. unit -> ('b, 'c) ST.st
      
Ben Millwood then added:
See also the following thread last year, "Not letting channels escape", which
(after some incomplete attempts from me) illustrates a fully safe with_file
function.

https://sympa.inria.fr/sympa/arc/caml-list/2014-08/msg00024.html
      
Gabriel Scherer also replied to the original question:
Many libraries provide a with_file_{in,out} function capturing this
pattern, without need for specific language support.

  BatFile.with_file_out "foo" (fun fd ->
    print_endline str
  )
      

Learning about compiler-libs

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

Leonid Rozenberg asked:
Are there any resources besides the couple of blog posts and reading the
source?

I found this surprising:

OCaml version 4.02.1

# #use "topfind" ;;
- : unit = ()
Findlib has been successfully loaded. Additional directives:
#require "package";; to load a package
#list;; to list the available packages
#camlp4o;; to load camlp4 (standard syntax)
#camlp4r;; to load camlp4 (revised syntax)
#predicates "p,q,...";; to set these predicates
Topfind.reset();; to force that packages will be reloaded
#thread;; to enable threads

- : unit = ()
# #require "compiler-libs.toplevel" ;;
/Users/leonidrozenberg/.opam/4.02.1/lib/ocaml/compiler-libs: added to search
path
/Users/leonidrozenberg/.opam/4.02.1/lib/ocaml/compiler-libs/ocamlcommon.cma:
loaded
/Users/leonidrozenberg/.opam/4.02.1/lib/ocaml/compiler-libs/ocamlbytecomp.cma:
loaded
/Users/leonidrozenberg/.opam/4.02.1/lib/ocaml/compiler-libs/ocamltoplevel.cma:
loaded
# let a x = x + 1 ;;
>> Fatal error: a unbound at toplevel
Fatal error: exception Misc.Fatal_error
      
Gabriel Scherer replied:
The short answer is: no, there is no documentation.

The long answer: compiler-libs was made available following the demand of
expert users, that were already familiar with the compiler codebase, willing
to reuse its internals to develop tooling around the language. Nobody had the
time back then to contribute a comprehensive documentation, or even to define
a reasonable API subset to expose (so basically everything is exposed).
Finally, there is no guarantee of API compatibility across OCaml versions, so
reusing this makes you tightly coupled to the compiler evolution.

Documentation emerges slowly under the form of blog posts, discussions, and
evolution of the codebase. In particular, over the course of his work on -ppx,
Alain Frisch enriched parsing/parsetree.mli with invaluable comments
describing the mapping between concrete and abstract syntax. Everyone is
warmly welcome to contribute such improvements to the (codebase)
documentation.
      

POSTDOC position at NOVA LINCS Lisbon (background in Programming Languages and Tools)

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00084.html

Luis Caires announced:
We would like to announce a post doc / research associate position at
NOVA Laboratory for Computer Science and Informatics (Lisbon) for
candidates with a strong background in topics such as programming
languages, programming language design and implementation, software
verification, and program analysis. The successful candidate will join
a just launched project on new programming models, incremental
verification techniques, and programming environments for the
interactive / live construction of trustworthy web/cloud applications.

Please contact me (lcaires(at)fct.unl.pt) for additional information
about the position and project. More information at:

http://nova-lincs.di.fct.unl.pt/open-positions/position-4
      

Gg 0.9.1

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00094.html

Daniel Bünzli announced:
Gg 0.9.1 has been released. This is a bugfix release. 

See the release notes:

  https://github.com/dbuenzli/gg/blob/v0.9.1/CHANGES.md#v091-2015-08-14-cambridge-uk

Gg provides basic types for computer graphics in OCaml. It is distributed
under a BSD3 license.

Homepage: http://erratique.ch/software/gg
API documentation: http://erratique.ch/software/gg/doc/Gg
      

PhD position announcement: Mixing Unproved and Proved sub-systems through Contracts for Correct-by-Construction system design

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00095.html

David Mentré announced:
CEA LIST and Mitsubishi Electric R&D Centre Europe are opening a fully funded
PhD position titled "Mixing Unproved and Proved sub-systems through Contracts
for Correct-by-Construction system design".

Position details are available here:


http://www.fr.mitsubishielectric-rce.eu/images/fck_upload/1507_Annonce_Formal%20methods_PhD_201510_EN.pdf

This PhD position is not strictly related to OCaml, but all formal related
software at CEA LIST and MERCE are written in OCaml so it would most probably
be used for the PhD work.

Do not hesitate to ask questions if needed. Feel free to forward this position
to relevant forums.
      

Vg 0.8.2

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00099.html

Daniel Bünzli announced:
Vg 0.8.2 has been released and will soon be available in opam.

Thanks to Arthur Wendling's work (and patience with me to merge), this release
brings us an initial Cairo [1] backend via the cairo2 bindings [2].

It allows to use Vg with gtk applications or any cairo context you are able to
get a handle on. This notably brings rendering to raster memory buffers and
offline PNG and PS file generation to Vg. It also provide redundant PDF and
SVG file generation but Vg's own pure OCaml renderers are much faster for
that.

Vg's online image database [3] has eventually been fixed so that the many
people that are on Linux using Firefox should no longer witness obscure (au
propre comme au figuré) stack overflows.

The full release notes are here:

  https://github.com/dbuenzli/vg/blob/v0.8.2/CHANGES.md#v082-2015-08-14-cambridge-uk

Vg brings declarative 2D vector graphics to OCaml. It is distributed under a BSD3 license.  

Homepage: http://erratique.ch/software/vg
API documentation: http://erratique.ch/software/vg/doc/

Best,

Daniel

P.S. The Cairo backend glyph API is a bit underpowered at the moment. If you
are interested in improving this, get in touch on
https://github.com/dbuenzli/vg/issues/9

P.P.S. `-safe-string` support means that Vg 0.8.2 is > OCaml 4.02.0 only. It
turns out that the bytes compatibility package is not really sufficient for
basic use cases, e.g. you don't get the bytes related functions in the
`Buffer` module.

[1] http://cairographics.org/  
[2] http://cairo.forge.ocamlcore.org/tutorial/
[3] http://erratique.ch/software/vg/demos/rhtmlc
      

Ocsigen releases

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00104.html

Drup announced:
We are happy to announce the releases of

- Eliom 4.2
- Server 2.6
- js_of_ocaml 2.6
- TyXML 3.5

We also welcome a new member in the ocsigen team, Vasilis Papavasileiou.

Key changes in the various releases:

- PPX support for js_of_ocaml with OCaml >= 4.02.2
  See documentation here.

  This was also the occasion to introduce a new syntax for object
  literals, and to improve the Camlp4 syntax (w.r.t. to
  locations). Both syntaxes emit the same code, and are perfectly
  compatible.

- Support for dynlink in js_of_ocaml.

- Logging improvements in Eliom and Server, in particular on
  the client side.

- A healthy amount of bugfixes.


The next releases will probably see major changes. The current plan
is:

- Replace Server's internals with cohttp, as part of our
  move towards Mirage-compatible libraries.

- Shared_react, which allows to build reactive pages from server side.

- PPX for Eliom.

- Support for async/core in js_of_ocaml.

 Have fun with Ocsigen!
      

Albatross: A Verifying Compiler v0.2

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00109.html

Helmut Brandl announced:
I am pleased to announce version 0.2 of the Albatross compiler.

The Albatross compiler suite is written in ocaml v4.0.

What is Albatross?

- A programming language with static verification.

- A theorem prover and a proof assistant.

http://albatross-lang.sourceforge.net

New features of version 0.2:
- Inductive Data Types
- Recursive Functions
- Proofs by Induction
- A lot of examples in the updated documentation
(http://albatross-lang.sourceforge.net/doc/language_description/albatross.pdf)
covering boolean logic, predicate logic, recursion and induction.
      

Simple exception - different behaviour between toplevel and compiled

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00121.html

Oliver Bandel announced:
using the attached files (executing testexc,bash)
I got different results between toplevel and compiled:

=====================================================
Testcase A
exception A of int * int
let _ = raise ( A(3,4) )
Exception: A (3, 4).
Fatal error: exception Exca.A(3, 4)
Fatal error: exception Exca.A(3, 4)
Testcase B
exception B of (int*int)
let _ = raise ( B(3,4) )
Exception: B (3, 4).
Fatal error: exception Excb.B(_)
Fatal error: exception Excb.B(_)
=====================================================

So just adding parantheses in a definition of an exception
yields in these differing results, with not-shown exception-values.

IMHO looks like a case for the bugtracker...

OCaml version is 4.02.1

exca.ml:
exception A of int * int
let _ = raise ( A(3,4) )

excb.ml:
exception B of (int*int)
let _ = raise ( B(3,4) )

testexc.bash:
echo Testcase A
FILE=exca.ml
cat    $FILE
ocaml  $FILE
ocamlc $FILE
./a.out
ocamlopt $FILE
./a.out
      
Arthur Wendling replied:
> exception A of int * int

This is an exception with two arguments.

> exception B of (int*int)

This is an exception with a single argument, which is a product of two values.
So the parenthesis actually matters:

# fun x -> A x ;;
Error: The constructor A expects 2 argument(s),
but is applied here to 1 argument(s)
# fun x -> B x ;;
- : int * int -> exn = <fun>

I agree that the syntax is a bit surprising, since we are used to ignore extra
parenthesis.

Anyway, now, regarding the output of the interpreter/compiler:
- A of int * int is printable by both, because the runtime can guess that the
two arguments are integers (because they aren't pointers.)
- B of (int * int) is only printed correctly by the interpreter, because it
keeps the source information. The compiler erases all that, so the runtime
only sees a single argument, that contains two ints, but it doesn't know how
to display it: it could be something else than a tuple from the point of view
of the user (like a record { x : int ; y : int }, but the names x,y have been
forgotten, so the runtime representation is identical to (int * int)).
      
Gabriel Scherer then said:
To Arthur's excellent answer, one can add that you can register
user-defined exception printers to batch programs (this does not
affect the toplevel):

$ cat test.ml
exception Foo of (int * int)

let () = Printexc.register_printer (function
  | Foo (a, b) ->
    Some (Printf.sprintf "Foo (%d, %d), with best regards" a b)
  | _ -> None
)

let v = (1, 2)
let () = raise (Foo v)

$ ocamlc -o test test.ml && ./test
Fatal error: exception Foo (1, 2), with best regards
      

Position at Wolfram Mathcore

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00131.html

Leonardo Laguna Ruiz announced:
This position may be interesting for Ocaml programmers.

Find the full description at: http://www.mathcore.com/company/careers.php

Software Engineer for Wolfram SystemModeler

Do you have a passion for compiler technology, math, and mathematical
modeling, and would like to exercise those skills while developing
world-leading modeling and simulation software? In that case, look no
further..

As a software engineer at Wolfram Mathcore, you will work mainly at our office
in Linköping, Sweden, on the development of the SystemModeler kernel. The main
function of the kernel is to translate models defined in the Modelica language
into executable simulation code.

Function and responsibilities

You will work in a team with responsibilities ranging from algorithm and user
interface design to testing. As a kernel developer your main responsibility is
maintaining existing code and implementing new features of the SystemModeler
kernel. This involves the following tasks, with OCaml used as the main
language for kernel development:

* Parsing and transforming representations of Modelica code
* Mathematical processing of equations
* Code generation of C/C++ simulation code
* Numerical runtime computations
      

Size of .cmo / .cmi workload of the compiler

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00132.html

Christoph Höger announced:
I autogenerate a rather large (> 12k) set of ocaml modules containing
classes which are parameterized over their final representation to allow
for hierarchic classes with polymorphic open recursion.

My compilation scheme seems to work well in principle, but I am reaching
a frustrating limit in practice: The compilation of the generated ml
files seems to run superlinear (in fact it seems to depend on the
hierarchical location of a class). As it turns out, the generated .cmo
and .cmi files are quite large (up to several hundreds of kb). When I
generate the .mli files or dump the .cmo files however, the output is
quite small (several hundred instructions in the bytecode, the .mli file
contains quite complex objects but still human readable).

Is there any known issue that leads to:

1. non-linear runtime when compiling inter-module classes
2. huge .cmo files outside of the actual bytecode

The generated source code can be found here:

https://www.dropbox.com/s/cllc0xikv9zwu1k/doesnotscale.tar.bz2?dl=0

To test the behavior, unpack and run

ocamlbuild ModelicaXX5FElectricalXX5FMachines.cmo

(there might be type-errors in the generated files somewhere, though).

Any advice or comments are deeply appreciated.
      
Fabrice Le Fessant then replied:
One possible explanation: object types are almost always expansed in
the .cmi files (and probably in the debug section of .cmo files), and
all the more if all the classes are defined in different .cmi files
(since each type is loaded from a different file, there is no
in-memory sharing when the same type appears in two different
modules).

When we created the Try-OCaml site for Js-of-OCaml
(https://try.ocamlpro.com/js_of_ocaml/), we ran in the same problem,
because js-of-ocaml uses object types for most values, and so the .cmi
files that were loaded were much bigger than for the original
Try-OCaml site (something like 12 MB instead of 1 MB to load the
toplevel). We ended up writting a compressor of .cmi files.

If you are using 4.01.0, you can download a bytecode image of that
compressor in the former repository of try-ocaml:

https://github.com/OCamlPro/tryocaml/tree/master/toplevellib/toplevellib-4.01.0

and then, you can test it on one of your .cmi files to see if it can
compress these files (for Try-OCaml, the image decreased from 12 MB to
2 MB if I remember correctly). Then, you could run it automatically on
each .cmi files after it has been generated by ocamlc, if it is indeed
the source of the problem.
      

Introduction to Functional Programming in OCaml

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00140.html

Habet MS announced:
pleased to announce the publication of an OCaml book (in French) : 
title: Initiation à la programmation fonctionnelle en OCaml
author: HABET Mohammed-Said 
edit: Edilivre, 2015

For more informations:
http://www.edilivre.com/initiation-a-la-programmation-fonctionnelle-en-ocaml-mohammed-said-habet.html
      

Setting Pervasive's stderr to unbuffered as default?

Archive: https://sympa.inria.fr/sympa/arc/caml-list/2015-08/msg00160.html

Oliver Bandel asked:
stderr on Unix is unbuffered by default.

In OCaml, all the Channels from Pervasives are buffered by default,
and flush-function must be used.
This issue is annoying me since ages...

Is there a way to set Unix-like-behaviour (unbuffered stderr =>  unbuffered
Pervasives.stderr)
as default?

Something like setbuf(3) / setvbuf(3) for OCaml's pervasives?

Would a feature-wish for this feature have any chance of success?
      
Gerd Stolpmann then said:
I cannot follow. Pervasives.stderr is unbuffered; however (see
pervasives.ml):

let print_endline s =
  output_string stdout s; output_char stdout '\n'; flush stdout
let print_newline () = output_char stdout '\n'; flush stdout

let prerr_endline s =
  output_string stderr s; output_char stderr '\n'; flush stderr
let prerr_newline () = output_char stderr '\n'; flush stderr

So far I know these are the only functions doing an implicit flush, and
they are doing it for both stdout and stderr.
      
Xavier Leroy then replied:
Just to avoid possible misunderstandings:

- All Pervasives.out_channel are buffered.  There is no such thing
  as an unbuffered out_channel.
- A few "print" functions from Pervasive flush explicitly when
  printing a newline (because those functions are often used for
  interactive I/O).
- The "%!" modifier for printf also forces a flush.

Hope it's clearer now.
      

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

OCaml Labs compiler hacking: Tenth OCaml compiler hacking evening and OCaml/ML talks
  http://ocamllabs.github.com/compiler-hacking/2015/08/20/mini-workshop.html

Jane Street: No (functional) experience required
  https://blogs.janestreet.com/no-functional-experience-required/

Functional Jobs: Haskell Engineer at Wagon (Full-time)
  http://functionaljobs.com/jobs/8857-haskell-engineer-at-wagon

OCamlCore Forge Projects: stdint
  https://forge.ocamlcore.org/projects/stdint/

Dario Teixeira: Announcing Lambdoc 1.0-beta4
  http://nleyten.com/post/2015/08/17/Announcing-Lambdoc-1.0-beta4

GaGallium: Merging OCaml patches
  http://gallium.inria.fr/blog/merging-ocaml-patches

Andrej Bauer: Provably considered harmful
  http://math.andrej.com/2015/08/05/provably-considered-harmful/

OCamlCore Forge News: Release of OCaml-bitcoin 2.0
  https://forge.ocamlcore.org/forum/forum.php?forum_id=926

Functional Jobs: Software Engineer, OCaml at Pegged Software (Full-time)
  http://functionaljobs.com/jobs/8854-software-engineer-ocaml-at-pegged-software

Github OCaml jobs: Full Time: Software Developer (Functional Programming) at
Jane Street in New York, NY; London, UK; Hong Kong
  http://jobs.github.com/positions/0a9333c4-71da-11e0-9ac7-692793c00b45
      

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