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

Alan Schmitt alan.schmitt at polytechnique.org
Tue Jul 2 02:02:15 PDT 2019


Hello

Here is the latest OCaml Weekly News, for the week of June 25 to 
July
02, 2019.

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

Learn Ocsigen: Graffiti tutorial updated
Release of OCamlFormat 0.10
Ocaml 4.09.0+beta1
Parallel and distributed execution of command lines, pardi!
Other OCaml News
Old CWN


Learn Ocsigen: Graffiti tutorial updated
════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/learn-ocsigen-graffiti-tutorial-updated/3983/1>


Vincent Balat announced
───────────────────────

  [Graffiti tutorial] explains step by step how to write a 
  [multi-user
  client-server drawing application] in OCaml.

  It is the best starting point for beginners with Ocsigen.

  An updated version of this tutorial is now online, thanks to
  [corentinjuvigny] and [chrismamo1].

  Please report any problem (mistakes etc.) [here].


[Graffiti tutorial] 
<http://ocsigen.org/tuto/latest/manual/application>

[multi-user client-server drawing application]
<http://ocsigen.org/graffiti>

[corentinjuvigny] <https://github.com/corentinjuvigny>

[chrismamo1] <https://github.com/chrismamo1>

[here] <https://github.com/ocsigen/tuto/issues>


Release of OCamlFormat 0.10
═══════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-release-of-ocamlformat-0-10/3988/1>


Guillaume Petiot announced
──────────────────────────

  *Release of OCamlFormat 0.10*

  We are pleased to announce the release of OCamlFormat 0.10 
  (available
  on opam).

  There have been numerous changes since the last release, so here 
  is a
  comprehensive list of the new features and breaking changes to 
  help
  the transition from OCamlFormat 0.9.

  `ocamlformat-0.10' now works on the 4.08 AST, although the 
  formatting
  should not differ greatly from the one of `ocamlformat-0.9' in 
  this
  regard.  Please note that it is necessary to build `ocamlformat' 
  with
  4.08 to be able to parse new features like `let*'.

  Upgrading from `ocamlformat-0.9' requires to install the 
  following
  dependencies:
  • ocaml-migrate-parsetree >= 1.3.1 (upgrade)
  • uuseg >= 10.0.0 (new)
  • uutf >= 1.0.1 (upgrade)

  This release focuses on preserving the style of the original 
  source
  and on handling more `ocp-indent' options.


Style preservation
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

◊ Expression grouping

  The new option `exp-grouping' has been added to preserve the 
  keywords
  `begin~/~end' that are used to delimit expressions instead of
  parentheses. `exp-grouping=parens' always uses parentheses to 
  delimit
  expressions. `exp-grouping=preserve' preserves the original 
  grouping
  syntax (parentheses or `begin~/~end').


◊ Horizontal alignment

  Horizontal alignment is something that users often use to make
  pattern-matching or type declarations easier to read, and it is 
  a
  feature that has been requested many times. Three new options 
  have
  been added to horizontally align the lines.

  `align-cases' horizontally aligns the match/try cases:
  ┌────
  │ let fooooooooooo =
  │   match foooooooooooooooooooooooo with
  │   | Bfooooooooooooooooo -> foooooooooooo
  │   | C (a, b, c, d)      -> fooooooooooooooooooo
  │   | _                   -> fooooooooooooooooooo
  └────

  `align-constructors-decl' horizontally aligns type declarations:
  ┌────
  │ type t =
  │   | ( :: ) of a * b
  │   | []     of looooooooooooooooooooooooooooooooooooooong_break
  └────

  `align-variants-decl' horizontally aligns variants type 
  declarations:
  ┌────
  │ type x =
  │   [ ~Foooooooo      of int
  │   | ~Fooooooooooooo of int ]
  └────


◊ Preserve blank lines in sequences

  The new option `sequence-blank-line' decides whether a blank 
  line is
  preserved between expressions of a
  sequence. `sequence-blank-line=compact' will not keep any blank 
  line
  between expressions of a sequence, this is still the default
  behavior. `sequence-blank-line=preserve' will keep a blank line
  between two expressions of a sequence if the input contains at 
  least
  one.

  This option can help preserving the readability of the code in 
  this
  situation:
  ┌────
  │ let foo x y =
  │   do_some_setup y ;
  │
  │   important_function x
  └────


Supporting more `ocp-indent' options
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  The long term goal of `ocamlformat' is to handle every 
  `ocp-indent'
  option, this release got closer to this goal as the following
  `ocp-indent' options are now supported by `ocamlformat':
  • max_indent
  • with
  • strict_with
  • ppx_stritem_ext
  • base
  • in
  • type


◊ Offset added to a new line

  The new option `max-indent' sets the maximum offset (number of
  columns) added to a new line in addition to the offset of the 
  previous
  line. If this offset is set to 2 columns, then each new line can 
  only
  be indented by 2 columns more in addition to the previous line, 
  for
  example:
  ┌────
  │ let () =
  │   fooooo
  │   |> List.iter (fun x ->
  │     let x = x $ y in
  │     fooooooooooo x)
  └────

  This option is equivalent to the `max_indent' option of 
  `ocp-indent',
  and it will be set if `max_indent' is set in an `.ocp-indent'
  configuration file.


◊ Indentation of pattern matching cases

  The new options `funtion-indent' and `match-indent' respectively
  decide the indentation of function cases and the indentation of
  match/try cases.  These options are equivalent to the `with' 
  option of
  `ocp-indent', and they will be set if `with' is set in an 
  `ocp-indent'
  configuration file.  If the indentation is set to 4 columns, 
  cases are
  formatted like this:

  ┌────
  │ let foooooooo = function
  │     | fooooooooooooooooooooooo -> foooooooooooooooooooooooooo
  │
  │ let foooooooo =
  │   match fooooooooooooooooooooooo with
  │       | fooooooooooooooooooooooo -> 
  foooooooooooooooooooooooooo
  └────

  The new options `function-indent-nested' and 
  `match-indent-nested'
  respectively decide whether the `function-indent' and the
  `match-indent' parameters should be applied even when in a
  sub-block. If these options are set to `never', it only applies
  `function-indent' or `match-indent' if the function or match 
  block
  starts a line. If these options are set to `always', then the 
  indent
  parameters are always applied. The `auto' value applies the
  indentation parameter when seen fit.

  These options are equivalent to the `strict_with' option of
  `ocp-indent', and they will be set if `strict_with' is set in an
  `ocp-indent' configuration file.


◊ Indentation inside extension nodes

  The new option `extension-indent' sets the indentation of items 
  (that
  are not at structure level) inside extension nodes.  The new 
  option
  `stritem-extension-indent' sets the indentation of structure 
  items
  inside extension nodes. This option is equivalent to the
  `ppx_stritem_ext' option of `ocp-indent', and it will be set if
  `ppx_stritem_ext' is set in an `.ocp-indent' configuration file.

  For example if `extension-indent' is set to 5 and
  `stritem-extension-indent' is set to 3:
  ┌────
  │ let foo =
  │   [%foooooooooo
  │        fooooooooooooooooooooooooooo 
  foooooooooooooooooooooooooooooooooo
  │ 	 foooooooooooooooooooooooooooo]
  │   [@@foooooooooo
  │        fooooooooooooooooooooooooooo 
  foooooooooooooooooooooooooooooooooo
  │ 	 foooooooooooooooooooooooooooo]
  │
  │ [@@@foooooooooo
  │    fooooooooooooooooooooooooooo 
  foooooooooooooooooooooooooooooooooo
  │      foooooooooooooooooooooooooooo]
  └────


◊ Let-binding indentation

  The new option `let-binding-indent' sets the indentation of let
  binding expressions if they do not fit on a single line. This 
  option
  is equivalent to the `base' option of `ocp-indent'.  The new 
  option
  `indent-after-in' sets the indentation after `let ... in', 
  unless
  followed by another `let'. This option is equivalent to the `in'
  option of `ocp-indent'.  The new option `type-decl-indent' sets 
  the
  indentation of type declarations if they do not fit on a single
  line. This option is equivalent to the `type' option of 
  `ocp-indent'.

  These options will be set if their `ocp-indent' counterparts are 
  set
  in an `.ocp-indent' configuration file.


Miscellaneous features
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  This release also brings some new options, new values for 
  existing
  features, or corrects erroneous behaviours.


◊ Indicate multiline delimiters

  The former `indicate-multiline-delimiters' boolean option is now 
  a
  3-valued option:
  • `indicate-multiline-delimiters=space' (was equivalent to 
  `true')
    prints a space inside the delimiter to indicate the matching 
    one is
    on a different line.
  • `indicate-multiline-delimiters=no' (was equivalent to `false')
    doesn't do anything special to indicate the closing delimiter.
  • `indicate-multiline-delimiters=closing-on-separate-line' is 
  the new
    feature of this option, it makes sure that the closing 
    delimiter is
    on its own line.

  On this example we can see the closing parenthesis delimiting 
  the
  nested pattern-matchings are on their own line and are aligned 
  with
  the matching opening parenthesis:
  ┌────
  │ let () =
  │    match v with
  │    | None -> None
  │    | Some x ->
  │        ( match x with
  │        | None -> None
  │        | Some x ->
  │ 	   ( match x with
  │ 	   | None -> None
  │ 	   | Some x -> x
  │ 	   )
  │        )
  └────


◊ Formatting of literal strings

  `break-string-literals=newlines' now takes into account
  pretty-printing commands like `@,', `@;' and `@\n' to produce 
  more
  readable strings. A new value for this option has been added,
  `break-string-literals=newlines-and-wrap', to break lines at 
  newlines
  delimiters (including pretty-printing commands) and also wrap 
  the
  string literals at the margin.

  Here is how `break-string-literals=newlines-and-wrap' formats a
  string:
  ┌────
  │ let fooooooooooo =
  │   "Lorem ipsum dolor sit amet, consectetur adipiscing elit, 
  sed do eiusmod \
  │    tempor incididunt ut labore et dolore magna aliqua.@;\
  │    Ut enim ad minim veniam, quis nostrud exercitation ullamco 
  laboris nisi \
  │    ut aliquip ex ea commodo consequat.@;\
  │    Duis aute irure dolor in reprehenderit in voluptate velit 
  esse cillum \
  │    dolore eu fugiat nulla pariatur.@;\
  │    Excepteur sint occaecat cupidatat non proident, sunt in 
  culpa qui \
  │    officia deserunt mollit anim id est laborum."
  └────

  *Warning:* the `break-string-literals' will likely be removed in 
  the
   next release and the default behavior would be 
   `newlines-and-wrap'.


◊ Break before the `in' keyword

  The new option `break-before-in' has been added to decide 
  whether the
  line should break before the `in' keyword of a `let'
  binding. `break-before-in=fit-or-vertical' will always break the 
  line
  before the `in' keyword if the whole `let' binding does not fit 
  on a
  single line, it is still the default behavior. 
  `break-before-in=auto'
  will only break the line if the `in' keyword does not fit on the
  previous line.

  For example:
  ┌────
  │ let _ =
  │   let short = this is short in
  │   let fooo =
  │     (this is very long) but (the in keyword can fit) on the 
  same line in
  │   foooooo
  └────


◊ Indentation of nested pattern-matching

  The new option `nested-match' defines the style of 
  pattern-matchings
  nested in the last case of another
  pattern-matching. `nested-match=wrap' wraps the nested
  pattern-matching with parentheses and adds indentation, this is 
  still
  the default behavior. `nested-match=align' vertically aligns the
  nested pattern-matching under the encompassing pattern-matching, 
  for
  example:

  ┌────
  │ let () =
  │   match v with
  │   | None -> None
  │   | Some x ->
  │   match x with
  │   | None -> None
  │   | Some x -> x
  └────

  The new option `cases-matching-exp-indent' decides the 
  indentation of
  cases right-hand sides which are `match' or `try'
  expressions. `cases-matching-exp-indent=compact' forces an 
  indentation
  of 2, unless `nested-match' is set to `align' and this is the 
  last
  case of the pattern matching. `compact' is the default
  behavior. `cases-matching-exp-indent=normal' indents as it would 
  any
  other expression.


◊ Whitelist of files to format

  A new kind of configuration files is now handled by 
  `ocamlformat':
  `.ocamlformat-enable' files.  If the `disable' option is set, an
  `.ocamlformat-enable' file can list the files that `ocamlformat'
  should format even when the `disable' option is set. Each line 
  in an
  `.ocamlformat-enable' file specifies a filename relative to the
  directory containing the `.ocamlformat-enable' file.

  The `.ocamlformat-enable' files are using the same syntax as the
  `.ocamlformat-ignore' files: lines starting with `#' are ignored 
  and
  can be used as comments.

  These new configuration files do not contradict the existing
  `.ocamlformat-ignore' files, as `.ocamlformat-enable' are only
  considered when `disable' is set, and `.ocamlformat-ignore' are 
  only
  considered when `disable' is not set.


◊ Disable outside detected project

  The `disable-outside-detected-project' option is now set by 
  default.

  When the option `--enable-outside-detected-project' is not set,
  `.ocamlformat' files outside of the project (including the one 
  in
  `XDG_CONFIG_HOME') are not read. The project root of an input 
  file is
  taken to be the nearest ancestor directory that contains a .git 
  or .hg
  or dune-project file. If no config file is found, formatting is
  disabled.


◊ Space around collection-expressions

  The former option `space-around-collection-expressions' that was
  deciding whether a space should be added inside the delimiters 
  of
  collection expressions (lists, arrays, records, variants) has 
  been
  replaced by 4 new options: `space-around-arrays',
  `space-around-lists', `space-around-records' and
  `space-around-variants', to allow a finer grain customization.


◊ Fit-or-vertical mode for pattern matching

  The `break-cases' option that decides the shape of pattern 
  matching
  has a new value `fit-or-vertical'. `break-cases=fit-or-vertical' 
  tries
  to fit all or-patterns on the same line, otherwise breaks each
  or-pattern (they are wrapped in other modes).  For example if 
  this set
  of or-patterns does not fit on a single line, we get the 
  following
  output:
  ┌────
  │ let ffffff =
  │   match foooooooooooo with
  │   | Aaaaaaaaaaaaaaaaa
  │   | Bbbbbbbbbbbbbbbbb
  │   | Ccccccccccccccccc
  │   | Ddddddddddddddddd
  │   | Eeeeeeeeeeeeeeeee -> foooooooooooooooooooo
  │   | Fffffffffffffffff -> fooooooooooooooooo
  └────


◊ K&R style for if-then-else

  The `if-then-else' option now has a new value `k-r' that uses
  parentheses (when necessary) to reproduce a formatting close to 
  the
  K&R style. For example:
  ┌────
  │ let _ =
  │   if b then (
  │     something loooooooooooooooooooooooooooooooong enough 
  to_trigger a break ;
  │     this is more
  │   ) else if b1 then (
  │     something loooooooooooooooooooooooooooooooong enough 
  to_trigger a break ;
  │     this is more
  │   ) else
  │     e
  └────


Breaking changes
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  • the `indicate-multiline-delimiters' option is no longer a 
  boolean
    option but now has 3 values: `space', `no' and
    `closing-on-separate-line' that are detailed in this patch 
    note.
  • the `disable-outside-detected-project' option is now set by 
  default.
  • the `default' preset profile has been removed (it was 
  equivalent to
    the `ocamlformat' profile with `break-cases=fit').
  • the `space-around-collection-expressions' option has been 
  replaced
    by 4 new options: `space-around-arrays', `space-around-lists',
    `space-around-records' and `space-around-variants'.


What's next?
╌╌╌╌╌╌╌╌╌╌╌╌

  We strongly encourage our users to try out the `conventional' 
  preset
  profile, as we plan to make it the default profile in a future
  release. This profile's purpose is to reproduce the most 
  commonly
  encountered styles, and it may be more pleasing to the eye than 
  the
  current default options.

  As stated previously, the `break-string-literals' will likely be
  removed in the next release and the default behavior would be
  `newlines-and-wrap'.


Credits
╌╌╌╌╌╌╌

  This release also contains many other changes and bug fixes that 
  we
  cannot detail here.

  We would like to thank our maintainers and contributors for this
  release: Jules Aguillon, Josh Berdine, Hugo Heuzard, Guillaume 
  Petiot
  and Thomas Refis, and especially our industrial users Jane 
  Street,
  Ahrefs and Nomadic Labs that made this work possible by funding 
  this
  project and providing helpful contributions and feedback.

  We would be happy to provide support for more customers, please
  contact us at contact at tarides.com

  If you wish to get involved with OCamlFormat development or file 
  an
  issue, please read the [contributing guide], any contribution is
  welcomed.


[contributing guide]
<https://github.com/ocaml-ppx/ocamlformat/blob/master/CONTRIBUTING.md>


Ocaml 4.09.0+beta1
══════════════════

  Archive:
  <https://sympa.inria.fr/sympa/arc/caml-list/2019-06/msg00054.html>


Damien Doligez announced
────────────────────────

  The release of OCaml 4.09.0 is approaching. We have created a 
  beta
  version to help you prepare for the release.

  The source code is available at these addresses:

  <https://github.com/ocaml/ocaml/archive/4.09.0+beta1.tar.gz>
  <https://caml.inria.fr/pub/distrib/ocaml-4.09/ocaml-4.09.0+beta1.tar.gz>

  The compiler can also be installed as an OPAM switch with one of 
  the
  following commands.

  ┌────
  │ opam switch create ocaml-variants.4.09.0+beta1 
  --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git
  └────

  or

  ┌────
  │ opam switch create ocaml-variants.4.09.0+beta1+<VARIANT> 
  --repositories=default,beta=git+https://github.com/ocaml/ocaml-beta-repository.git
  └────

  where you replace <VARIANT> with one of these:
  • afl
  • default_unsafe_string
  • flambda
  • fp
  • fp+flambda

  We want to know about all bugs. Please report them here:
   <https://github.com/ocaml/ocaml/issues>


Parallel and distributed execution of command lines, pardi!
═══════════════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-parallel-and-distributed-execution-of-command-lines-pardi/4015/1>


UnixJunkie announced
────────────────────

  I am pleased to announce the first release of pardi (which the
  community recently helped to debug):

  <https://github.com/UnixJunkie/pardi>

  Pardi is a command line tool to parallelize programs which are 
  not
  parallel; provided that you can cut an input file into 
  independent
  chunks.

  For example, to compress a file in parallel using 1MB chunks:

  ┌────
  │ pardi -d b:1048576 -m s -i <YOUR_BIG_FILE> -o 
  <YOUR_BIG_FILE>.gz \
  │         -w 'xz -c -9 %IN > %OUT'
  └────

  Using the right option, you can cut an input file by lines (e.g. 
  SMI
  files), by number of bytes (for binary files), by separating 
  lines
  verifying a regexp (quite generic) or by a block separating line
  (e.g. MOL2/SDF/PDB file formats).

  If processing a single record of your input file is too fine 
  grained,
  you can play with the -c option to reach better parallelization 
  (try
  10,20,50,100,200,500,etc).

  ┌────
  │ usage:
  │ pardi ...
  │   {-i|--input} <file>: where to read from (default=stdin)
  │   {-o|--output} <file>: where to write to (default=stdout)
  │   {-n|--nprocs} <int>: max jobs in parallel (default=all 
  cores)
  │   {-c|--chunks} <int>: how many chunks per job (default=1)
  │   {-d|--demux} {l|b:<int>|r:<regexp>|s:<string>}: how to cut 
  input
  │   file into chunks (line/bytes/regexp/sep_line; default=line)
  │   {-w|--work} <string>: command to execute on each chunk
  │   {-m|--mux} {c|s|n}: how to mux job results in output file
  │ (cat/sorted_cat/null; default=cat)
  └────


Other OCaml News
════════════════

From the ocamlcore planet blog
──────────────────────────────

  Here are links from many OCaml blogs aggregated at [OCaml 
  Planet].

  • [Compiler Engineer at Axoni (Full-time)]
  • [Learn Eliom - Graffiti tutorial updated]


[OCaml Planet] <http://ocaml.org/community/planet/>

[Compiler Engineer at Axoni (Full-time)]
<https://functionaljobs.com/jobs/9171-compiler-engineer-at-axoni>

[Learn Eliom - Graffiti tutorial updated]
<https://ocsigen.github.io/blog/2019/06/25/graffiti/>


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/20190702/096e3c3b/attachment-0001.html>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 487 bytes
Desc: not available
URL: <http://lists.idyll.org/pipermail/caml-news-weekly/attachments/20190702/096e3c3b/attachment-0001.pgp>


More information about the caml-news-weekly mailing list