Hello
Here is the latest OCaml Weekly News, for the week of March 04 to 11, 2014.
Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-03/msg00031.html
Ben Millwood announced:I am pleased to announce the 111.03.00 release of the Core suite. The following packages were upgraded: - async - async_extra - async_kernel - async_unix - bin_prot - core - core_extended - core_kernel - custom_printf - jenga - ocaml_plugin - re2 - sexplib - textutils In addition, with this release we are including a new package: - enumerate, a syntax extension for enumerating finite types. Files and documentation for this release are available on our website and all packages are in opam: https://ocaml.janestreet.com/ocaml-core/111.03.00/individual/ https://ocaml.janestreet.com/ocaml-core/111.03.00/doc/ Here is the list of changes for this version: # 111.03.00 ## async_extra - Add `?max_connections:int` argument to `Rpc.Connection.serve`. `max_connections` is passed to `Tcp.Server.create`, and limits the number of connections that an Rpc server will accept. - Improved `Log.Rotation`: - Made `Log.Rotation.t` abstract; use `create` rather than an explicit record. - Added a `` `Dated`` `naming_scheme`. - Add `Log.Rotation.default`, for getting a sensible default rotation scheme. - Added an optional (but discouraged) option to symlink the latest log file. - Every log rotation scheme has an associated `Time.Zone.t`. - Changed the internal representation of `Log.Rotation.t`, but `t_of_sexp` is backwards compatible, so existing config files will continue to work. - Changed `Udp.bind_any` to use `Socket.bind ~reuseaddr:false`, to ensure a unique port. - Added `Tcp.Server.listening_socket`, which returns the socket the server is listening on. Changed `Tcp.Server` so that if the listening socket is closed, the server is closed. - Added to `Udp.Config.t` a `max_ready : int` field to prevent UDP receive loops from starving other async jobs. - Improved `File_tail` to cut the number of `fstat` calls in half. `File_tail` uses a stat loop to monitor a file and continue reading it as it grows. We had made two `fstat` invocations per loop iteration, using `Async.Std.Unix.with_file` which constructs an `Fd.t` and therefore does it own `fstat`. Switching to `Core.Std.Unix.with_file` with `In_thread.run` eliminated the extra `fstat`. ## async_unix - Improved `Socket.accept` to abort and return `` `Socket_closed`` when the file descriptor underlying the socket is closed. - Added to `Socket.bind` a `?reuseaddr:bool` argument, preserving the default as `true`. - Added `Fd.close_started`, which becomes determined when `close` is called on an `Fd.t`. ## bin_prot - Fixed build on ARM. ## core - Added `Unix.Syslog` module. - Changed `Command.run` to no longer ignore the first element of its `~argv` parameter. - Made `Time.Span.to_short_string` show microsecond precision. ## core_extended - Added `Set_lang`, a DSL for sets with constants, union, intersection, and difference. - In `Process`, use `epoll` rather than `select` when possible, This prevents errors when selecting on file descriptors numbered greater than `FD_SETSIZE` (1024). - Removed `Syslog` module. There is now `Unix.Syslog` in core instead; the APIs are not compatible, but they are similar. ## core_kernel - Added `Error.to_string_hum_deprecated` that is the same as `Error.to_string_hum` pre 109.61. - Changed `Error.to_string_hum` so that `Error.to_string_hum (Error.of_string s) = s`. This fixed undesirable sexp escaping introduced in 109.61 and restores the pre-109.61 behavior for the special case of `Error.of_string`. A consequence of the removal of the custom `to_string_hum` converter in 109.61 was that: Error.to_string_hum (Error.of_string s) = Sexp.to_string_hum (Sexp.Atom s) That introduced sexp escaping of `s`. - Added to `Doubly_linked` functions for moving an element within a list. val move_to_front : 'a t -> 'a Elt.t -> unit val move_to_back : 'a t -> 'a Elt.t -> unit val move_after : 'a t -> 'a Elt.t -> anchor:'a Elt.t -> unit val move_before : 'a t -> 'a Elt.t -> anchor:'a Elt.t -> unit - Improved `Core_map_unit_tests.Unit_tests` to allow arbitrary data in the map, not just `ints`. This was done by eta expansion. ## custom_printf - Simplified the code generated by `pa_custom_printf` to make it more readable. ## re2 - Fixed a bug with `replace_exn` and anchoring. Fixed this bug: $ R.replace_exn ~f:(fun _ -> "a") (R.create_exn "^") "XYZ";; - : string = "aXaYaZa" $ R.replace_exn ~f:(fun _ -> "a") (R.create_exn "^X") "XXXYXXZ";; - : string = "aaaYXXZ" ## textutils - Changed `Textutils.Console` to not reference `Async.Log`, so that building inline benchmark runners no longer requires building `Async`. The change makes `Textutils`, and by extension `Core_extended` and `Core_bench`, not depend on `Async`.
Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-03/msg00025.html
Matthieu Dubuget asked:Is the following behaviour expected, or a misunderstanding of mine? In short, I'd like to use the Format module to prepare an output inside a Buffer.t. But a basic <hov> box does not break lines as I would expect, while printf does. OCaml version 4.01.0 # open Format;; # printf "@[<hov0>111,@,222,@,333,@,444,@,555,@,666@]@.";; 111,222,333,444,555,666 - : unit = () # set_margin 9;; - : unit = () # printf "@[<hov0>111,@,222,@,333,@,444,@,555,@,666@]@.";; 111,222, 333,444, 555,666 - : unit = () # sprintf "@[<hov0>111,@,222,@,333,@,444,@,555,@,666@]@.";; - : string = "111,222,333,444,555,666\n" Why doesn't sprintf exhibit the same behaviour as printf? Trying with fprintf… # fprintf str_formatter "@[<hov0>111,@,222,@,333,@,444,@,555,@,666@]@.";; - : unit = () # flush_str_formatter ();; - : string = "111,222,333,444,555,666\n"Jeremy Yallop replied:
The set_margin function only affects std_formatter: https://github.com/ocaml/ocaml/blob/8ba031a/stdlib/format.ml#L1027 You need to use pp_set_margin for other formatters.Benoit Vaugon also suggested:
The set_margin function configure the std_formatter, ie the formatter of the standard output (the one used by printf). To change the margin when printing in a buffer, you can run something like this : # open Format;; # let buf = Buffer.create 16;; val buf : Buffer.t = <abstr> # let formatter = formatter_of_buffer buf;; val formatter : Format.formatter = <abstr> # pp_set_margin formatter 9;; - : unit = () # fprintf formatter "@[<hov0>111,@,222,@,333,@,444,@,555,@,666@]@.";; - : unit = () # Buffer.contents buf;; - : string = "111,222,\n333,444,\n555,666\n"Martin Jambon later suggested:
Note that I made a library called easy-format that supposedly makes it easier to pretty-print code exactly the way you want: project page: http://mjambon.com/easy-format.html sample code + output: http://mjambon.com/easy_format_example.htmlRaphaël Proust then added, and Oleg replied:
> Another alternative to format for pretty-printing code (or other things): PPrint > > Release blog post (with some examples of use): > http://gallium.inria.fr/blog/first-release-of-pprint/ > Documentation: http://gallium.inria.fr/~fpottier/pprint/doc/PPrint.html > Installation instruction: `opam install pprint` That formatter uses Wadler's Pretty-printer, which is not optimal. The optimal one takes linear time in the size of the document (regardless of the page width), and, for constant page width, formats documents of any size in constant space. It is obviously incremental and has bounded latency. There are several optimal formatters. The recent one was based on simple generators, described in http://okmij.org/ftp/continuations/PPYield/index.html#pp Curiously, a Clojure programmer has read our paper and re-wrote the algorithm in Clojure -- without any help from us. It seems he is very satisfied with the results: https://github.com/brandonbloom/fipp That web page has a few examples.Bob Atkey then asked and Oleg replied:
> Have you compared your implementation to Christian Lindig's 'Strictly Pretty'?: > > http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.34.2200 > > I think the runtime of his implementation is dependent on page width, > due to repeated use of the fits function to measure whether a group > fits within the current line. A simple optimisation is to precompute > this width, as (I think) you do. I did this in my simple > implementation of Lindig's idea: > > https://github.com/bobatkey/pretty-monospace/blob/master/lib/Pretty.ml > > Neither of these implementations are incremental though; both require > the entire document to be present up front. > Thank you for the reference! I should compare with his and your implementations. Our pretty-printer is designed from the outset to be incremental. It operates on a stream of tokens: text-string, newline, begin-group, end-group. It is literally a functional composition of four stream transformers which annotate the stream tokens and then format them, outputting chunks of the final text. The formatting is simple if the begin-group token is annotated with the width of the corresponding group. The key idea is that we need to know this width only up to the point: if it exceeds the page width, we don't need to know by how much. So, computing this annotation requires only a bounded look-ahead. It is crucial for the performance to use a sequence data structure with the amortized constant-time addition and removal on both ends. Standard libraries of Haskell and Clojure luckily provide such a data structure.
Archive: https://sympa.inria.fr/sympa/arc/caml-list/2014-03/msg00035.html
Yotam Barnoy asked and Simon Cruanes replied:> I have a question about Batteries Included. Specifically, how do I get the > syntax extensions working and which syntax extensions are available? The > various bits of documentation I've found seemed either contradictory or did > not mention any syntax extensions at all. I'm specifically interested in > things like automatic rope generation and list comprehensions. The current version of Batteries is 2.2.0 and its documentation is here: http://ocaml-batteries-team.github.io/batteries-included/hdoc2/ . As far as I know, there are no more syntax extensions in Batteries since 2.0.0 (which explains why it doesn't depend on camlp4). I don't know much about the "rope generation" you talk about, but list comprehensions are nicely replaced (imho) by the |> operator: List.range 1 `To 10 |> List.filter (< 5) |> List.map string_of_int You can ask more questions on the Batteries mailing list ( https://lists.forge.ocamlcore.org/cgi-bin/listinfo/batteries-devel ). Hope you will find it helpful!Arnaud Spiwack then added:
List comprehension in a few (non-syntax checked) lines. TL;DR: list comprehension = monadic combinators. let return a = [a] let (>>=) x f = List.(flatten (map f x)) let (>>) x y = x >>= fun () -> y let guard b = if b then [()] else [] With these combinators [ f (x,y) | x <- l ; y <-r ; x=y+1 ] then translates to l >>= fun x -> r >>= fun y -> guard (x=y+1) >> return (f x) Less compact, no doubt, but still reasonably practical.Ivan Gotovchits then said and ygrek added:
> By the way, list comprehension is already included in standard ocaml > distribution. It is not as mighty as batteries one, and slightly differs > in syntax: > > [ x / 2 | x <- [ 2;4;6] ] $ ocaml OCaml version 4.00.1 .ocamlinit done # #camlp4o;; Camlp4 Parsing version 4.00.1 # #require "camlp4.listcomprehension";; # [ x / 2 | x <- [ 2;4;6] ];; - : int list = [1; 2; 3]
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/. An original programming pattern in Mezzo: http://gallium.inria.fr/blog/mezzo-control-flow-inversion From Jekyll site to Unikernel in fifty lines of code.: http://amirchaudhry.com/from-jekyll-to-unikernel-in-fifty-lines GUI Event Handling with a Functional Hierarchical State Machine: http://cranialburnout.blogspot.com/2014/03/gui-event-handling-with-functional.html OCaml EFL 1.9.0 and 1.8.2 released: https://forge.ocamlcore.org/forum/forum.php?forum_id=899 ocurl 0.7.0 released: https://forge.ocamlcore.org/forum/forum.php?forum_id=898 A Component-based GUI with Functional Flavour: http://cranialburnout.blogspot.com/2014/03/a-component-based-gui-with-functional.html OCamlPro Highlights: Feb 2014: http://www.ocamlpro.com/blog/2014/03/05/monthly-2014-02.html Intuitionistic Mathematics and Realizability in the Physical World: http://math.andrej.com/2014/03/04/intuitionistic-mathematics-and-realizability-in-the-physical-world/
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.