Attn: Development Editor, Latest OCaml Weekly News

Alan Schmitt <[email protected]>
Newsgroups gmane.comp.lang.caml.inria
Message-ID <[email protected]>
Hello

Here is the latest OCaml Weekly News, for the week of January 02 to 09,
2024.

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

Odoc module index bookmarklet
create-melange-app 1.0.0 - A CLI for quickly becoming productive with Melange
What’s possible with Melange
Ocaml-ts-mode - Emacs ocaml major mode using tree sitter
Using Menhir to parse into idiomatic JS (TypeScript) structures
Play with project-wide occurrences for OCaml!
New release of Menhir (20231231)
Ocsigen: summary of recent releases
sarif 0.1.0 - Static Analysis Results Interchange Format (SARIF) For OCaml
Other OCaml News
Old CWN


Odoc module index bookmarklet
═════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/odoc-module-index-bookmarklet/13780/1>


Yawar Amin announced
────────────────────

  Hello, I made a [bookmarklet] that injects an index of a module’s
  contents into the sidebar of an _odoc-generated module documentation_
  page. For example, if you go to <https://aantron.github.io/dream/> ,
  and run the bookmarklet, you will see:

  <https://global.discourse-cdn.com/business7/uploads/ocaml/optimized/2X/b/b8ff2875a69e16df70772fe76e04f8bad334bc5d_2_1380x624.png>


[bookmarklet] <https://yawaramin.github.io/bookmarklets/#h2-odoc-idx>


create-melange-app 1.0.0 - A CLI for quickly becoming productive with Melange
═════════════════════════════════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-create-melange-app-1-0-0-a-cli-for-quickly-becoming-productive-with-melange/13794/1>


Dillon Mulroy announced
───────────────────────

  Hello y’all 👋

  I have been working on creating a scaffolding tool aimed at enabling
  JavaScript and TypeScript developers to quickly become familiar and
  productive with OCaml, ReasonML, and Melange. The developer
  experience, tooling, and project setup is opinionated and meant to be
  familiar and friendly for folks coming from that ecosystem.

  So, without further ado, I’m excited to announce create-melange-app,
  1.0.0!

  Get started by simply running `npm create melange-app@latest' and
  completing the questions that the CLI will guide you through.

  Project setup:

  <https://global.discourse-cdn.com/business7/uploads/ocaml/optimized/2X/f/f933ddbdd7f1a8471f82d58ded774eeeffc98800_2_900x932.jpeg>

  Scaffolding:

  <https://global.discourse-cdn.com/business7/uploads/ocaml/optimized/2X/c/c82f71d8455efb6d4e2de8275f7aecba72780294_2_900x564.jpeg>

  <https://global.discourse-cdn.com/business7/uploads/ocaml/optimized/2X/9/929f373bee8384d50d017200f73c354e61ef916c_2_900x534.jpeg>

  ✨Your new Melange app ✨

  <https://global.discourse-cdn.com/business7/uploads/ocaml/optimized/2X/e/eb0987302d99dfdb0ae87bf1bf371856fe27624d_2_900x576.jpeg>

  <https://global.discourse-cdn.com/business7/uploads/ocaml/optimized/2X/6/6b3a945d63c3664a792894366e8ead786ef6b723_2_900x792.jpeg>

  You can find the code/projected generated in this example here:
  <https://github.com/dmmulroy/create-melange-app-example>

  I’ve tried to take great care to provide as much helpful information
  for developers unfamiliar with our ecosystem as possible. You’ll find
  many of the scaffolded files commented with explanations, examples,
  and additional resources aimed at quickly becoming productive with
  OCaml, ReasonML, and Melange.

  *Looking forward 👀*

  I have a lot of ideas around making bindings easier and more pleasant
  to write for manage, along with some delightful ways to integrate them
  into CMA.

  But first…

  We’re rewriting to native OCaml using [MintTea]! Currently
  `create-melange-app' is written using Melange and [Ink], a library for
  rendering React components too the terminal.

  When I started CMA, OCaml didn’t have a great TUI story for easily
  making delightful experiences (plus I wanted an excuse to go deeper
  with Melange, and doesn’t a CLI written with OCaml and React sound
  ridiculous? 😂)

  I would love for CMA itself to be a great OSS project for beginners
  with OCaml to get involved with and learn with and I’m aiming to bring
  as many people along for that ride as I can :)

  You can follow my development of CMA on [my twitch channel] where I
  live stream OCaml content every M-F 7am - 10am ET

  Thanks y’all! 🐫


[MintTea] <https://github.com/leostera/minttea>

[Ink] <https://github.com/vadimdemedes/ink>

[my twitch channel] <https://twitch.tv/dmmulroy>


What’s possible with Melange
════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/whats-possible-with-melange/13806/1>


David Sancho announced
──────────────────────

  Hi

  Since dune got the integration with Melange (and Ahrefs migrated to
  Melange
  <https://discuss.ocaml.org/t/ahrefs-is-now-built-with-melange/12107>)
  I wanted to write about the benefits of using it.

  I wrote a blog post comparing Melange with the previous compiler
  (BuckleScript/ReScript) and what’s possible. I tried to be objetive
  and focus only on the technical parts of it.

  The link to the post is:
  <https://sancho.dev/blog/whats-possible-with-melange>

  Hope you like it, and feel free to ask anything!


Ocaml-ts-mode - Emacs ocaml major mode using tree sitter
════════════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ocaml-ts-mode-emacs-ocaml-major-mode-using-tree-sitter/13807/1>


Malcolm announced
─────────────────

  This weekend I got interested in emacs major modes based on
  treesitter, so I decided to implement `ocaml-ts-mode'. The code can be
  found here:

  <https://github.com/terrateamio/ocaml-ts-mode>

  It was actually very easy thanks to the hard work others have done in
  creating the treesitter grammar.

  It supports:

  • Syntax highlighting of `.ml' and `.mli' files.
  • Initial indentation support (this is probably currently broken in
    multiple places)
  • `C-c C-a' - Switch between `.ml' and `.mli' files for a module.

  This is less feature rich than Tuareg mode, so I don’t know if it
  replaces it. If anything, maybe it could be integrated into tuareg
  mode.

  I have no experience writing elisp so this probably has obvious
  mistakes. Contributions welcome!

  Enjoy!


Malcolm then added
──────────────────

  Whoops, in my excitement learning about treesitter I didn’t notice
  that there already is an ocaml-ts-mode. That one is probably the
  preferred one to use. I’ll probably direct any of my development
  towards it. But learning how to make a major mode was a fun
  experience.


Using Menhir to parse into idiomatic JS (TypeScript) structures
═══════════════════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/using-menhir-to-parse-into-idiomatic-js-typescript-structures/13809/1>


Shon announced
──────────────

  Hello and Happy New Year!

  As we all know, despite being named an [Objective Categorical Abstract
  Machine Language], OCaml is Obviously a Completely Awesome [Meta
  Language](<https://en.wikipedia.org/wiki/ML_(programming_language)>).
  The awesomeness is founded on the wonderful language, but obviously
  completed by the extraordinary ecosystem of tools and techniques that
  take life in that language. :stuck_out_tongue_winking_eye:

  This is a note to share a solution I hacked together using a handful
  of these awesome tools in our lovely language, but also a request for
  any suggestions on a more elegant solution to the problem posed.


[Objective Categorical Abstract Machine Language]
<https://en.wikipedia.org/wiki/Caml>

The Problem
╌╌╌╌╌╌╌╌╌╌╌

  I wanted to use Menhir and Sedlex to write a fault-tolerant,
  incremental parser for a preexisting project that has an intermediate
  representation (IR), and a bunch of other tools, written in
  TypeScript.


Non-solutions
╌╌╌╌╌╌╌╌╌╌╌╌╌

  Unfortunately, achieving this outcome was not quite as simple as
  adding a `(mode js)' to dune to have the generated parser compiled by
  [Js_os_ocaml (Jsoo) ]. Of course, that *does* work like a charm, and
  if we could justify rewriting everything in OCaml, we’d be able to
  produce JS easy as pie. But for interop with the existing TypeScript
  code this won’t fly. We need to parse into JS objects that represent
  the IR in a human-readable way, ideally matching our existing
  TypeScript types, but Jsoo gives something like this.

  ┌────
  │ > parser.parse('def foo(a,b) = 123')
  │ [ 0, [ 0, [ 0, [Array], [Array] ], 0 ] ]
  └────

  My next thought was to use Melange: it seems to be a great project
  with a lot of excellent work going in to it, and, iiuc, its purpose is
  precisely to compile OCaml into idiomatic(ish) JS. But I hit a road
  block right away, which led me to ask
  <https://discuss.ocaml.org/t/what-are-the-limits-and-prerequisites-of-using-dependencies-with-melange/13688>
  and to try something else.


[Js_os_ocaml (Jsoo) ]
<https://ocsigen.org/js_of_ocaml/latest/manual/overview>


A Solution
╌╌╌╌╌╌╌╌╌╌

  Fortunately, the wealth of shining jewels-of-tools in the OCaml
  ecosystem made this short work. The solution I ended up with is hacky
  as heck, but its doing what I needed:

  • I define our types using the excellent [atd].
  • I generate OCaml and TypeScript representations of the types, along
    with JSON serializers, via a dune config like
    ┌────
    │ (library
    │  (public_name lang_ir)
    │  (libraries atdgen))
    │ 
    │ ;; The OCaml ser/de-serializers
    │ (rule
    │  (targets lang_ir_j.ml
    │           lang_ir_j.mli)
    │  (deps    lang_ir.atd)
    │  (action  (run atdgen -j -j-std %{deps})))
    │ 
    │ ;; The OCaml types
    │ (rule
    │  (targets lang_ir_t.ml
    │           lang_ir_t.mli)
    │  (deps    lang_ir.atd)
    │  (action  (run atdgen -t %{deps})))
    │ 
    │ ;; The TypeScript types and ser/de
    │ (rule
    │  (targets lang_ir.ts)
    │  (deps    lang_ir.atd)
    │  (action  (run atdts %{deps})))
    │ 
    │ ;; Conversion of the TypeScript into vanilla JS so I can test it with node
    │ (rule
    │  (targets lang_ir.js)
    │  (deps    lang_ir.ts)
    │  (action  (run npx tsc %{deps})))
    └────
  • I use menhir and sedlex to define a parser that produces inhabitants
    of the OCaml types generated in `lang_ir_t.ml'. (Working out the
    incremental, fault-tolerant parsing was its own exhilarating side
    quest, but I’ll save a report on that for it’s own post.)
  • Then I use Jsoo to run the parser in JS and then serialize its
    optimized but inscritable representation into the JSON dictated by
    atd:
    ┌────
    │     open Lang_parser_lib
    │ 
    │     open Js_of_ocaml
    │ 
    │     (* Export functions *)
    │     (* See  https://ocsigen.org/js_of_ocaml/latest/manual/rev-bindings *)
    │     let _ =
    │     Js.export_all
    │         (object%js
    │         method parse s =
    │             let lexbuf = Sedlexing.Utf8.from_string s in
    │             match parse lexbuf with (* run the parser *)
    │             | Some t -> Lang_ir.Quint_ir_j.string_of_t t (* produce a JSON string
    │ from the result*)
    │             | None -> ""
    │         end)
    └────
  • And, finally, I make a little `wrapper.js' that invokes the
    atd-generated deserializer to parse into the TypeScript
    representation:
    ┌────
    │ var ir = require('./_build/default/ir/lang_ir.js')
    │ var parser = require('./_build/default/js/lang_parser.bc.js')
    │ 
    │ exports.parse = function (s) {
    │   return ir.readT(JSON.parse(parser.parse(s)))
    │ }
    └────


[atd] <https://github.com/ahrefs/atd>


The result
╌╌╌╌╌╌╌╌╌╌

  I now can use the wrapper script to parse into the nice TypeScript
  (compatible) structures I need:

  ┌────
  │ [me@comp mparsing]$ node
  │ > var p = require('./wrapper.js')
  │ undefined
  │ > p.parse("def foo(a,b) = 123")
  │ [
  │ {
  │     loc: { start_: [Object], end_: [Object] },
  │     v: { name: 'foo', params: [Array], body: [Object] }
  │ }
  │ ]
  └────

  I have three hopes for this post:

  1. I hope to contribute yet another note celebrating the virtues of
     our extraordinary programming language ecosystem.
  2. I hope it might be useful for others who need to solve similar
     problems.
  3. I hope there is a more elegant way to achieve this result (namely,
     without having to go through serialization) and that one of y’all
     can point the way.

  :heart: :camel:


Play with project-wide occurrences for OCaml!
═════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-preview-play-with-project-wide-occurrences-for-ocaml/13814/1>


vds announced
─────────────

  Hi fellow camelers 👋, I am very pleased to announce that every one
  can now try the upcoming project-wide occurrences feature for Merlin
  and OCaml-LSP.

  This feature involves changes to multiple packages such as `ocaml',
  `merlin', `ocaml-lsp' and `dune' so we decided to prepare a custom
  opam repository to make it easy for adventurous people to install the
  feature, play with it, and most-importantly… break it ! We hope you
  will have as much fun querying around your codebases as we do :-)


Requirements for this preview:
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  • Have projects compatible with /OCaml 4.14.2/.
  • These projects build with /Dune/. (The tools themselves are
    build-system agnostic, but this preview only include rules for
    Dune.)
  • You use an /LSP-based editor plugin/. (We do plan to bring basic
    support to the vanilla `emacs' and `vim' modes for Merlin.)


What the feature does…
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  • ✅ Returns every *usages* of types, values, constructors and labels
    in `ml' and `mli' files in the workspace
  • ✅ Returns direct usages of modules (like `M' in `include M')
  • ✅ Can be called on any such usage of a value or on its *definition*
    itself


…what is does not do yet:
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  • ❌ Return *declarations* related to searched values in both *ml* and
    *mli* files. This will come in a second iteration.
  • ❌ Occurrences of modules appearing in paths: like `M' and `N' in
    `M.N.P'. This will also arrive later.
  • ⚠️ Renaming is experimental and not as smart as one would expect
    (with regard to punning and other syntactic tricks).


…and known caveats:
╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌╌

  • ⚠️ Interaction with PPX might give unexpected results depending on
    the specifics of the PPX.
  • ⚠️ Values whose definition cannot be determined statically (like
    items of a first-class module) won’t be searched project-wide. For
    the same reason, walues coming from libraries that do not install
    their `cmt' files won’t be searched project-wide.


Demo
╌╌╌╌

  In the following demo, the feature is used to rename a symbol in
  Merlin. Since the name appears in one *declaration*, this last
  occurrence still needs to be replaced by hand for the build to
  succeed:

  <https://global.discourse-cdn.com/business7/uploads/ocaml/original/2X/5/5f9380fcc7e841c54e018a390946eaa801ff4241.gif>


Setup
╌╌╌╌╌

  You can find detailed setup instruction in the [custom opam
  repository]. In short:

  1. Add the repository to your opam installation: `opam repo add index
     https://github.com/voodoos/opam-repository-index.git'
  2. Create a switch (global or local) with the `+index' ocaml variant:
     `opam switch create --repositories=default,index 4.14.2+index'
  3. Install `merlin', `ocaml-lsp' and the indexer: `opam install
     indexing-tools'
  4. Build the index with your project: `dune build @ocaml-index
     @your-usual-target-maybe-install-or-all --watch'

  References and renaming queries should return result on the entire
  workspace.


[custom opam repository]
<https://github.com/voodoos/opam-repository-index>


Feedback
╌╌╌╌╌╌╌╌

  Please do not hesitate to share any feedback on the feature here or by
  [opening an issue on the repository] :slightly_smiling_face:


[opening an issue on the repository]
<https://github.com/voodoos/opam-repository-index/issues>


New release of Menhir (20231231)
════════════════════════════════

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


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

  It is my pleasure to announce a new version of Menhir, 20231231. It
  should be available now:

  ┌────
  │ opam update
  │ opam install menhir.20231231
  └────

  The main new features are as follows:

  • The new command line switch `--unparsing' (which must be used in
    conjunction with `--table') causes Menhir to generate an unparsing
    API. In short, unparsing is the process of transforming abstract
    syntax trees back into text. The unparsing API is intended to help
    users write correct unparsers, but does not automate the whole
    process.

    For more details, please see the paper [Correct, Fast LR(1)
    Unparsing].

    The unparsing API requires linking with the library `MenhirCST', and
    requires OCaml 4.08.

  • Attributes can now be attached with a production. (In previous
    versions of Menhir, attributes could be attached only with a symbol,
    with a specific occurrence of a symbol in the right-hand side of a
    production, or with the whole grammar.) This is achieved by letting
    one or more attributes appear immediately after the semantic action.

    During the two grammar transformation phases (expansion of
    parameterized nonterminal symbols and elimination of `%inline'
    nonterminal symbols), the `[@name]' attributes attached with
    productions receive special treatment, so as to allow each
    production to receive a unique name.


[Correct, Fast LR(1) Unparsing]
<http://cambium.inria.fr/~fpottier/publis/pottier-unparsing-2024.pdf>


Ocsigen: summary of recent releases
═══════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ocsigen-summary-of-recent-releases/13817/1>


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

  We do not announce very often our releases on this forum. Here is a
  roundup of recent releases to make amends.

  Many releases of [Js_of_ocaml] last year, with important features like
  the support of OCaml 5 effects, global dead-code elimination, support
  for modern JavaScript and [a huge list of improvements and fixes].
  There is now also a new backend for js_of_ocaml, [Wasm_of_ocaml]
  written by @vouillon, to compile to WebAssembly. It can be used as a
  replacement for js_of_ocaml with very few changes.

  [Eliom], the OCaml Web framework, has now reached version 10.2.
  Amongst the most recent changes:
  • The Dune-based build system is now the default one for client-server
    apps
  • compatibility with OCaml 5
  • Reactive programming: Update to recent versions of js_of_ocaml,
    which support weak pointers
  • Documentation improvements

  An [experimental version] is also available to build WASM applications
  with wasm_of_ocaml

  [Ocsigen-Start] version 6.1
  • removes a dependency on Ocamlnet to make it compatible with OCaml 5.
    No default email function is now provided. Warning: this might be a
    regression if you use the default email-sending function.
  • updates the dune-based build system

  [Tyxml] 4.6 was released with [fixes] on some tags and options.

  [Lwt] reach version [5.7]

  Several maintenance releases of [Ocsigen-Toolkit]

  The Ocsigen team wishes you a happy new year!


[Js_of_ocaml] <http://ocsigen.org/js_of_ocaml>

[a huge list of improvements and fixes]
<https://github.com/ocsigen/js_of_ocaml/blob/master/CHANGES.md>

[Wasm_of_ocaml] <https://github.com/ocaml-wasm/wasm_of_ocaml>

[Eliom] <http://ocsigen.org/eliom>

[experimental version] <https://github.com/ocsigen/eliom/pull/767>

[Ocsigen-Start] <http://ocsigen.org/ocsigen-start>

[Tyxml] <http://ocsigen.org/tyxml>

[fixes] <https://github.com/ocsigen/tyxml/releases>

[Lwt] <http://ocsigen.org/lwt>

[5.7] <https://github.com/ocsigen/lwt/releases/tag/5.7.0>

[Ocsigen-Toolkit] <http://ocsigen.org/ocsigen-toolkit>


sarif 0.1.0 - Static Analysis Results Interchange Format (SARIF) For OCaml
══════════════════════════════════════════════════════════════════════════

  Archive:
  <https://discuss.ocaml.org/t/ann-sarif-0-1-0-static-analysis-results-interchange-format-sarif-for-ocaml/13821/1>


Geoffrey Borough announced
──────────────────────────

  Hi folks, I announce the initial release of sarif version 0.1.0, a
  library for processing and validating the SARIF format. If you are
  familiar with static analysis and/or code scanner like Semgrep or Snyk
  etc, SARIF is one of the output format that people generate and share
  after scanning, the specification itself is quite big and convoluted.

  My motivation for making this library is that there seems to be no
  definitive library for SARIF in the OCaml ecosystem, and even
  companies like Semgrep relies on some python glue code to generate the
  format. Given OCaml’s importance in the static analysis scene I
  thought it would be nice if this gets over the line :slight_smile:

  Code: <https://github.com/gborough/sarif>

  Documentation:
  <https://gborough.github.io/sarif/sarif/sarif/index.html> (Package
  available very soon in opam-repository pending PR approval)

  Have a nice day!


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

From the ocaml.org blog
───────────────────────

  Here are links from many OCaml blogs aggregated at [the ocaml.org
  blog].

  • [Parsing with Binary String Pattern Matching]


[the ocaml.org blog] <https://ocaml.org/blog/>

[Parsing with Binary String Pattern Matching]
<https://practicalocaml.com/parsing-with-binary-string-pattern-matching/>


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
  to the [caml-list].

  [Alan Schmitt]


[send me a message] <mailto:[email protected]>

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

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

[caml-list] <https://sympa.inria.fr/sympa/info/caml-list>

[Alan Schmitt] <https://alan.petitepomme.net/>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.