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 CEBB97EE80 for ; Wed, 20 Mar 2013 10:34:45 +0100 (CET) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of artemkin@gmail.com) identity=pra; client-ip=209.85.212.56; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="artemkin@gmail.com"; x-sender="artemkin@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of artemkin@gmail.com designates 209.85.212.56 as permitted sender) identity=mailfrom; client-ip=209.85.212.56; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="artemkin@gmail.com"; x-sender="artemkin@gmail.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@mail-vb0-f56.google.com) identity=helo; client-ip=209.85.212.56; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="artemkin@gmail.com"; x-sender="postmaster@mail-vb0-f56.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Ao0EALWBSVHRVdQ4cGdsb2JhbABDiBK0PQGIQoFIFg4BDAslBSSCJQEFGgkENR0QCQJCAgIjEQEFARyIGgESDJQ6jyGLY0+ECYNeChmBDYhrF48LBAeCLYETA4h1iiWEZYhNhTQ/glSBTC0c X-IPAS-Result: Ao0EALWBSVHRVdQ4cGdsb2JhbABDiBK0PQGIQoFIFg4BDAslBSSCJQEFGgkENR0QCQJCAgIjEQEFARyIGgESDJQ6jyGLY0+ECYNeChmBDYhrF48LBAeCLYETA4h1iiWEZYhNhTQ/glSBTC0c X-IronPort-AV: E=Sophos;i="4.84,876,1355094000"; d="scan'208";a="7154742" Received: from mail-vb0-f56.google.com ([209.85.212.56]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 20 Mar 2013 10:34:44 +0100 Received: by mail-vb0-f56.google.com with SMTP id s24so753544vbi.1 for ; Wed, 20 Mar 2013 02:34:42 -0700 (PDT) X-Received: by 10.49.24.109 with SMTP id t13mr505756qef.19.1363772082855; Wed, 20 Mar 2013 02:34:42 -0700 (PDT) X-Google-Doc-Id: d608ad471edc32a X-Google-Web-Client: true Date: Wed, 20 Mar 2013 02:34:42 -0700 (PDT) From: Stanislav Artemkin To: ocaml-core@googlegroups.com Cc: caml-list@inria.fr Message-Id: In-Reply-To: References: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="----=_Part_1135_1129863.1363772082460" X-Google-Token: ELKFpooFhEtcLQeSfTI0 X-Google-IP: 195.151.254.101 X-Validation-by: artemkin@gmail.com Subject: [Caml-list] Re: [ANN] Core Suite 109.14.00 released + custom_printf ------=_Part_1135_1129863.1363772082460 Content-Type: multipart/alternative; boundary="----=_Part_1136_31354420.1363772082460" ------=_Part_1136_31354420.1363772082460 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Bitbucket doesn't contain latest changes. Do I correctly understand that=20 Github is a main source? What is the strategy of updating Bitbucket repos? Thanks =D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, 19 =D0=BC=D0=B0=D1=80=D1=82=D0= =B0 2013 =D0=B3., 18:35:57 UTC+4 =D0=BF=D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2= =D0=B0=D1=82=D0=B5=D0=BB=D1=8C Jeremie Dimino=20 =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB: > > I'm pleased to announce the 109.14.00 release of the Core suite.=20 > > The new package of the week is custom_printf: a syntax extension for=20 > format strings. Formats prefixed with [!] support the new conversion=20 > specifier [%{}] and a few variants. Arguments are wrapped=20 > with the appropriate conversion function.=20 > > For example:=20 > > printf !"%{Float}" 42.0;=20 > printf !"%{Float.pretty}" 42.0;=20 > printf !"%{sexp:int * string}" (42, "foo");=20 > > is the same as:=20 > > printf "%s" (Float.to_string 42.0);=20 > printf "%s" (Float.Format.pretty 42.0);=20 > printf "%s" (Sexp.to_string_hum (<:sexp_of< int * string >> (42,=20 > "foo")));=20 > > > Files and documentation for this release are available on our website=20 > and all packages are in opam:=20 > > https://ocaml.janestreet.com/ocaml-core/109.14.00/individual/=20 > https://ocaml.janestreet.com/ocaml-core/109.14.00/doc/=20 > > Here are the changelogs for versions 109.12.00 to 109.14.00:=20 > > # 109.12.00=20 > > ## async_extra=20 > > - Made explicit the equivalence between type `Async.Command.t` and=20 > type `Core.Command.t`.=20 > > ## async_unix=20 > > - Fixed a bug in `Fd.syscall_in_thread`.=20 > > The bug could cause:=20 > > ```ocaml=20 > Fd.syscall_in_thread bug -- should be impossible=20 > ```=20 > > The bug was that `syscall_in_thread` raised rather than returning=20 > `Error`.=20 > - Changed `Tcp.connect` and `Tcp.with_connect` to also supply the=20 > connected socket.=20 > > Supplying the connected socket makes it easy to call `Socket`=20 > functions, e.g. to find out information about the connection with=20 > `Socket.get{peer,sock}name`. This also gives information about the IP= =20 > address *after* DNS, which wouldn't otherwise be available.=20 > > One could reconstruct the socket by extracting the fd from the=20 > writer, and then calling `Socket.of_fd` with the correct=20 > `Socket.Type`. But that is both error prone and not discoverable.=20 > - Added `Writer.schedule_bigsubstring`, which parallels=20 > `Writer.schedule_bigstring`.=20 > > ## core=20 > > - Add some functions to `Byte_units`.=20 > - Added functions: `to_string_hum`, `scale`, `Infix.//`.=20 > - Eliminated the notion of "preferred measure", so a `Byte_units.t`=20 > is just a `float`.=20 > - Improved the performance of `Array.of_list_rev`.=20 > > The new implementation puts the list elements directly in the right=20 > place in the resulting array, rather that putting them in order and=20 > then reversing the array in place.=20 > > Benchmarking shows that the new implementation runs in 2/3 the time of= =20 > the old one.=20 > - Fixed `Fqueue.t_of_sexp`, which didn't work with `sexp_of_t`.=20 > > There was a custom `sexp_of_t` to abstract away the internal record=20 > structure and make the sexp look like a list, but there wasn't a=20 > custom `t_of_sexp` defined, so it didn't work.=20 > - Added `Stable.V1` types for `Host_and_port`.=20 > - Removed `Identifiable.Of_sexpable` and `Identifiable.Of_stringable`,=20 > in favor of `Identifiable.Make`=20 > > `Identifiable.Of_sexpable` encouraged a terrible implementation of=20 > `Identifiable.S`. In particular, `hash`, `compare`, and bin_io were=20 > all built by converting the type to a sexp, and then to a string.=20 > > `Identifiable.Of_stringable` wasn't as obviously bad as=20 > `Of_sexpable`. But it still used the string as an intermediate,=20 > which is often the wrong choice -- especially for `compare` and=20 > `bin_io`, which can be generated by preprocessors.=20 > > Added `Identifiable.Make` as the replacement. It avoids using sexp=20 > conversion for any of the other operations.=20 > - Added `List.intersperse` and `List.split_while`.=20 > > These came from `Core_extended.List`.=20 > > ```ocaml=20 > val intersperse : 'a list -> sep:'a -> 'a list=20 > val split_while : 'a list -> f:('a -> bool) -> 'a list ** 'a list=20 > ```=20 > - Added a functor, `Pretty_printer.Register`, for registering pretty=20 > printers.=20 > The codifies the idiom that was duplicated in lots of places:=20 > > ```ocaml=20 > let pp formatter t =3D Format.pp_print_string formatter (to_string t)= =20 > let () =3D Pretty_printer.register "Some_module.pp")=20 > ```=20 > > ## fieldslib=20 > > - Added back `Fields.fold` to `with fields` for `private` types.=20 > > We had removed `Fields.fold` for `private` types, but this caused=20 > some pain. So we're putting it back. At some point, we'll patch=20 > `with fields` to prevent setting mutable fields on private types via=20 > the fields provided by `fold`.=20 > > ## sexplib=20 > > - A tiny lexer improvement in `lexer.mll`. Used=20 > `lexbuf.lex_{start|curr}_pos` instead of=20 > `lexbuf.lex_{start|curr}_p.pos_cnum` for computing the length of a=20 > lexeme since the difference is the same.=20 > > # 109.13.00=20 > > ## async_core=20 > > - Fixed `Pipe.iter`'s handling of a closed pipe.=20 > > Fixed the handling by `Pipe.iter` and related foldy functions that=20 > handle one element at a time, which behaved surprisingly with a pipe=20 > whose read end has been closed. These functions had worked by=20 > reading a queue as a batch and then applying the user function to=20 > each queue element. But if the pipe's read end is closed during the=20 > processing of one queue element, no subsequent element should be=20 > processed. Prior to this fix, the `iter` didn't notice the pipe was=20 > closed for read until it went to read the next batch.=20 > - Renamed `Pipe.read_one` as `Pipe.read_one`', and added=20 > `Pipe.read_one` that reads a single element.=20 > > ## async_unix=20 > > - Added `Writer.write_line`, which is `Writer.write` plus a newline at=20 > the end.=20 > - Added `?close_on_exec:bool` argument to `{Reader,Writer}.open_file`=20 > and `Async.Unix.open_file`.=20 > > Made the default `close_on_exec:true` for `Reader` and `Writer`.=20 > - Added a `compare` function to `Socket.Address.Inet`.=20 > > ## core=20 > > - Added `Command.Spec.flags_of_args_exn`, for compatibility with=20 > OCaml's standard library.=20 > > This function converts a `Core.Std.Arg.t` into a `Command.Spec.t`.=20 > - Made various modules `Identifiable`: `Char`, `String`, and the=20 > various `Int` modules.=20 > > In particular, `Int` being identifiable is useful, because one can=20 > now write:=20 > > ```ocaml=20 > module My_numeric_identifier : Identifiable ` Int=20 > ```=20 > > You might think that we could now delete `String_id`, and just=20 > write:=20 > > ```ocaml=20 > module My_string_identifier : Identifiable ` String=20 > ```=20 > > But this is not quite equivalent to using `String_id`, because=20 > `String_id.of_string` enforces that its argument is nonempty.=20 > > - Removed module `Space_safe_tuple`, which became unnecessary in OCaml=20 > 4.00.0.=20 > > OCaml 4.00.0 included Fabrice's patch to fix the space leak that=20 > `Space_safe_tuple` was circumventing (PR#5288, commit SVN 11085).=20 > - Added `Exn.to_string_mach`, for single-line output.=20 > - Added `Linux_ext.bind_to_interface`, to improve security of UDP=20 > applications.=20 > > ```ocaml=20 > val bind_to_interface : (File_descr.t -> string -> unit) Or_error.t=20 > ```=20 > > This uses the linux-specifc socket option `BINDTODEVICE` to prevent=20 > packets being received from any interface other than one named.=20 > - Fixed `Unix.mkdir_p` on Mac OS X.=20 > > # 109.14.00=20 > > ## async=20 > > - Added function `Monitor.kill`, which kills a monitor and all its=20 > descendants.=20 > > This prevents any jobs from ever running in the monitor again.=20 > > ## async_unix=20 > > - Fixed major performance degradation (since 109.04) in `Reader.read*`=20 > functions.=20 > - Added function `Rpc.Implementation.map_inv`.=20 > > ```ocaml=20 > val map_inv : 'a t -> f:('b -> 'a) -> 'b t=20 > ```=20 > - Add functions `Reader.file_lines` and `Writer.save_lines`.=20 > > These deal with files as lists of their lines.=20 > > ```ocaml=20 > val Reader.file_lines : string -> string list Deferred.t=20 > val Writer.save_lines : string -> string list -> unit Deferred.t=20 > ```=20 > - Added a `?wakeup_scheduler:bool` optional argument to functions in=20 > the `Thread_safe` module.=20 > > The default is `true`, which continues the behavior that has been in=20 > place since 109.09.=20 > However, once can use `~wakeup_scheduler:false` to reduce CPU use,=20 > in return for increased=20 > latency (because the scheduler won't run a cycle immediately).=20 > > ## core=20 > > - Fixed major performance problem with hashing in `Int.Table`.=20 > > Our `Int.Table.replace` was 3 times slower than polymorphic hash=20 > table and `find` was _8_ times slower.=20 > > This was caused by using:=20 > > ```ocaml=20 > external seeded_hash_param : int -> int -> int -> 'a -> int =3D=20 > "caml_hash" "noalloc"=20 > ```=20 > > in `Int.Table` but:=20 > > ```ocaml=20 > external old_hash_param : int -> int -> 'a -> int =3D=20 > "caml_hash_univ_param" "noalloc"=20 > ```=20 > > everywhere else.=20 > > The `seeded_hash_param` was introduced in Caml 4.=20 > > We fixed this problem by changing `Int.hash` from:=20 > > ```ocaml=20 > let hash (x : t) =3D Hashtbl.hash x=20 > ```=20 > > to:=20 > > ```ocaml=20 > let hash (x : t) =3D if x >=3D 0 then x else ~-x=20 > ```=20 > - Added `Bigstring.{pread,pwrite}`, which allow reading and writing at=20 > a specific file offset.=20 > - Added module `Nothing`, which is a type with no values.=20 > > This is useful when an interface requires you to specify a type that=20 > you know will never be used in your implementation.=20 > - Changed `Identifiable.Make` so that it registers a pretty printer.=20 > > `Identifiable.Make` now uses `Pretty_printer.Register`. This=20 > requires all calls to `Identifiable.Make` to supply a `val=20 > module_name : string`.=20 > - Made `Core.Zone` match the `Identifiable` signature.=20 > - Made polymorphic equality always fail on `Core.Map.t` and=20 > `Core.Set.t`.=20 > > Before this change, polymorphic equality on a `Core.Map` or a=20 > `Core.Set` could either raise or return `false`. It returnd `false`=20 > if the data structures were unequal, and raised if the data=20 > structures were equal.=20 > > This is because their type definitions looked like:=20 > > ```ocaml=20 > type ('k, 'v, 'comparator) t =3D=20 > { tree : ('k, 'v) Tree0.t;=20 > comparator : ('k, 'comparator) Comparator.t;=20 > }=20 > ```=20 > > and polymorphic equality visits a block's fields in order. So, it=20 > will detect unequal trees and return false, but if the trees are=20 > equal, it will compare the comparators and raise because of the=20 > functional value.=20 > > This change reversed the order of the fields so polymorphic equality=20 > always fails.=20 > > ## custom_printf=20 > > - initial import=20 > Added support for `%{}` in `printf`-style format strings.=20 > > If you put `!` before a format string, it allows the use of a spec=20 > like `%{}` in the format string. For example, using=20 > `%{Time}` wraps `Time.to_string` around the appropriate argument.=20 > > It also allows different formats for a given type:=20 > `%{.}` wraps `.Format.`=20 > around the appropriate argument. For example, `%{Float.pretty}`=20 > would wrap `Float.Format.pretty` around the appropriate argument.=20 > > ## fieldslib=20 > > - Made `with fields` expose first-class fields for private types while=20 > preserving privacy.=20 > > There is now an additional phantom type in a first-class field that=20 > prevents building or modifying elements of a private type.=20 > > One consequence of this change is that the `Field.t` type is now an=20 > abstract type -- it used to be exposed as a record type. So, one=20 > must, e.g., change `field.Field.name` to `Field.name field`.=20 > > --=20 > Jeremie Dimino, for the Core team=20 > ------=_Part_1136_31354420.1363772082460 Content-Type: text/html; charset=utf-8 Content-Transfer-Encoding: quoted-printable Bitbucket doesn't contain latest changes. Do I correctly understand that Gi= thub is a main source? What is the strategy of updating Bitbucket repos?
Thanks

=D0=B2=D1=82=D0=BE=D1=80=D0=BD=D0=B8=D0=BA, = 19 =D0=BC=D0=B0=D1=80=D1=82=D0=B0 2013 =D0=B3., 18:35:57 UTC+4 =D0=BF= =D0=BE=D0=BB=D1=8C=D0=B7=D0=BE=D0=B2=D0=B0=D1=82=D0=B5=D0=BB=D1=8C Jeremie = Dimino =D0=BD=D0=B0=D0=BF=D0=B8=D1=81=D0=B0=D0=BB:
I'm pleased to announce the 109.14.00 release of the Co= re suite.

The new package of the week is custom_printf: a syntax extension for
format strings.  Formats prefixed with [!] support the new convers= ion
specifier [%{<Module>}] and a few variants.  Arguments are w= rapped
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 * s= tring >> (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/10= 9.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 returnin= g `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 connecti= on with
  `Socket.get{peer,sock}name`.  This also gives information a= bout 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 discov= erable.
- 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 ri= ght
  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 t= ime 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 rec= ord
  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 bi= n_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 intermed= iate,
  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 us= ing 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 pr= inters.
  The codifies the idiom that was duplicated in lots of places:

  ```ocaml
  let pp formatter t =3D Format.pp_print_string formatter (to_stri= ng t)
  let () =3D 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 leng= th 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 th= at
  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 d= uring 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 c= an
  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) O= r_error.t
  ```

  This uses the linux-specifc socket option `BINDTODEVICE` to prev= ent
  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 Defe= rred.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 bee= n in
place since 109.09.
  However, once can use `~wakeup_scheduler:false` to reduce CPU us= e,
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 -&= gt; int =3D
"caml_hash" "noalloc"
  ```

  in `Int.Table` but:

  ```ocaml
  external old_hash_param : int -> int -> 'a -> int =3D
"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) =3D Hashtbl.hash x
  ```

  to:

  ```ocaml
  let hash (x : t) =3D if x >=3D 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`.  Th= is
  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 return= d `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 =3D
    { 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 equa= lity
  always fails.

## custom_printf

- initial import
  Added support for `%{<Module>}` in `printf`-style format s= trings.

  If you put `!` before a format string, it allows the use of a sp= ec
  like `%{<Module>}` 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:
  `%{<Module>.<identifier>}` wraps `<Module>.For= mat.<identifier>`
  around the appropriate argument.  For example, `%{Float.pre= tty}`
  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 t= hat
  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.  S= o, one
  must, e.g., change `field.Field.name` to `Field.name field`.

--=20
Jeremie Dimino, for the Core team
= ------=_Part_1136_31354420.1363772082460-- ------=_Part_1135_1129863.1363772082460--