[cwn] Attn: Development Editor, Latest OCaml Weekly News

Alan Schmitt alan.schmitt at polytechnique.org
Tue Dec 8 03:07:29 PST 2020


Hello

Here is the latest OCaml Weekly News, for the week of December 01 to 08,
2020.

Table of Contents
─────────────────

OCaml 4.12.0, second alpha release
ez_subst.0.1.0 and ez_cmdliner.0.2.0
New release of Menhir (20201201)
http-multipart-formdata 1.0.0
Multicore OCaml: November 2020
Seq vs List, optimization
dap 1.0.0 – Debug Adapter Protocol for OCaml
✂️ form2xml - a tiny cli tool to slice http form-data dumps
http-multipart-formdata 1.0.1
Set up OCaml 1.1.4
First Public Release (beta) of the Memthol memory profiling visualizer
Exception vs Result
Making web calls to OCaml
wasmtime 0.0.1: lightweight WebAssembly runtime
First release of Lwt-exit
Old CWN


OCaml 4.12.0, second alpha release
══════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ocaml-4-12-0-second-alpha-release/6887/1>


octachron announced
───────────────────

  The release of OCaml 4.12.0 is approaching. We have released a second
  alpha version to help fellow hackers join us early in our bug hunting
  and opam ecosystem fixing fun.

  Beyond the usual bug fixes this new alpha version removes the type
  system change that restricted the propagation of type information
  between branches of a "match".  The newly introduced warning was more
  troublesome than expected, the feature has been thus postponed to 4.13
  .

  The base compiler can be installed as an opam switch with the
  following commands
  ┌────
  │ opam update
  │ opam switch create 4.12.0~alpha2
  │ --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git
  └────
  If you want to tweak the configuration of the compiler, you can pick
  configuration options with
  ┌────
  │ opam update
  │ opam switch create <switch_name> --packages=ocaml-variants.4.12.0~alpha2+options,<option_list>
  │ --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git
  └────
  where `<option_list>' is a comma separated list of ocaml-option-*
  packages. For instance, for a flambda and afl enabled switch:
  ┌────
  │ opam switch create 4.12.0~alpha2+flambda+afl
  │ --packages=ocaml-variants.4.12.0~alpha2+options,ocaml-option-flambda,ocaml-option-afl
  │ --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git
  └────
  All available options can be listed with "opam search ocaml-option".

  The source code for the alpha is also available at these addresses:

  • <https://github.com/ocaml/ocaml/archive/4.12.0-alpha2.tar.gz>
  • <https://caml.inria.fr/pub/distrib/ocaml-4.12/ocaml-4.12.0~alpha2.tar.gz>

  If you want to test this version, it is advised to install the alpha
  opam repository

  <https://github.com/kit-ty-kate/opam-alpha-repository>

  with
  ┌────
  │ opam repo add alpha git://github.com/kit-ty-kate/opam-alpha-repository.git
  └────
  This alpha repository contains various packages patched with fixes in
  the process of being upstreamed. Once the repository installed, these
  patched packages will take precedence over the non-patched version.

  If you find any bugs, please report them here:
   <https://github.com/ocaml/ocaml/issues>


ez_subst.0.1.0 and ez_cmdliner.0.2.0
════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-ez-subst-0-1-0-and-ez-cmdliner-0-2-0/6888/1>


Fabrice Le Fessant announced
────────────────────────────

  I am please to announce the new releases of two opam packages:
  `ez_subst' and `ez_cmdliner'. We use both of them as dependencies of
  `drom' (and use `drom' to manage them).

  • `ez_subst' is a simple library to perform string replacements in
    strings. It can be seen as a replacement for `Printf' when you are
    lost with too many `%s' in one format, or a replacement for
    `Buffer.add_substitute' when you want a more control. Replacements
    are chosen by functions, and can be separately specified using
    optional arguments ``brace' (for `${var}'), ``paren' (for `$(var)'),
    ``bracket' (for `$[var]') and ``var' (for `$alphanum'). Separator
    `$' can be changed, and notation can be symmetric (`%{x}%').

    <https://ocamlpro.github.io/ez_subst>
    <https://ocamlpro.github.io/ez_subst/doc/ez_subst/Ez_subst/V1/EZ_SUBST/index.html>

    For example:
    ┌────
    │ open Ez_subst.V1 (* versionned interface *)
    │ 
    │ let s = EZ_SUBST.string ~brace:(fun ctxt n -> string_of_int
    │    (ctxt + int_of_string n)) ~ctxt:3 "${4} ${5}"
    │ 
    │ let s = EZ_SUBST.string ~sep:'!'  ~paren:(fun () s ->
    │    String.uppercase s) ~ctxt:() "!(abc) !(def)"
    │ 
    │ let s = EZ_SUBST.string ~sym:true ~sep:'%' ~brace:(fun ctxt_ s
    │    -> ctxt ^ " " ^ s) ~ctxt:"Hello" "%{John}% %{Sandy}%"
    │ 
    │ let s = EZ_SUBST.string_from_list ~default:"unknown" [ "name",
    │    "Doe"; "surname", "John" ] "${name} $(surname) is missing"
    └────

  • `ez_cmdliner' is a simple layer over `cmdliner' to provide an
    interface à la `Arg' module. It provides support for a one-command
    and sub-commands modes. It also provides a ReST generator to
    document sub-commands and integrate the documentation in a Sphinx
    documentation (to use with `drom' for example).

    <https://ocamlpro.github.io/ez_cmdliner>

    For example:

    ┌────
    │ open Ezcmd.V2
    │ let cmd_new =  EZCMD.sub "new"   (* for `drom new` *)
    │  ~args: [
    │   [ "dir" ],  Arg.String (fun s -> dir := Some s),
    │      EZCMD.info ~docv:"DIRECTORY"
    │       "Dir where package sources are stored (src by default)";
    │   [ "library" ],  Arg.Unit (fun () -> skeleton := Some "library"),
    │      EZCMD.info "Project contains only a library";
    │   [ "i"; "inplace" ], Arg.Set inplace, (* for `-i` or `--inplace` *)
    │       EZCMD.info "Create project in the the current directory";
    │   [],    Arg.Anon (0, fun name -> project_name := Some name),
    │       EZCMD.info ~docv:"PROJECT" "Name of the project"
    │  ]
    │  ~doc:"Create a new project"
    │  (fun () ->
    │     action ~name:!project_name ~skeleton:!skeleton ~dir:!dir
    │       ~inplace:!inplace ~args)
    │  ~man: [
    │    `S "DESCRIPTION";
    │    `Blocks [
    │      `P "This command performs the following actions:";
    │    ]
    │ ]
    │ let () = EZCMD.main_with_subcommands ~name:"drom" ~version:"0.1.0"
    │    ~doc:"Create and manage an OCaml project" ~man:[] ~argv [ cmd_new ]
    │    ~common_args
    └────

  Both packages are now available in opam repository.


New release of Menhir (20201201)
════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-new-release-of-menhir-20201201/6892/1>


François Pottier announced
──────────────────────────

  I would like to announce a new release of Menhir, the LR(1) parser
  generator for OCaml. The most prominent new features are intended to
  improve the comfort of the machinery that allows producing custom
  syntax error messages: a demo of this machinery has been added, new
  library functions have been added so as to make it easier to use, and
  the commands that deal with `.messages' files have been improved. An
  excerpt of the changelog appears below.

  ┌────
  │ opam update
  │ opam upgrade menhir
  └────

  Happy parsing!


2020/12/01
╌╌╌╌╌╌╌╌╌╌

  • The module `MenhirLib.ErrorReports' is extended with new functions:
    `wrap_supplier', `extract', `sanitize', `compress', `shorten',
    `expand'.

  • The new module `MenhirLib.LexerUtil' offers a few functions that
    help reading a file, setting up a lexing buffer, printing source
    code positions, etc.

  • The new demo `calc-syntax-errors' demonstrates how to produce
    customized syntax error messages.

  • The new command `--merge-errors' merges two `.messages' files. It
    can be useful when two or more users have independently produced
    partial `.messages' files and wish to combine their work.
    (Suggested by Gabriel Scherer and François Bobot.)

  • The commands that read `.messages' files have been hardened so as to
    tolerate situations where a sentence mentions a nonexistent symbol
    or does not lead to an error state. When such a sentence is
    encountered, an error message is produced on the standard error
    channel; then, this sentence is ignored and processing
    continues. (As an exception, the command `--compile-errors' refuses
    to proceed in the presence of such sentences.)


2020/11/22
╌╌╌╌╌╌╌╌╌╌

  • The new command line switch `--dump-resolved' writes a description
    of the automaton to the file `.automaton.resolved' after all
    conflicts have been resolved and after extra reductions have been
    introduced. This file also shows which states have a default
    reduction.

  • The command line switch `--dump' writes a description of the
    automaton to the file `.automaton' after benign conflicts have been
    silently resolved, but *before* severe conflicts are resolved and
    before extra reductions are introduced. (This behavior is
    unchanged.) The manner in which end-of-stream conflicts are
    displayed in this file has been improved.

  • In the files `.automaton' and `.automaton.resolved', the reduction
    table in each state is now presented in a much more compact and
    readable way.

  • In the files `.automaton' and `.automaton.resolved', the known
    suffix of the stack in each state is now explicitly shown. (Although
    it can be deduced from the LR(1) items, showing it helps.)

  • Document the problem caused by placing a module alias declaration in
    an `.mly' file. (See *Questions and Answers* in the manual.)

  • Turn off a costly internal well-formedness assertion.  This allows a
    30% speedup in the construction of large automata and in the
    conflict explanation process. (Reported by Joe.)


http-multipart-formdata 1.0.0
═════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-http-multipart-formdata-1-0-0/6893/1>


Bikal Lem announced
───────────────────

  It is my pleasure to announce the release of http-multipart-formdata
  v1.0.0. As the name suggests, the library implements functionality to
  allow HTTP file uploads and form processing. Tangentially, it
  implements the standard [RFC 7578 - Returning Values from Forms:
  multipart/form-data] which is the standard browsers use to send form
  data to a web server.

  I developed this library as part of my endeavour to create ocaml web
  applications.

  It is also an example of the parser construction library [reparse]
  which I also released a few days ago.

  • [http-multipart-formdata]
  • [API docs]


[RFC 7578 - Returning Values from Forms: multipart/form-data]
<https://tools.ietf.org/html/rfc7578>

[reparse] <https://discuss.ocaml.org/t/ann-reparse-2-0-0/6868/3>

[http-multipart-formdata]
<https://github.com/lemaetech/http-multipart-formdata>

[API docs] <https://lemaetech.co.uk/http-multipart-formdata/>


Multicore OCaml: November 2020
══════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/multicore-ocaml-november-2020/6899/1>


Anil Madhavapeddy announced
───────────────────────────

  Welcome to the November 2020 Multicore OCaml report! This update along
  with the [previous updates] have been compiled by @shakthimaan,
  @kayceesrk, and @avsm.

  *Multicore OCaml:* Since the support for systhreads has been merged
  last month, many more ecosystem packages compile.  We have been doing
  bulk builds (using a specialised [opam-health-check instance]) against
  the opam repository in order to chase down the last of the lingering
  build bugs. Most of the breakage is around packages using C stubs
  related to the garbage collector, although we did find a few actual
  multicore bugs (related to the thread machinery when using
  dynlink). The details are under "ecosystem" below. We also spent a lot
  of time on optimising the stack discipline in the multicore compiler,
  as part of writing a draft paper on the effect system (more details on
  that later).

  *Upstream OCaml:* The [4.12.0alpha2 release] is now out, featuring the
  dynamic naked pointer checker to help make your code only used
  external pointers that are boxed. Please do run your codebase on it to
  help prepare.  For OCaml 4.13 (currently the `trunk') branch, we had a
  full OCaml developers meeting where we decided on the worklist for
  what we're going to submit upstream.  The major effort is on [GC safe
  points] and not caching the [minor heap pointer], after which the
  runtime domains support has all the necessary prerequisites upstream.
  Both of those PRs are highly performance sensitive, so there is a lot
  of poring over graphs going on (notwithstanding the irrepressible
  @stedolan offering [a massive driveby optimisation]).

  *Sandmark Benchmarking:* The lockfree and Graph500 benchmarks have
  been added and updated to Sandmark respectively, and we continue to
  work on the tooling aspects. Benchmarking tests are also being done on
  AMD, ARM and PowerPC hardware to study the performance of the
  compiler. With reference to stock OCaml, the safepoints PR has now
  landed for review.

  As with previous updates, the Multicore OCaml tasks are listed first,
  which are then followed by the progress on the Sandmark benchmarking
  test suite. Finally, the upstream OCaml related work is mentioned for
  your reference.


[previous updates] <https://discuss.ocaml.org/tag/multicore-monthly>

[opam-health-check instance] <http://check.ocamllabs.io:8082>

[4.12.0alpha2 release]
<https://discuss.ocaml.org/t/ocaml-4-12-0-second-alpha-release/6887>

[GC safe points] <https://github.com/ocaml/ocaml/pull/10039>

[minor heap pointer] <https://github.com/ocaml/ocaml/pull/9876>

[a massive driveby optimisation]
<https://github.com/ocaml/ocaml/pull/10039#issuecomment-733912979>

Multicore OCaml
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

◊ Ongoing

  • [ocaml-multicore/ocaml-multicore#439] Systhread lifecycle work

    An improvement to the initialization of systhreads for general
    resource handling, and freeing up of descriptors and stacks. There
    now exists a new hook on domain termination in the runtime.

  • [ocaml-multicore/ocaml-multicore#440] `ocamlfind ocamldep' hangs in
    no-effect-syntax branch

    The `nocrypto' package fails to build for Multicore OCaml
    no-effect-syntax branch, and ocamlfind loops continuously. A minimal
    test example has been created to reproduce the issue.

  • [ocaml-multicore/ocaml-multicore#443] Minor heap allocation startup
    cost

    An issue to keep track of the ongoing investigations on the impact
    of large minor heap size for OCaml Multicore programs. The
    sequential and parallel exeuction run results for various minor heap
    sizes are provided in the issue.

  • [ocaml-multicore/ocaml-multicore#446] Collect GC stats at the end of
    minor collection

    The objective is to remove the use of double buffering in the GC
    statistics collection by using the barrier present during minor
    collection in the parallel_minor_gc schema. There is not much
    slowdown for the benchmark runs, normalized against stock OCaml as
    seen in the illustration.
    <https://aws1.discourse-cdn.com/standard11/uploads/ocaml/original/2X/7/7ea3f6d4aed319353e711ad8d75acb5093a087ad.png>


  [ocaml-multicore/ocaml-multicore#439]
  <https://github.com/ocaml-multicore/ocaml-multicore/pull/439>

  [ocaml-multicore/ocaml-multicore#440]
  <https://github.com/ocaml-multicore/ocaml-multicore/issues/440>

  [ocaml-multicore/ocaml-multicore#443]
  <https://github.com/ocaml-multicore/ocaml-multicore/issues/443>

  [ocaml-multicore/ocaml-multicore#446]
  <https://github.com/ocaml-multicore/ocaml-multicore/pull/446>


◊ Completed

  ◊ Upstream

    • [ocaml-multicore/ocaml-multicore#426] Replace global roots
      implementation

      This PR replaces the existing global roots implementation with
      that of OCaml's `globroots', wherein the implementation places
      locks around the skip lists. In future, the `Caml_root' usage will
      be removed along with its usage in globroots.

    • [ocaml-multicore/ocaml-multicore#427] Garbage Collector colours
      change backport

      The [Garbage Collector colours change] PR from trunk for the major
      collector have now been backported to Multicore OCaml. This
      includes the optimization for `mark_stack_push', the `mark_entry'
      does not include `end', and `caml_shrink_mark_stack' has been
      adapted from trunk.

    • [ocaml-multicore/ocaml-multicore#432] Remove caml_context push/pop
      on stack switch

      The motivation to remove the use of `caml_context' push/pop on
      stack switches to make the implementation easier to understand,
      and to be closer to upstream OCaml.


    [ocaml-multicore/ocaml-multicore#426]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/426>

    [ocaml-multicore/ocaml-multicore#427]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/427>

    [Garbage Collector colours change]
    <https://github.com/ocaml/ocaml/pull/9756>

    [ocaml-multicore/ocaml-multicore#432]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/432>


  ◊ Stack Improvements

    • [Fix stack overflow on scan stack#431] Fix issue 421: Stack
      overflow on scan stack

      The `caml_scan_stack' now uses a while loop to avoid a stack
      overflow corner case where there is a deep nesting of fibers.

    • [ocaml-multicore/ocaml-multicore#434] DWARF fixups for effect
      stack switching

      The PR provides fixes for `runtime/amd64.S' on issues found using
      a DWARF validator. The patch also cleans up dead commented out
      code, and updates the DWARF information when we do
      `caml_free_stack' in `caml_runstack'.

    • [ocaml-multicore/ocaml-multicore#435] Mark stack overflow backport

      The mark-stack overflow implementation has been updated to be
      closer to trunk OCaml. The pools are added to a skiplist first to
      avoid any duplicates, and the pools in `pools_to_rescan' are
      marked later during a major cycle. The result of the `finalise'
      benchmark time difference with mark stack overflow is shown below:

      <https://aws1.discourse-cdn.com/standard11/uploads/ocaml/optimized/2X/e/ee388eb5cd9cb9d5bc49f1ec8cc2f205fd350bf0_2_1380x434.png>

    • [ocaml-multicore/ocaml-multicore#437] Avoid an allocating C call
      when switching stacks with continue

      The `caml_continuation_use' has been updated to use
      `caml_continuation_use_noexc' and it does not throw an
      exception. The allocating C `caml_c_call' is no longer required to
      call `caml_continuation_use_noexc'.

    • [ocaml-multicore/ocaml-multicore#441] Tidy up and more commenting
      of caml_runstack in amd64.S

      The PR adds comments on how stacks are switched, and removes
      unnecessary instructions in the x86 assembler.

    • [ocaml-multicore/ocaml-multicore#442] Fiber stack cache (v2)

      Addition of stack caching for fiber stacks, which also fixes up
      bugs in the test suite (DEBUG memset, order of initialization). We
      avoid indirection out of `struct stack_info' when managing the
      stack cache, and efficiently calculate the cache freelist bucket
      for a given stack size.


    [Fix stack overflow on scan stack#431]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/431>

    [ocaml-multicore/ocaml-multicore#434]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/434>

    [ocaml-multicore/ocaml-multicore#435]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/435>

    [ocaml-multicore/ocaml-multicore#437]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/437>

    [ocaml-multicore/ocaml-multicore#441]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/441>

    [ocaml-multicore/ocaml-multicore#442]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/442>


  ◊ Ecosystem

    • [ocaml-multicore/lockfree#5] Remove Kcas dependency

      The `Kcas.Wl' module is now replaced with the Atomic module
      available in Multicore stdlib. The exponential backoff is
      implemented with `Domain.Sync.cpu_relax'.

    • [ocaml-multicore/domainslib#21] Point to the new repository URL

      Thanks to Sora Morimoto (@smorimoto) for providing a patch that
      updates the URL to the correct ocaml-multicore repository.

    • [ocaml-multicore/multicore-opam#40] Add multicore Merlin and
      dot-merlin-reader

      A patch to merlin and dot-merlin-reader to work with Multicore
      OCaml 4.10.

    • [ocaml-multicore/ocaml-multicore#403] Segmentation fault when
      trying to build Tezos on Multicore

      The latest fixes on replacing the global roots implementation, and
      fixing the STW interrupt race to the no-effect-syntax branch has
      resolved the issue.


    [ocaml-multicore/lockfree#5]
    <https://github.com/ocaml-multicore/lockfree/pull/5>

    [ocaml-multicore/domainslib#21]
    <https://github.com/ocaml-multicore/domainslib/pull/21>

    [ocaml-multicore/multicore-opam#40]
    <https://github.com/ocaml-multicore/multicore-opam/pull/40>

    [ocaml-multicore/ocaml-multicore#403]
    <https://github.com/ocaml-multicore/ocaml-multicore/issues/403>


  ◊ Compiler Fixes

    • [ocaml-multicore/ocaml-multicore#438] Allow C++ to use
      caml/camlatomic.h

      The inclusion of extern "C" headers to allow C++ to use
      caml/camlatomic.h for building ubpf.0.1.

    • [ocaml-multicore/ocaml-multicore#447] domain_state.h: Remove a
      warning when using -pedantic

      A fix that uses `CAML_STATIC_ASSERT' to check the size of
      `caml_domain_state' in domain_state.h, in order to remove the
      warning when using -pedantic.

    • [ocaml-multicore/ocaml-multicore#449] Fix stdatomic.h when used
      inside C++ for good

      Update to `caml/camlatomic.h' with extern C++ declaration to use
      it inside C++. This builds upbf.0.1 and libsvm.0.10.0 packages.


    [ocaml-multicore/ocaml-multicore#438]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/438>

    [ocaml-multicore/ocaml-multicore#447]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/447>

    [ocaml-multicore/ocaml-multicore#449]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/449>


  ◊ Sundries

    • [ocaml-multicore/ocaml-multicore#422] Simplify minor heaps
      configuration logic and masking

      A `Minor_heap_max' size is introduced to reserve the minor heaps
      area, and `Is_young' for relying on a boundary check. The
      `Minor_heap_max' parameter can be overridden using the
      OCAMLRUNPARAM environment variable. This implementation approach
      is geared towards using Domain local allocation buffers.

    • [ocaml-multicore/ocaml-multicore#429] Fix a STW interrupt race

      A fix for the STW interrupt race in
      `caml_try_run_on_all_domains_with_spin_work'. The
      `enter_spin_callback' and `enter_spin_data' fields of
      `stw_request' are now initialized after we interrupt other
      domains.

    • [ocaml-multicore/ocaml-multicore#430] Add a test to exercise
      stored continuations and the GC

      The PR adds test coverage for interactions between the GC with
      stored, cloned and dropped continuations to exercise the minor and
      major collectors.

    • [ocaml-multicore/ocaml-multicore#444] Merge branch
      'parallel_minor_gc' into 'no-effect-syntax'

      The `parallel_minor_gc' branch has been merged into the
      `no-effect-syntax' branch, and we will try to keep the
      `no-effect-syntax' branch up-to-date with the latest changes.


    [ocaml-multicore/ocaml-multicore#422]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/422>

    [ocaml-multicore/ocaml-multicore#429]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/429>

    [ocaml-multicore/ocaml-multicore#430]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/430>

    [ocaml-multicore/ocaml-multicore#444]
    <https://github.com/ocaml-multicore/ocaml-multicore/pull/444>


Benchmarking
╌╌╌╌╌╌╌╌╌╌╌╌

◊ Ongoing

  • [ocaml-bench/sandmark#196] Filter benchmarks based on tag

    An enhancement to move towards a generic implementation to filter
    the benchmarks based on tags, instead of relying on custom targets
    such as _macro.json or _ci.json.

  • [ocaml-bench/sandmark#191] Make parallel.ipynb notebook interactive

    The parallel.ipynb notebook has been made interactive with drop-down
    menus to select the .bench files for analysis. The notebook README
    has been merged with the top-level README file. A sample
    4.10.0.orunchrt.bench along with the *pausetimes_multicore.bench
    files have been moved to the test artifacts/ folder for user
    testing.

  • We are continuing to test the use of `opam-compiler' switch
    environment to execute the Sandmark benchmark test suite. We have
    been able to build the dependencies, `orun' and `rungen', the
    `OCurrent' pipeline and its dependencies, and `ocaml-ci' for the
    ocaml-multicore:no-effect-syntax branch. We hope to converge to a
    2.0 implementation with the required OCaml tools and ecosystem.


  [ocaml-bench/sandmark#196]
  <https://github.com/ocaml-bench/sandmark/pull/196>

  [ocaml-bench/sandmark#191]
  <https://github.com/ocaml-bench/sandmark/pull/191>


◊ Completed

  • [ocaml-bench/sandmark#179] [RFC] Classifying benchmarks based on
    running time

    The [Classification of benchmarks] PR has been resolved, which now
    classifies the benchmarks based on their running time:
    • `lt_1s': Benchmarks that run for less than 1 second.
    • `lt_10s': Benchmarks that run for at least 1 second, but, less
      than 10 seconds.
    • `10s_100s': Benchmarks that run for at least 10 seconds, but, less
      than 100 seconds.
    • `gt_100s': Benchmarks that run for at least 100 seconds.

  • [ocaml-bench/sandmark#189] Add environment support for wrapper in
    JSON configuration file

    The OCAMLRUNPARAM arguments can now be passed as an environment
    variable when executing the benchmarks in runtime. The environment
    variables can be specified in the `run_config.json' file, as shown
    below:

    ┌────
    │ {
    │    "name": "orun_2M",
    │    "environment": "OCAMLRUNPARAM='s=2M'",
    │    "command": "orun -o %{output} -- taskset --cpu-list 5 %{command}"
    │  }
    └────

  • [ocaml-bench/sandmark#183] Use crout_decomposition name for
    numerical analysis benchmark

    The `numerical-analysis/lu_decomposition.ml' benchmark has now been
    renamed to `crout_decomposition.ml' to avoid naming confusion, as
    there are a couple of LU decomposition benchmarks in Sandmark.

  • [ocaml-bench/sandmark#190] Bump trunk to 4.13.0

    The trunk version in Sandmark ocaml-versions/ has now been updated
    to use `4.13.0+trunk.json'.

  • [ocaml-bench/sandmark#192] GraphSEQ corrected

    The minor fix for the Kronecker generator has been provided for the
    Graph500 benchmark.

  • [ocaml-bench/sandmark#194] Lockfree benchmarks

    The lockfree benchmarks for both the serial and parallel
    implementation are now included in Sandmark, and it uses the
    `lockfree_bench' tag. The time and speedup illustrations are as
    follows:

    <https://aws1.discourse-cdn.com/standard11/uploads/ocaml/optimized/2X/0/01496cbe634b692538b2863768b4a3ed2e99b68a_2_1380x274.png>
    <https://aws1.discourse-cdn.com/standard11/uploads/ocaml/optimized/2X/6/6e26c55539151cc4c3658ebac20e7807d672adce_2_1380x266.png>


  [ocaml-bench/sandmark#179]
  <https://github.com/ocaml-bench/sandmark/issues/179>

  [Classification of benchmarks]
  <https://github.com/ocaml-bench/sandmark/pull/188>

  [ocaml-bench/sandmark#189]
  <https://github.com/ocaml-bench/sandmark/pull/189>

  [ocaml-bench/sandmark#183]
  <https://github.com/ocaml-bench/sandmark/pull/183>

  [ocaml-bench/sandmark#190]
  <https://github.com/ocaml-bench/sandmark/pull/190>

  [ocaml-bench/sandmark#192]
  <https://github.com/ocaml-bench/sandmark/pull/192>

  [ocaml-bench/sandmark#194]
  <https://github.com/ocaml-bench/sandmark/pull/194>


OCaml
╌╌╌╌╌

◊ Ongoing

  • [ocaml/ocaml#9876] Do not cache young_limit in a processor register

    The removal of `young_limit' caching in a register is being
    evaluated using Sandmark benchmark runs to test the impact change on
    for ARM64, PowerPC and RISC-V ports hardware.

  • [ocaml/ocaml#9934] Prefetching optimisations for sweeping

    The PR includes an optimization of `sweep_slice' for the use of
    prefetching, and to reduce cache misses during GC. The normalized
    running time graph is as follows:

    <https://aws1.discourse-cdn.com/standard11/uploads/ocaml/optimized/2X/4/4d3ea2a50b4a40998c23b23a88ff65bbaadafbbf_2_1380x542.png>

  • [ocaml/ocaml#10039] Safepoints

    A draft Safepoints implementation for AMD64 for the 4.11 branch that
    are implemented by adding a new `Ipoll' operation to Mach. The
    benchmark results on an AMD Zen2 machine are given below:

    <https://aws1.discourse-cdn.com/standard11/uploads/ocaml/optimized/2X/6/6953eb519379800fda791d122ba3ee6e99ef0b79_2_714x998.png>

  Many thanks to all the OCaml users and developers for their continued
  support, and contribution to the project.


  [ocaml/ocaml#9876] <https://github.com/ocaml/ocaml/pull/9876>

  [ocaml/ocaml#9934] <https://github.com/ocaml/ocaml/pull/9934>

  [ocaml/ocaml#10039] <https://github.com/ocaml/ocaml/pull/10039>


Acronyms
╌╌╌╌╌╌╌╌

  • ARM: Advanced RISC Machine
  • DWARF: Debugging With Attributed Record Formats
  • GC: Garbage Collector
  • JSON: JavaScript Object Notation
  • OPAM: OCaml Package Manager
  • PR: Pull Request
  • PR: Pull Request
  • RFC: Request For Comments
  • RISC-V: Reduced Instruction Set Computing - V
  • STW: Stop-The-World
  • URL: Uniform Resource Locator


Seq vs List, optimization
═════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/seq-vs-list-optimization/6885/25>


Deep in this thread, Sacha Ayoun asked and Raphaël Proust said
──────────────────────────────────────────────────────────────

        But then what’s the point of Seq ?

  A bit of a spoiler for an upcoming release of a few of our libraries
  at Nomadic Labs…

  We had a bug report: calls to some RPCs exposed by some of our
  binaries would occasionally cause some lag. One of the root causes of
  the issue was JSON serialisation. The original serialisation scheme
  was intended for a limited range of uses (especially, small sizes) but
  then it was used outside of this intended range and some relatively
  big values were serialised and pushed down the RPC stack.

  To circumvent this, we are about to release
  • a “json lexeme sequence” backend for our serialiser library:
    `construct_seq : 'a encoding -> 'a -> json_lexeme Seq.t' where
    `json_lexeme = Jsonm.lexeme = [ `Null | `Bool of bool | … | `As |
    `Ae | `Os | `Oe ]'
  • a json lexeme sequence to string sequence converter.

  For this second part, we actually have three different converters
  intended for slightly different uses.  They have different
  granularity, they have different allocation profiles, and they make
  slightly different assumption most notably about concurrency:
  • `string_seq_of_json_lexeme_seq : chunk_size_hint:int -> json_lexeme
    Seq.t -> string Seq.t' which uses one (1) internal buffer of size
    `chunk_size_hint'. Consuming one element of the resulting sequence
    causes several json lexemes to be consumed and printed onto the
    internal buffer until it is full. When this happens, a snapshot
    (copy) of the buffer is delivered in the `Cons' cell. So for
    chunk-size-hint of, say, 1Ko, the sequence translator uses roughly
    1Ko of memory and emits 1Ko chunks of memory that the consumer is
    responsible for.
  • `small_string_seq_of_json_lexeme_seq : json_lexeme Seq.t -> string
    Seq.t' which translates each of the lexeme as a single string. It's
    a little bit more than a simple `Seq.map' because it needs to insert
    separators and escape strings. It mostly returns statically
    allocated strings so there are no big allocations at all.
  • `blit_instructions_seq_of_jsonm_lexeme_seq : buffer: bytes ->
    json_lexeme Seq.t -> (bytes * int * int) Seq.t' which works somewhat
    similarly to the first one but uses `buffer' instead of allocating
    its own. And it returns a seq of `(source, offset, length)' which
    are intended to be blitted onto whatever the consumer wants to
    propagates the data too. This barely allocates at all (it currently
    does allocate relatively big chunks when escaping strings, but we
    have planned to improve this in the future. (The sequence returns a
    source to blit; this source is physically equal to `buffer' most of
    the time but not always; specifically, for large strings that are
    present within the json data, the sequence just points to them as a
    source.)

  Note that the description above is a simplification: there is a bit
  more to it than that. Also note that all this is still Work In
  Progress. Check out
  <https://gitlab.com/nomadic-labs/json-data-encoding/-/merge_requests/5>
  (the value to json lexeme sequence code) and
  <https://gitlab.com/nomadic-labs/data-encoding/-/merge_requests/19>
  (the json lexeme sequence to string sequence code).


dap 1.0.0 – Debug Adapter Protocol for OCaml
════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-dap-1-0-0-debug-adapter-protocol-for-ocaml/6903/1>


文宇祥 announced
────────────────

  This is the [debug adapter protocol] library extract from
  [ocamlearlybird]. Include types generated from specification and a DAP
  prioritized JSON RPC implementation. It's useful to implement debug
  adapter in OCaml.

  Debug adapter protocol

  • Project page: <https://github.com/hackwaly/ocaml-dap>
  • Documentation: <https://hackwaly.github.io/ocaml-dap/>


[debug adapter protocol]
<https://microsoft.github.io/debug-adapter-protocol/>

[ocamlearlybird] <https://github.com/hackwaly/ocamlearlybird>

CHANGES:
╌╌╌╌╌╌╌╌

  Initial release.

  • Specification version is 1.43


✂️ form2xml - a tiny cli tool to slice http form-data dumps
══════════════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-form2xml-a-tiny-cli-tool-to-slice-http-form-data-dumps/6912/1>


😷 Marcus Rohrmoser announced
─────────────────────────────

  when doing static web sites, feedback is an issue. form2xml helps you
  keep the server stupid, but still makes form-data feedback possible.

  Just dump the form posts, rsync and merge them into your client-side,
  unix pipe, toolchain.

  form2xml bridges the tooling-gap between http and xml/xslt with utmost
  primitivity in the making. I chose simplicity over compliance because
  form2xml isn't intended to run server-side or unattended. I'm aware of
  excellent prior art, but hesitated to add build dependencies for now
  and rather see if it proves useful as is.

  <https://mro.name/form2xml>


http-multipart-formdata 1.0.1
═════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-http-multipart-formdata-1-0-1/6917/1>


Bikal Lem announced
───────────────────

  I have just released a maintenance release of
  `http-multipart-formadata'. This is a maintenace release to address a
  reported issue.

  [#10 Fix equality]


[#10 Fix equality]
<https://github.com/lemaetech/http-multipart-formdata/issues/10>


Set up OCaml 1.1.4
══════════════════

  Archive: <https://discuss.ocaml.org/t/ann-set-up-ocaml-1-1-4/6926/1>


Sora Morimoto announced
───────────────────────

  We have a changelog since this release.

  By the way, I'm preparing to publish v2 of setup-ocaml. It has a cache
  feature that is entirely independent of GitHub, so you don't have to
  worry about cache limit per repository, and you don't have to spend
  nearly 10 minutes on setup.

  <https://github.com/avsm/setup-ocaml/blob/master/CHANGELOG.md>

  <https://github.com/avsm/setup-ocaml/releases/tag/v1.1.4>


First Public Release (beta) of the Memthol memory profiling visualizer
══════════════════════════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-first-public-release-beta-of-the-memthol-memory-profiling-visualizer/6927/1>


OCamlPro announced
──────────────────

  We are happy to announce the first public release of Memthol, a
  visualizer and analyzer for memory profiling data generated from OCaml
  programs, thanks to the work of Adrien Champion and Vincent Laviron.

  *Memthol* is a visualizer and analyzer for program profiling. It works
  on memory *dumps* containing information about the size and
  (de)allocation date of part of the allocations performed by some
  execution of a program. For information regarding building memthol,
  features, browser compatibility…  refer to the [memthol github
  repository].  *Please note that Memthol, as a side project, is a work
  in progress that remains in beta status for now.*


[memthol github repository] <https://github.com/OCamlPro/memthol>

Memthol's background
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  The Memthol work was started more than a year ago (we had published a
  short introductory paper at the [JFLA2020]). The whole idea was to use
  the previous work originally achieved on [ocp-memprof], and look for
  some extra funding to achieve a usable and industrial version. Then
  came the excellent [memtrace profiler] by Jane Street's team.

  The memtrace format is nicely designed and polished enough to be
  considered a future standard for other tools. This is why Memthol
  supports Jane Street's *dumper* format, instead of our own dumper
  library's.

  Memthol is a self-funded side project, that we think is worth giving
  to the OCaml community. Its approach is valuable, and can be
  complementary. It is released under the free GPL licence v3.

  We welcome any extra funding to achieve a usable and industrial
  version!


[JFLA2020] <http://jfla.inria.fr/jfla2020.html>

[ocp-memprof] <https://memprof.typerex.org/>

[memtrace profiler]
<https://blog.janestreet.com/finding-memory-leaks-with-memtrace/>


[Memthol's features]:
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  • multi-client: open several tabs in your browser for the same
    profiling session to visualize the data separately
  • self-contained: the BUI packs all its static assets, once you have
    the binary you do not need anything else (except a browser)
  • data-splitting: plot several families of data separately in the same
    chart by separating them based on size, allocation lifetime, source
    locations in the allocation callstack, etc.

  Issues are welcome. As Memthol is mostly tested on the Chrome web
  browser, you might experience problems with other browsers. Do not
  hesitate open issues.

  We have designed a mini-tutorial on Memthol available on our github
  repository and our blogpost, which you can find by following this link
  :
  <https://www.ocamlpro.com/2020/12/01/memthol-exploring-program-profiling/>


[Memthol's features] <https://github.com/OCamlPro/memthol>


Exception vs Result
═══════════════════

  Archive: <https://discuss.ocaml.org/t/exception-vs-result/6931/1>


Chas Emerick discussed
──────────────────────

  Last week, @BikalGurung blogged [On Effectiveness of Exceptions in
  OCaml], in part as a follow-up to [his announcement of his parser
  combinator library] [reparse], which eschews `Result'-based error
  handling in favor of exceptions. I've long preferred using `Result'
  (and its equivalents in other languages), and my experience so far
  with OCaml is that that preference is shared by many in the community
  and by authors of key libraries, but I was happy to consider a new
  counterpoint.

  Doing so prompted me to consider my rationale(s) more than I had
  previously, and do some additional reading and research, all of which
  ended up further cementing my pro-`Result' bias. What follows are
  counterpoints to Bikal's two most consequential arguments (in my
  opinion), and some elaboration beyond.  Many thanks to Bikal for his
  posting his experience report!


[On Effectiveness of Exceptions in OCaml]
<https://lemaetech.co.uk/articles/exceptions.html>

[his announcement of his parser combinator library]
<https://discuss.ocaml.org/t/ann-reparse-2-0-0/6868>

[reparse] <https://github.com/lemaetech/reparse/>

Stacktrace / Location Information
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  First, Bikal focuses in on how useful error handling should "allow us
  to efficiently, correctly and accurately identify the source of our
  errors". I agree, but he compares exceptions and `result' on this
  basis like so:

        OCaml exception back traces - or call/stack traces - is
        one such tool which I have found very helpful. It gives
        the offending file and the line number in it. This make
        investigating and zeroing in on the error efficient and
        productive.

        Using result type means you lose this valuable utility
        that is in-built to the ocaml language and the compiler.

  It is true that `Error' does not _implicitly_ carry backtraces as
  exceptions do, but there is nothing preventing one from choosing to
  include a backtrace with a returned error, since OCaml backtraces
  helpfully exist separate from its exception facility:

  ┌────
  │ let b x =
  │   if x > 0
  │   then Ok 0
  │   else Error ("unimplemented", Printexc.get_callstack 10)
  │ 
  │ let a x = b x
  │ 
  │ let _ = match a (int_of_string @@ Sys.argv.(1)) with
  │ 	  | Ok v -> Format.printf "%d at ." v
  │ 	  | Error (msg, stack) ->
  │ 	    Format.fprintf Format.err_formatter "Error: %s at ." msg;
  │ 	    Printexc.print_raw_backtrace stderr stack
  └────

  ┌────
  │ $ ocamlc -g -o demo.exe src/demo.ml
  │ $ ./demo.exe -1
  │ Error: unimplemented
  │ Raised by primitive operation at file "src/demo.ml", line 5, characters 31-56
  │ Called from file "src/demo.ml", line 9, characters 14-47
  └────

  From a strictly ergonomic standpoint, it makes sense to wish that
  e.g. the `Error' constructor were treated specially such that values
  it produced always carried a stack trace (as exceptions do/are), so
  that programmers would not need to opt into it as above. However, that
  would not come without costs, including a maybe-significant runtime
  penalty that might render `Result' a less useful way to _cheaply_
  signal recoverable error conditions (something that other
  exception-dominant languages/runtimes struggle to do given that
  stacktrace generation is far from free).


Correctness
╌╌╌╌╌╌╌╌╌╌╌

  Bikal's final topic was re: correctness, and to what extent using one
  or another error-handling mechanism tangibly affects his work. What he
  says is short enough to reproduce in full:

        I thought this would be the biggest advantage of using
        `result' type and a net benefit. However, my experience of
        *NOT* using it didn't result in any noticeable reduction
        of *correct by construction* OCaml software. Conversely, I
        didn't notice any noticeable improvement on this metric
        when *using* it. What I have noticed over time is that
        abstraction/encapsulation mechanisms and type system in
        particular play by far the most significant role in
        creating *correct by construction* OCaml software.

  There's a lot left undefined here: what "correct by construction"
  might mean generally, what it means in the context of OCaml software
  development, how it could be measured (_is_ there a metric, or are we
  just reckoning here?), and so on.

  While reminding myself of exactly what "correct by construction"
  meant, I came across a fantastic lecture by Martyn Thomas[1] that
  neatly defines it (and goes into some detail of how to go about
  achieving it); from the accompanying lecture notes[2]:

        …you start by writing a requirements specification in a
        way that makes it possible to analyse whether it contains
        logical omissions or contradictions. Then you develop the
        software in a way that provides very strong evidence that
        the program implements the specification (and does nothing
        else) and that it will not fail at runtime. We call this
        making software “correct by construction”, because the way
        in which the software is constructed guarantees that it
        has these properties.

  While we aren't working with anything as formal as a theorem prover
  when we are programming in OCaml, it does provide us with a tremendous
  degree of certainty about how our programs will behave. One of the
  greatest sources of that certainty is its default of requiring
  functions and pattern matches to be exhaustive with regard to the
  domain of values of the type(s) they accept; i.e. a function that
  accepts a `result' must provide cases for all of its known
  constructors:

  ┌────
  │ let get = function Ok v -> v
  └────
  ┌────
  │ $ ocamlc -g -o demo.exe src/demo.ml
  │ File "src/demo.ml", line 15, characters 10-28:
  │ 15 | let get = function Ok v -> v
  │                ^^^^^^^^^^^^^^^^^^
  │ Warning 8: this pattern-matching is not exhaustive.
  │ Here is an example of a case that is not matched:
  │ Error _
  └────

  This one way we "provide evidence" to the OCaml compiler that our code
  does not not contain "logical omissions", to use Prof. Thomas'
  nomenclature.

  There are ways to relax this requirement, though. Aside from simply
  telling the compiler to not bother us with its concerns via an
  attribute:

  ┌────
  │ let get = function Ok v -> v [@@warning "-8"]
  └────

  …we could simply use exceptions instead. For example, an
  exception-based variant of the program I started with earlier:

  ┌────
  │ exception Unimplemented
  │ 
  │ let a x =
  │   if x > 0
  │   then 0
  │   else raise Unimplemented
  │ 
  │ let _ = Format.printf "%d at ." @@ a (int_of_string @@ Sys.argv.(1))
  └────

  This approach is less correct by any measure: the `Unimplemented'
  exception is not indicated in the signature of `a', making it easy to
  call `a' without handling the exception, or being aware of its
  possibility at all. Insofar as the exceptions in question are not
  intended to be fatal, program-terminating errors, this approach
  absolutely increases the potential for "logical omissions", increases
  the potential for programs to fail at runtime, and hobbles the
  exhaustivity guarantees that the OCaml compiler provides for us
  otherwise.

  Later in the reparse announcement thread, @rixed said (presumably in
  response to this tension):

        If only we had a way to know statically which exceptions
        can escape any functions that would be the best of both
        worlds!

  And indeed, this approach of incorporating known thrown exception
  types into function signatures is a known technique, (in)famously
  included in Java from the beginning (called *checked exceptions*), but
  widely disdained. I suspect that disdain was more due to Java's other
  weaknesses in exception handling than the principal notion of
  propagating exception types in function/method signatures. It would be
  interesting to see something like checked exceptions experimented with
  in OCaml, though it may be that doing so would nullify one of the
  primary benefits that those preferring exceptions enjoy (perceived
  improved aesthetics/clarity), and/or the work needed to achieve this
  might approximate the typed effect handling approaches that @lpw25 et
  al. have been pursuing for some time.

  [1]: *Making Software 'Correct by Construction'*
  <https://www.gresham.ac.uk/lectures-and-events/making-software-correct-by-construction>
  [2]:
  <https://www.gresham.ac.uk/lecture/transcript/download/making-software-correct-by-construction/>


bnguyenvanyen said
──────────────────

  Just chiming in to note that there has been an interesting discussion
  on this topic two years ago:
  <https://discuss.ocaml.org/t/specific-reason-for-not-embracing-the-use-of-exceptions-for-error-propagation/1666/40>

  It's also interesting to note that that discussion also ended up
  talking about typed effects.  As I understand it, they would indeed
  subsume checked exceptions, and I'm quite excited about them.


Yawar Amin also said
────────────────────

  Cristiano Calcagno has been doing some pretty interesting work on
  this:
  <https://github.com/reason-association/reanalyze/blob/72712393459d7e132c78e0700abffc5fc4cd09b8/EXCEPTION.md>

  Let me quote the central concept from there:

        The exception analysis is designed to keep track
        statically of the exceptions that might be raised at
        runtime. It works by issuing warnings and recognizing
        annotations. Warnings are issued whenever an exception is
        raised and not immediately caught. Annotations are used to
        push warnings from he local point where the exception is
        raised, to the outside context: callers of the current
        function. Nested functions need to be annotated
        separately.


Later in the thread, Chet Murthy said
─────────────────────────────────────

  I'm going to address the general issue of "programming with monads",
  and not specifically the result monad, b/c I think it's just an
  instance of the general phenomenon.

  TL;DR In 1992, when someone told me about "programming with monads", I
  replied that I *already* programmed with monads: I used the "SML
  Monad".  And this LtU post seems to me to be pithily succinct
  (<http://lambda-the-ultimate.org/node/5504> )

  (1) when we talk about program correctness, we mean two things:
  reasoning about programs, and type-safety.  I'll address each in turn
  below.

  (2) All monadic transformations of which I am aware (exceptions,
  state, control, I/O) are direct equivalents to the "standard
  semantics" for such language-features, e.g. as described in Michael
  J.C.  Gordon's book /The Denotational Description of Programming
  Languages/.  *Programming with monads is programming with some
  combinators and macros, on the right-hand-side of the denotational
  interpreters* in that book.

  (3) "reasoning about programs" has historically meant "equational
  reasoning", and IIUC, Felleisen&Sabry's work (and follow-on works)
  proved pretty conclusively that anything you can prove about the
  right-hand-side of the denotational semantics interpeter defiition,
  you can "pull back" to equational reasoning with extra rules, on the
  left-hand-side of the DS interpreter.

  (4) "type safety":

        If only we had a way to know statically which exceptions
        can escape any functions

  There was a cottage industry of "effect type systems" to
  capture/reason-about exceptions, state, maybe other things, decades
  ago.  They were judged too cumbersome for programmers to use, and
  hence died-out.  >10yr ago there was a caml-light (OCaml?) variant
  that checked exceptions in function-types; it didn't catch on.  Look
  at Java, where some exceptions are "checked" and others are not: some
  exceptions, it's just too cumbersome to track in the type system.  And
  so either your "result" monad only captures some of the exceptions, or
  it's going to be wildly cumbersome.

  (5) Monads are less-efficient than direct-style, memory-wise.  For me,
  the moment in 1992 when I (an avowed SML/NJ bigot) became convinced of
  the superiority of caml-light (notwithstanding 2.5x slower on average)
  was when I realized that it was -so- much less memory-intensive.
  Because it didn't allocate stack-frames on the heap, and closures
  started out on the stack and only moved to the heap on-demand.  Henry
  Baker made the observation >20yr ago that the stack is a form of
  nursery.  Writing in monadic style is sacrificing this obviously
  performance advantage.  In the era of multicore, arguments made back
  then about memory, can be recast as arguments about the cache today,
  since (as hardware designers put it) "memory is at infinity" today.

  P.S. And yet, I use monads sometimes, too.  Rarely.  But for instance,
  it's a good model for (e.g.)  writing a type-checker that wants to
  type-check a list of expressions (no unification, hence no
  side-effects) and not stop at the firs type-error, but rather gather
  together errors from all the expressions in the list, and produce an
  error with all of them combined.  So the type-checker at the top of
  each member of the list catches any raised exception, stores it in an
  accumulator, and goes on to the rest of the list; at the end of the
  list, if the accumulator is empty, it returns the list of
  result-types; otherwise it raises an exception containing list of
  errors stored in the accumulator.

  It's rare, and if the Result monad didn't exist, I'd hack something
  together, but …. it's literally the only use I can think of, that
  wasn't driven by a library (e.g. `bos') using the Result monad itself
  (and my needing to use that library).

  And this *efficiency* is the real reason that exception-based
  backtraces are better: IIUC, OCaml exceptions are *really* cheap
  because they don't materialize that backtrace until demanded.  It
  means that you have to be careful what code you put between the
  "try-with" and the demand for the backtrace, but it's *efficient*.
  Materializing the backtrace for every exception raised would be
  ….. pretty horrendously inefficient, and yet that's what you have to
  do if you use the result monad.


Malcolm also said
─────────────────

  I wrote two blog posts on my experience using `result' awhile ago,
  linked below.  Much of it still holds.  Many of the pain points others
  have mentioned do exist, but in my judgement, *given the current state
  of Ocaml*, results are strictly better (at the very least at the API
  boundary, assuming you can convince yourself no exceptions escape it)
  than exceptions.  I also believe that the reasonable error values are
  necessary.  For example, I know some APIs like some variation of `('a,
  string) result' which, IMO, is not a great API as I end up comparing
  strings and hoping the string value is actually part of the API and
  not some rando value tossed in there.  Double for when meaningful
  aspects of the error are encoded in the string and I have to decode it
  to decide what to do.

  For my own things I do require that all errors are convertible to a
  string so I can just show them to the user, this is especially
  important for development and debugging, IME.  This is one of the few
  places where I do wish we had something like type classes so I could
  do something like:

  ┌────
  │ foo ()
  │ >>= function
  │ | Ok () -> yadda
  │ | Error err -> show err
  └────

  YMMV

  <http://functional-orbitz.blogspot.com/2013/01/experiences-using-resultt-vs-exceptions.html>

  <http://functional-orbitz.blogspot.com/2013/01/introduction-to-resultt-vs-exceptions.html>


Making web calls to OCaml
═════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/making-web-calls-to-ocaml/6932/1>


Peter Fishman asked
───────────────────

  Hi, I am new to OCaml and in fact, I'm not a even a programmer
  (although I did study CS at Cornell back in the 80's and learned
  functional programming in a language called scheme.)  I am thinking
  about developing financial wellness web applications with the
  underlying computations in OCaml, but with the user interface in
  something else - like java script.  How would a java script website
  make a call to an Ocaml program (or function)?  Or put another way,
  can I publish a financial model built in OCaml so that a web (or
  mobile) application could call it - passing arguments to the function
  and receiving back the result of evaluating the functional expression?
  My apologies if this is not asked correctly or if it is a very basic
  question, but I am not sure I have the right terminology to ask the
  question properly!  Help is appreciated!


Wojtek Czekalski replied
────────────────────────

  You can, there are multiple ways to achieve what you want. If I
  understand correctly you want to build a web server in OCaml and a web
  app front end. Here's a list of what different projects used:
  <https://discuss.ocaml.org/t/your-production-web-stack-in-2020/6691/11>

  Edit: To elaborate because I realized I didn't answer your question,
  typically you'd have a frontend which uses something like [rest] or
  [graphql] to fetch data from your server. There's a lot to unpack
  here. I'm sure you'll be able to pull it off but if you're not
  comfortable with programming make sure that you approach the problem
  gradually and make sure to avoid analysis paralysis.


[rest] <https://en.wikipedia.org/wiki/Representational_state_transfer>

[graphql] <https://en.wikipedia.org/wiki/GraphQL>


Yawar Amin also replied
───────────────────────

  Hi, a couple of thoughts here. As @wokalski said, you will need to set
  up a server application, and a web frontend. I don't know much about
  your background but, my guess is you would like to avoid complexity
  and keep things simple. Personally here's what I would recommend:

  1. Write a simple command-line application, in the style of a [Unix
     filter], in OCaml that takes 'requests' in the form of plain text
     on standard input and prints its calculation result to standard
     output. E.g., to take an input of `add 2 2' and output `4', it
     could work like this:

     ┌────
     │ $ echo 'add 2 2' | my_calculator.exe
     │ 4
     └────

  2. Next, use [websocketd] to wrap your calculator tool and serve it
     over WebSocket, which is a standard Web technology that allows
     clients to continuously talk to servers (2-way communication). So,
     clients could send a plain text command like `add 2 2' (note,
     exactly the same as you would have on the command line), and get
     back a response `4'.

  3. Finally, write a web application (just some HTML and JavaScript)
     that connects to the WebSocket server from step (2) and sends and
     receives messages. Here is an example of that:
     <https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API/Writing_WebSocket_client_applications>

  The reason I am recommending this strategy, is to let you start small
  and simple, and skip over much of the complexity of dealing with
  modern web application development. You can focus on writing your
  calculator as a simple command-line tool, and 'outsource' the server
  part to a specialized tool.

  Final thought: if you are working on a financial wellness tool, you
  almost certainly need decimal arithmetic (as opposed to binary
  arithmetic from OCaml's built-in float type). You will want to use a
  decimal package like <https://github.com/janestreet/bigdecimal> , or
  (disclaimer: mine) <https://opam.ocaml.org/packages/decimal/> .

  Good luck!


[Unix filter] <https://en.wikipedia.org/wiki/Filter_(software)#Unix>

[websocketd] <https://github.com/joewalnes/websocketd>


😷 Marcus Rohrmoser also replied
────────────────────────────────

  @peter I think I'm doing something similar – a simple web tool for
  geographic calculations from character sequences called geohash to gps
  coordinate pairs and vice versa. Here is it:
  <https://demo.mro.name/geohash.cgi/u154>. You'll find the source
  there, too.

  Key is, I scale towards n=1, need no state.

  The backend is <200 LOC to handle all the http stuff (there isn't
  much, no auth, no state, no cookies) and another ~100 LOC for the
  actual computation.

  1 dependency, no 'modern' web toolkit, no client libs/frameworks, no
  concurrency


wasmtime 0.0.1: lightweight WebAssembly runtime
═══════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-wasmtime-0-0-1-lightweight-webassembly-runtime/6936/1>


Laurent Mazare announced
────────────────────────

  We just released a first version of a package providing OCaml bindings
  to the [wasmtime] WebAssembly runtime. The package is available on
  opam and can be found in this [GitHub repo]. It can be used to run
  .wasm modules in an OCaml process, including modules making system
  calls through [WASI].  For now, the package only provides a low-level
  api closely matching the Rust implementation. We intend to provide a
  higher level api on top of this.  The GitHub repo contains various
  examples in the `tests' directory which reproduce some examples from
  the main wasmtime repo.  Feedback/issue reports are very welcome!


[wasmtime] <https://wasmtime.dev>

[GitHub repo] <https://github.com/LaurentMazare/ocaml-wasmtime>

[WASI] <https://wasi.dev/>


First release of Lwt-exit
═════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-first-release-of-lwt-exit/6938/1>


Raphaël Proust announced
────────────────────────

  On behalf of [Nomadic Labs], I'm happy to announce the first release
  of Lwt-exit, a small opinionated library to cleanly handle exits and
  signals in applications that use Lwt.

  The library is available through opam: `opam install lwt-exit', hosted
  on gitlab: <https://gitlab.com/nomadic-labs/lwt-exit>, distributed
  under the MIT license:
  <https://gitlab.com/nomadic-labs/lwt-exit/-/blob/master/LICENSE> and
  the documentation is available online:
  <https://nomadic-labs.gitlab.io/lwt-exit/>

  This library is used in the [Tezos codebase] to clean up system
  resources (flush buffered writes, cleanly close p2p connections, etc.)
  during exits. It is also used to attach signal handlers (both for
  interactive use via Ctrl+C and for daemonisation via systemctl).


[Nomadic Labs] <https://nomadic-labs.com/>

[Tezos codebase] <https://gitlab.com/tezos/tezos>


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]


[send me a message] <mailto:alan.schmitt at polytechnique.org>

[the archive] <http://alan.petitepomme.net/cwn/>

[RSS feed of the archives] <http://alan.petitepomme.net/cwn/cwn.rss>

[online] <http://lists.idyll.org/listinfo/caml-news-weekly/>

[Alan Schmitt] <http://alan.petitepomme.net/>

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.idyll.org/pipermail/caml-news-weekly/attachments/20201208/3aef6279/attachment-0001.html>


More information about the caml-news-weekly mailing list