From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 3ED1E7EE80 for ; Tue, 19 Mar 2013 15:36:01 +0100 (CET) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of jdimino@janestreet.com) identity=pra; client-ip=38.105.200.229; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="jdimino@janestreet.com"; x-sender="jdimino@janestreet.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of jdimino@janestreet.com designates 38.105.200.229 as permitted sender) identity=mailfrom; client-ip=38.105.200.229; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="jdimino@janestreet.com"; x-sender="jdimino@janestreet.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@tot-dmz-mxout1.janestreet.com) identity=helo; client-ip=38.105.200.229; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="jdimino@janestreet.com"; x-sender="postmaster@tot-dmz-mxout1.janestreet.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AhkBALh2SFEmacjlmWdsb2JhbABDxlweDgEBAQEBCAsLBxQoglIZAQE4JV0SAQUBI4gmAwmkCopygzGBCgEFjw8GklWTHINGgR+EXoNvhTQWKYQt X-IPAS-Result: AhkBALh2SFEmacjlmWdsb2JhbABDxlweDgEBAQEBCAsLBxQoglIZAQE4JV0SAQUBI4gmAwmkCopygzGBCgEFjw8GklWTHINGgR+EXoNvhTQWKYQt X-IronPort-AV: E=Sophos;i="4.84,872,1355094000"; d="scan'208";a="7059833" Received: from mx5.janestreet.com (HELO tot-dmz-mxout1.janestreet.com) ([38.105.200.229]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 19 Mar 2013 15:36:00 +0100 Received: from [172.27.22.15] (helo=tot-smtp) by tot-dmz-mxout1.janestreet.com with esmtp (Exim 4.76) (envelope-from ) id 1UHxdt-0001Fv-Qz for caml-list@inria.fr; Tue, 19 Mar 2013 10:35:57 -0400 Received: from tot-dmz-mxgoog1.delacy.com ([172.27.224.14] helo=mxgoog2.janestreet.com) by tot-smtp with esmtps (TLSv1:AES256-SHA:256) (Exim 4.72) (envelope-from ) id 1UHxdt-0005aJ-Pn for caml-list@inria.fr; Tue, 19 Mar 2013 10:35:57 -0400 Received: from mail-ie0-f199.google.com ([209.85.223.199]) by mxgoog2.janestreet.com with esmtp (Exim 4.76) (envelope-from ) id 1UHxdt-0004mO-Mt for caml-list@inria.fr; Tue, 19 Mar 2013 10:35:57 -0400 Received: by mail-ie0-f199.google.com with SMTP id c13so2886004ieb.2 for ; Tue, 19 Mar 2013 07:35:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=janestreet.com; s=google; h=x-received:mime-version:x-received:date:message-id:subject:from:to :content-type; bh=c/fVOR6j7KdF/XRJO3LQF2HmViuljjAa+URbFdZKw2o=; b=c6SEt083TeKMsKWMBXBX4s+yxFsHR1NGSdu6NNW/TbgmLwFguCbFCUGgeR/eH+1YT1 7I904BwrrAN4ybWkaFydOXbu/RXZXPkFcvK/W84ejKkpBQ5lypjxUqhHTTSkIiEe4VVV 4UeVhdqAH6zuFbDakgtxL94f7/CcnNhjrvnwk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20120113; h=x-received:mime-version:x-received:date:message-id:subject:from:to :content-type:x-gm-message-state; bh=c/fVOR6j7KdF/XRJO3LQF2HmViuljjAa+URbFdZKw2o=; b=iP4kgDnkVdRDuq6u8WH55fb6UeI4mQWUXWsCzTNTqWsbOTCl8sIPnwmjoZvR78c6PA ARdt1N+LcXSE4pui8Rs0dqfPRuc8BeAun0XmQEb/32d6pe7gTzU5+HeMUJq8dEnGdTnw fJcrrsuI3bEuxmxoPX0YIRh6Iu1rlz2E9aJ0VRMEDQFQhjyVvnpqMCqhTQPApTFOWRW2 it/vXpb1/5Ba5P9w0ktpoSfySg/oNu6GRBfmD1WbL/05TkzhR/68fTmbM8OmrbxuRjqD +0nDUv10XqY9YVV1/jD3nhB9JdCUHTSQWswdFRRZ3h5yPFJc+dsh+FjzwPRdTjgXFspy I5dQ== X-Received: by 10.42.203.68 with SMTP id fh4mr11138741icb.36.1363703757337; Tue, 19 Mar 2013 07:35:57 -0700 (PDT) MIME-Version: 1.0 X-Received: by 10.42.203.68 with SMTP id fh4mr11138736icb.36.1363703757231; Tue, 19 Mar 2013 07:35:57 -0700 (PDT) Received: by 10.50.70.6 with HTTP; Tue, 19 Mar 2013 07:35:57 -0700 (PDT) Date: Tue, 19 Mar 2013 14:35:57 +0000 Message-ID: From: Jeremie Dimino To: caml-list@inria.fr, ocaml-core@googlegroups.com Content-Type: text/plain; charset=ISO-8859-1 X-Gm-Message-State: ALoCoQmJ3KbuqaFik7ez6c/NFVyXn3BqOqlc7jkrMes+wjlKlr9sFTJonhb4N+nCrFMs8JDDXAAOpDIiuAjdK2S6Xsvi705snwLGQy8VCLMXzpTc9Y4BxOri1tRq/wDOI5zjQ7IXIfYrBC5CLC+1rzE54CNsOyvcAQ== Subject: [Caml-list] [ANN] Core Suite 109.14.00 released + custom_printf I'm pleased to announce the 109.14.00 release of the Core suite. The new package of the week is custom_printf: a syntax extension for format strings. Formats prefixed with [!] support the new conversion specifier [%{}] and a few variants. Arguments are wrapped with the appropriate conversion function. For example: printf !"%{Float}" 42.0; printf !"%{Float.pretty}" 42.0; printf !"%{sexp:int * string}" (42, "foo"); is the same as: printf "%s" (Float.to_string 42.0); printf "%s" (Float.Format.pretty 42.0); printf "%s" (Sexp.to_string_hum (<:sexp_of< int * string >> (42, "foo"))); Files and documentation for this release are available on our website and all packages are in opam: https://ocaml.janestreet.com/ocaml-core/109.14.00/individual/ https://ocaml.janestreet.com/ocaml-core/109.14.00/doc/ Here are the changelogs for versions 109.12.00 to 109.14.00: # 109.12.00 ## async_extra - Made explicit the equivalence between type `Async.Command.t` and type `Core.Command.t`. ## async_unix - Fixed a bug in `Fd.syscall_in_thread`. The bug could cause: ```ocaml Fd.syscall_in_thread bug -- should be impossible ``` The bug was that `syscall_in_thread` raised rather than returning `Error`. - Changed `Tcp.connect` and `Tcp.with_connect` to also supply the connected socket. Supplying the connected socket makes it easy to call `Socket` functions, e.g. to find out information about the connection with `Socket.get{peer,sock}name`. This also gives information about the IP address *after* DNS, which wouldn't otherwise be available. One could reconstruct the socket by extracting the fd from the writer, and then calling `Socket.of_fd` with the correct `Socket.Type`. But that is both error prone and not discoverable. - Added `Writer.schedule_bigsubstring`, which parallels `Writer.schedule_bigstring`. ## core - Add some functions to `Byte_units`. - Added functions: `to_string_hum`, `scale`, `Infix.//`. - Eliminated the notion of "preferred measure", so a `Byte_units.t` is just a `float`. - Improved the performance of `Array.of_list_rev`. The new implementation puts the list elements directly in the right place in the resulting array, rather that putting them in order and then reversing the array in place. Benchmarking shows that the new implementation runs in 2/3 the time of the old one. - Fixed `Fqueue.t_of_sexp`, which didn't work with `sexp_of_t`. There was a custom `sexp_of_t` to abstract away the internal record structure and make the sexp look like a list, but there wasn't a custom `t_of_sexp` defined, so it didn't work. - Added `Stable.V1` types for `Host_and_port`. - Removed `Identifiable.Of_sexpable` and `Identifiable.Of_stringable`, in favor of `Identifiable.Make` `Identifiable.Of_sexpable` encouraged a terrible implementation of `Identifiable.S`. In particular, `hash`, `compare`, and bin_io were all built by converting the type to a sexp, and then to a string. `Identifiable.Of_stringable` wasn't as obviously bad as `Of_sexpable`. But it still used the string as an intermediate, which is often the wrong choice -- especially for `compare` and `bin_io`, which can be generated by preprocessors. Added `Identifiable.Make` as the replacement. It avoids using sexp conversion for any of the other operations. - Added `List.intersperse` and `List.split_while`. These came from `Core_extended.List`. ```ocaml val intersperse : 'a list -> sep:'a -> 'a list val split_while : 'a list -> f:('a -> bool) -> 'a list ** 'a list ``` - Added a functor, `Pretty_printer.Register`, for registering pretty printers. The codifies the idiom that was duplicated in lots of places: ```ocaml let pp formatter t = Format.pp_print_string formatter (to_string t) let () = Pretty_printer.register "Some_module.pp") ``` ## fieldslib - Added back `Fields.fold` to `with fields` for `private` types. We had removed `Fields.fold` for `private` types, but this caused some pain. So we're putting it back. At some point, we'll patch `with fields` to prevent setting mutable fields on private types via the fields provided by `fold`. ## sexplib - A tiny lexer improvement in `lexer.mll`. Used `lexbuf.lex_{start|curr}_pos` instead of `lexbuf.lex_{start|curr}_p.pos_cnum` for computing the length of a lexeme since the difference is the same. # 109.13.00 ## async_core - Fixed `Pipe.iter`'s handling of a closed pipe. Fixed the handling by `Pipe.iter` and related foldy functions that handle one element at a time, which behaved surprisingly with a pipe whose read end has been closed. These functions had worked by reading a queue as a batch and then applying the user function to each queue element. But if the pipe's read end is closed during the processing of one queue element, no subsequent element should be processed. Prior to this fix, the `iter` didn't notice the pipe was closed for read until it went to read the next batch. - Renamed `Pipe.read_one` as `Pipe.read_one`', and added `Pipe.read_one` that reads a single element. ## async_unix - Added `Writer.write_line`, which is `Writer.write` plus a newline at the end. - Added `?close_on_exec:bool` argument to `{Reader,Writer}.open_file` and `Async.Unix.open_file`. Made the default `close_on_exec:true` for `Reader` and `Writer`. - Added a `compare` function to `Socket.Address.Inet`. ## core - Added `Command.Spec.flags_of_args_exn`, for compatibility with OCaml's standard library. This function converts a `Core.Std.Arg.t` into a `Command.Spec.t`. - Made various modules `Identifiable`: `Char`, `String`, and the various `Int` modules. In particular, `Int` being identifiable is useful, because one can now write: ```ocaml module My_numeric_identifier : Identifiable ` Int ``` You might think that we could now delete `String_id`, and just write: ```ocaml module My_string_identifier : Identifiable ` String ``` But this is not quite equivalent to using `String_id`, because `String_id.of_string` enforces that its argument is nonempty. - Removed module `Space_safe_tuple`, which became unnecessary in OCaml 4.00.0. OCaml 4.00.0 included Fabrice's patch to fix the space leak that `Space_safe_tuple` was circumventing (PR#5288, commit SVN 11085). - Added `Exn.to_string_mach`, for single-line output. - Added `Linux_ext.bind_to_interface`, to improve security of UDP applications. ```ocaml val bind_to_interface : (File_descr.t -> string -> unit) Or_error.t ``` This uses the linux-specifc socket option `BINDTODEVICE` to prevent packets being received from any interface other than one named. - Fixed `Unix.mkdir_p` on Mac OS X. # 109.14.00 ## async - Added function `Monitor.kill`, which kills a monitor and all its descendants. This prevents any jobs from ever running in the monitor again. ## async_unix - Fixed major performance degradation (since 109.04) in `Reader.read*` functions. - Added function `Rpc.Implementation.map_inv`. ```ocaml val map_inv : 'a t -> f:('b -> 'a) -> 'b t ``` - Add functions `Reader.file_lines` and `Writer.save_lines`. These deal with files as lists of their lines. ```ocaml val Reader.file_lines : string -> string list Deferred.t val Writer.save_lines : string -> string list -> unit Deferred.t ``` - Added a `?wakeup_scheduler:bool` optional argument to functions in the `Thread_safe` module. The default is `true`, which continues the behavior that has been in place since 109.09. However, once can use `~wakeup_scheduler:false` to reduce CPU use, in return for increased latency (because the scheduler won't run a cycle immediately). ## core - Fixed major performance problem with hashing in `Int.Table`. Our `Int.Table.replace` was 3 times slower than polymorphic hash table and `find` was _8_ times slower. This was caused by using: ```ocaml external seeded_hash_param : int -> int -> int -> 'a -> int = "caml_hash" "noalloc" ``` in `Int.Table` but: ```ocaml external old_hash_param : int -> int -> 'a -> int = "caml_hash_univ_param" "noalloc" ``` everywhere else. The `seeded_hash_param` was introduced in Caml 4. We fixed this problem by changing `Int.hash` from: ```ocaml let hash (x : t) = Hashtbl.hash x ``` to: ```ocaml let hash (x : t) = if x >= 0 then x else ~-x ``` - Added `Bigstring.{pread,pwrite}`, which allow reading and writing at a specific file offset. - Added module `Nothing`, which is a type with no values. This is useful when an interface requires you to specify a type that you know will never be used in your implementation. - Changed `Identifiable.Make` so that it registers a pretty printer. `Identifiable.Make` now uses `Pretty_printer.Register`. This requires all calls to `Identifiable.Make` to supply a `val module_name : string`. - Made `Core.Zone` match the `Identifiable` signature. - Made polymorphic equality always fail on `Core.Map.t` and `Core.Set.t`. Before this change, polymorphic equality on a `Core.Map` or a `Core.Set` could either raise or return `false`. It returnd `false` if the data structures were unequal, and raised if the data structures were equal. This is because their type definitions looked like: ```ocaml type ('k, 'v, 'comparator) t = { tree : ('k, 'v) Tree0.t; comparator : ('k, 'comparator) Comparator.t; } ``` and polymorphic equality visits a block's fields in order. So, it will detect unequal trees and return false, but if the trees are equal, it will compare the comparators and raise because of the functional value. This change reversed the order of the fields so polymorphic equality always fails. ## custom_printf - initial import Added support for `%{}` in `printf`-style format strings. If you put `!` before a format string, it allows the use of a spec like `%{}` in the format string. For example, using `%{Time}` wraps `Time.to_string` around the appropriate argument. It also allows different formats for a given type: `%{.}` wraps `.Format.` around the appropriate argument. For example, `%{Float.pretty}` would wrap `Float.Format.pretty` around the appropriate argument. ## fieldslib - Made `with fields` expose first-class fields for private types while preserving privacy. There is now an additional phantom type in a first-class field that prevents building or modifying elements of a private type. One consequence of this change is that the `Field.t` type is now an abstract type -- it used to be exposed as a record type. So, one must, e.g., change `field.Field.name` to `Field.name field`. -- Jeremie Dimino, for the Core team