core 109.35.00-rc1

# 109.35.00

## async_core

- Added new configuration options for Async, `max_inter_cycle_timeout`
  and `max_num_jobs_per_priority_per_cycle`.

  ```ocaml
  val max_inter_cycle_timeout : Time.Span.t
  val max_num_jobs_per_priority_per_cycle : int
  ```

  These are configurable as usual via `ASYNC_CONFIG`.

- Added an `ASYNC_CONFIG` option to debug the `Shutdown` module.
- Added `find` and `find_map` to `Deferred.Monad_sequence`.

## async_extra

- Added module `Async.Udp`, aimed at high-performance UDP
  applications.
- Added module `Lock_file.Nfs`, which wraps the functions in
  `Core.Std.Lock_file.Nfs`.

## async_unix

- Made some configuration possible via additional optional arguments
  to `go_main`.

  ```ocaml
  ?max_num_open_file_descrs:int
  ?max_num_threads:int
  ```
- Made some aspects of the async scheduler configurable via functions
  in `Scheduler`.

  ```ocaml
  val set_check_invariants                  : bool        -> unit
  val set_detect_invalid_access_from_thread : bool        -> unit
  val set_max_inter_cycle_timeout           : Time.Span.t -> unit
  val set_record_backtraces                 : bool        -> unit
  ```
- Added a dynamic check in `Pipe` that a consumer is used with the
  correct pipe.

  Specifically, check that a consumer supplied to a read operation on
  a `Pipe.Reader.t` was previously created by `add_consumer` with that
  same reader.
- Renamed `Pipe.fold` as `fold_without_pushback` and added `Pipe.fold`
  with an analogous type to `Pipe.iter`.
- Fixed a bug in `Pipe.merge`, which did not always close the
  resulting pipe when the merge was finished.

  This had prevented medusa regtests from working correctly.
- In `Writer`, changed the default `buffer_age_limit` for files to
  ``Unlimited`.

  THis was done for the same reason that we treat files specially in
  flush on close -- slowness will likely be resolved eventually with a
  file, unlike with a socket.

## core

- Added `or_error` functions in `Unix.Exit_*` types to `unit
  Or_error.t`.

  This makes it easier to deal with combining with infix operators
  `>>=?` and `>>|?`

## core_extended

- Added stable versions of types contained in the `Selector` module.

## core_kernel

- Added `with compare` to `List.Assoc.t`.
- Made `Pooled_hashtbl.create` handle non-positive and very large
  `size`s in the same way as `Core.Hashtbl`.
- Added `is_error`, `is_ok`, and `does_raise` to `Core.Std`.

  ```ocaml
  let is_error ` Result.is_error
  let is_ok    ` Result.is_ok
  val does_raise : (unit -> _) -> bool
  ```
- Reimplemented `Heap` and reworked the interface to be more standard.

  The new implementation uses pairing heaps and `Pool`.
- Added a module `Pool.Unsafe`, which is like `Pool`, except that
  `create` doesn't require an initial value.

  This makes it unsafe to access pool pointers after they have been
  freed.  But it is useful for situations when one isn't able to
  create an initial value, e.g. `Core.Heap`.
- Removed `Time.to_localized_string` and `Time.to_string_deprecated`.

  These did not include the time-zone offset.  Instead, use
  `Time.to_string` and `Time.to_string_abs`, which do include the
  time-zone offset.
- Exposed that `Int63.t = private int` on 64-bit machines.

  This lets the OCaml compiler avoid `caml_modify` when dealing with
  it.
- Added `Gc` stat functions that don't allocate: `Gc.minor_words`,
  `Gc.major_words`, `Gc.promoted_words`.

  Added the following `Gc` functions:

  ```ocaml
  Gc.minor_words : unit -> int
  Gc.major_words : unit -> int
  Gc.promoted_words : unit -> int
  ```

  such that these functions cause no allocations by themselves. The
  assumption being that 63-bit ints should be large enough to express
  total allocations for most programs.  On 32-bit machines the numbers
  may overflow and these functions are not as generally useful.

  These functions were added because doing memory allocation debugging
  with `Gc.quick_stat` as the primary means of understanding
  allocations is difficult: tracking down allocations of the order of
  a few hundred words in a hot loop by putting in lots of `quick_stat`
  statements becomes too intrusive because of the memory allocations
  they cause.

  Here are some benchmarks of existing `Gc` functions and the newly
  added functions:

  ```
  $ ./test_bench.exe -q 2 -clear name time +alloc +time-err
  Estimated testing time 12s (change using -quota SECS).
  ┌─────────────────┬───────────┬─────────────┬──────────┬───────┐
  │ Name            │ Time (ns) │      95% ci │ Time R^2 │ Minor │
  ├─────────────────┼───────────┼─────────────┼──────────┼───────┤
  │ quick_stat      │     92.16 │ +0.72 -0.64 │     1.00 │ 23.00 │
  │ counters        │     33.63 │ +0.26 -0.23 │     1.00 │ 10.00 │
  │ allocated_bytes │     37.89 │ +0.34 -0.32 │     1.00 │ 12.00 │
  │ minor_words     │      4.63 │ +0.03 -0.02 │     1.00 │       │
  │ major_words     │      4.36 │ +0.02 -0.02 │     1.00 │       │
  │ promoted_words  │      4.10 │ +0.03 -0.02 │     1.00 │       │
  └─────────────────┴───────────┴─────────────┴──────────┴───────┘
  ```

## faillib

- New syntax extension to get improved location information on calls
  to `failwiths`.

  Added `failwithp`, which is like `failwiths` but takes a `_here_`
  argument:

  ```ocaml
  val failwithp : Lexing.position -> string -> 'a -> ('a -> Sexp.t) -> _
  ```

  `pa_fail` automatically converts `failwiths` into `failwithp _here_`

  If you don't want to compile with `pa_fail`, then you can manually
  write `failwithp _here_`.  Otherwise, running the same source
  through `pa_fail` gets you location information for free.

## ocaml_plugin

- Changed the execution of plugin's toplevel to run in async instead
  of `In_thread.run`, unless a config parameter says otherwise.

## textutils

- Added new module `Textutils.Text_graph` for plotting text graphs on
  a terminal.

  Her is an example density plot for `minor_words` from
  `mcquote-stats.data`.

  ```
  (354 (3%) values outside the range, bucket size is 38.58)
      74.00     3786 |----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----|
     112.58        0 |
     151.17        0 |
     189.75        0 |
     228.33        0 |
     266.92        0 |
     305.50        0 |
     344.08        0 |
     382.67        0 |
     421.25        0 |
     459.83     3653 |----+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+-
     498.42        4 |
     537.00     1055 |----+----1----+----2----+--
     575.58      308 |----+---
     614.17       70 |-
     652.75      404 |----+----1
     691.33       71 |-
     729.92       32 |
     768.50       18 |
     807.08      151 |---
     845.67       17 |
     884.25        4 |
     922.83        8 |
     961.42       66 |-
    1000.00        0 |
  ```

  Each `-` is approximately 37.860 units.