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 cont...@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.schm...@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/>

Attachment: signature.asc
Description: PGP signature

_______________________________________________
caml-news-weekly mailing list
caml-news-weekly@lists.idyll.org
http://lists.idyll.org/listinfo/caml-news-weekly

Reply via email to