OCaml Weekly News

Previous Week Up Next Week

Hello

Here is the latest OCaml Weekly News, for the week of January 11 to 18, 2022.

Table of Contents

Blog post: Writing a Game Boy emulator in OCaml

Lin Oshitani announced

I have written a blog post to share my experience of writing a Game Boy emulator in OCaml.

I will cover things like:

  • Overview of the Game Boy architecture.
  • Using functors to implement testable modules.
  • Using GADTs to encode the Game Boy instruction set.
  • Using test ROMs and ppx_expect to implement the emulator in exploratory programming style.
  • Finding bottlenecks and improving performance.
  • General thoughts on OCaml.

Please take a look if you are interested and/or share with anyone who might be interested.

Also, let me know if you have any questions or comments.

Thanks!

https://linoscope.github.io/writing-a-game-boy-emulator-in-ocaml/

Bogue, the OCaml GUI

Deep in this thread, octachron asked

Looking at the dependencies, I noticed that you also wrote a binding to SDL_ttf. I am wondering if it would be enough to provide a SDL-based reimplementation of the Graphics library (with exactly the same interface)? It could be a nice way to have a pedagogical graphical API which is just a front-end for a full graphical library.

sanette replied

Yes, I think it would be fairly easy. Looking at the Graphics API, the only things that are not included in SDL~+~SDL_ttf~+~SDL_image are graphics primitives like (filled) ellipses and (filled) polygons. One could write bindings to SDL_gfx (*) for these, but it's more fun to program them directly in ocaml ;)

(*) in fact they already exist, https://github.com/fccm/tsdl-gfx

V3.ocaml.org: getting ready to launch

Anil Madhavapeddy announced

In my previous post this summer about the upcoming revision of the website, I gave an overview of where we were headed and presented a roadmap for OCaml's online presence.

Since August 2021, we've made considerable progress. We're on track to launch the website in February 2022 (only a couple of months beyond my summer prediction!), and the roadmap after that is becoming clearer thanks to all your feedback.

You can see it live at https://v3.ocaml.org/, with the package search available at v3.ocaml.org/packages

Let's dive into it!

Update

Until August 2021, we had been working on the foundations for v3: the user flows, sitemap, and the reusable infrastructure for the data used in ocaml.org. With all the infrastructure and data ready, our efforts since have been focused on completing the frontend.

One of the clearest priorities we had from community feedback was to ensure that the unified package documentation gets to the live site as soon as possible. The build process for this is not trivial, as it involves combining the outputs of 20,000+ opam packages with the rest of the website, while maintaining a reasonable developer experience for the main site. We have therefore merged the various frontend and backend codebases into a single OCaml-based one. We've merged the NextJS / ReScript / Tailwind codebase to the backend server that serves the package documentation. This has allowed us to consolidate our technology stack and simplify our continuous deployment story, but also to directly serve the website from a pure OCaml stack (using packages from our own community such as Dream and ocaml-tls). We're deeply grateful to the ReScript team for the technology that let us prototype the new revision of the website so quickly, and to implement the templates we're now using.

Here's an overview of the sitemap and all the pages we've implemented.

In addition to the frontend work, here are some backend highlights:

  • A global navigation bar on the package documentaion. You can now navigate through all package libraries from the navbar (by @TheLortex in #86)
  • A toplevel on the homepage (by @tmattio, @patricoferris and @jonludlam in #106, #135 and #159)
  • Added redirections from current ocaml.org URLs
  • An internationalisation framework that serves pages in different languages. The framework exists, but the page translations will come later (by @tmattio in #84)
  • A code-highlighting library that adds code highlighting in the tutorials (by @patricofferis in #108)
  • Handled Let's Encrypt certificate renewals and HTTPS redirects (by @tmattio and @patricofferis in #182)

See the full changelog here: https://github.com/ocaml/v3.ocaml.org-server/blob/main/CHANGES.md.

As mentioned above, we are feature complete, so we will be reviewing the site to get final approval from @xavierleroy and the core development team to launch the new site in a few weeks. We still have some work to do until then, but we'll dedicate these next few weeks to receive community feedback and make any appropriate changes.

So now is the time to give us the feedback you have! You can do this by replying to this post or opening GitHub issues on the repository ocaml/v3.ocaml.org-server. Mostly, we're hoping to receive actionable feedback such as:

  • Are you able to find all the information you're expecting to find on the website?
  • Do you find the documentation (both the learn section and package documentation) usable?
  • Do you find some design elements make the website hard to use (e.g., for color blind folks)?

Also, please don't hesitate to open a GitHub Issue if you notice any bugs.

As you know, the release of OCaml 5.00.0, including Multicore support, is coming in 2022, so the timing of the v3 website launch is not coincidental. When OCaml 5.00.0 is released, the website will serve as an entry point for people new to OCaml, so we need to be ready with a usuable website, helpful documentation, clear package sites, etc. All your feedback and insights on how we can do better is greatly appreciated.

What's Next?

Launching the website is the first step on our roadmap to improve OCaml's online presence.

As mentioned above, the immediate goal is to be ready for this OCaml 5.00.0 release. With this in mind, for the next few months, we'll focus on improving the documentation and ensuring it includes good user pathways to learn about Domains, Effects, and generally how to write concurrent programs in OCaml.

In addition to the documentation, some of the other projects on our roadmap are:

  • An online editor integrated in ocaml.org (aka a Playground)
  • Toplevels for all the packages that compile to JavaScript

This is an exciting time! Stay tuned!

How Can You help?

We need your help!

Until now, the development and design of the new site has been driven by a small team of people from Solvuu, OCaml Labs, Tarides, the University of Cambridge and individual contributors from our community. This was useful to get the momentum we needed to deliver on all the feedback from the community (package documentation, job board, new blog, etc.), but OCaml.org is a community project and needs to be driven by all of us.

In particular, we built what we hope is a good framework to represent the community with pages like:

  • A job board
  • The OCaml blog
  • The meetings and workshops
  • The industrial users and academic users
  • The success stories

Now that the framework is there, we need your help to contribute to these pages, allowing us to serve great content and make the pages useful.

Job Board

The job board is an experiment. We're hoping that we'll get enough content on it so it's useful for people looking for OCaml positions.

To do this, we need more job posts.

If you are hiring OCaml developers, you can add your job posts here: https://github.com/ocaml/v3.ocaml.org-server/blob/main/data/jobs.yml

Blog

The previous blog contained a lot of articles that had nothing to do with OCaml, as it was an unmonitored RSS/Atom aggregator.

A long term project is to build a decentralised RSS feed for the OCaml community to publish blog posts about OCaml. In the interim, we can keep using those RSS feeds but also list the article IDs we want to display.

If you have a blog about OCaml, you can add your RSS feed and list of articles here: https://github.com/ocaml/v3.ocaml.org-server/blob/main/data/news-sources.yml

We would also like to integrate the Caml Weekly News (which recently celebrated its second decade!) directly onto the main ocaml.org website.

Events

At the moment, the Events pages lists the OCaml workshops and the Meetups.

If you're organising events, don't hesitate to put them here: https://github.com/ocaml/v3.ocaml.org-server/blob/main/data/meetups.yml

Perhaps we can advertise new events from the website, if that helps organising your events.

Success Stories

In the new website, we've revamped the success stories to contain detailed company descriptions and the way they use OCaml, including which challenges their business faced and how OCaml helped overcome them.

If you're using OCaml, you can write a success story for your business here: https://github.com/ocaml/v3.ocaml.org-server/tree/main/data/success_stories/en

Tutorials and Manual

As mentioned above, we'll be revamping the documentation in the next few months. This is a large project with a lot of content to write, so we'll need the community's help. If you're interesting in contributing, don't hesitate to reach out at <thibaut.mattio@gmail.com> to @tmattio.

The OCaml manual in particular is rendered using the old style, and we are planning to port it to odoc in order to fit in with the new style and also to cross-reference into the API documentation. (this requires more discussions with the core development team, and @octachron has begun looking at it).

Package Documentation

Now that we have a great package site with documentation, it's time to write great documentation for your packages!

The odoc maintainers worked on some guidelines on how to write odoc files: https://ocaml.github.io/odoc/odoc_for_authors.html

We'll also be integrating toplevels for the packages you publish on Opam. It will use js_of_ocaml, so if you've published packages that should be compatible with js_of_ocaml, you can start making sure they are before we roll out the toplevels in the package documentation.

Acknowledgements

Thank you to everyone who contributed to the development of this new version of the website!

In particular:

  • Ashish Agarwal (Solvuu)
  • Kanishka Azimi (Solvuu)
  • Richard Davison (Solvuu)
  • Patrick Ferris (OCaml Labs)
  • Gemma Gordon (OCaml Labs)
  • Isabella Leandersson (OCaml Labs)
  • Thibaut Mattio (Tarides)
  • Anil Madhavapeddy (University of Cambridge)

For the groundwork on rethinking the sitemap, user flows, new content, design, and frontend and package docs!

  • Jon Ludlam (OCaml Labs)
  • Jules Aguillon (Tarides)
  • Lucas Pluvinage (Tarides)

For the work on the package site infrastructure and UI!

  • Paul-Elliot Anglès d'Auriac (Tarides)

For meticulously going through the website to find issues.

  • Isabella Leandersson (OCaml Labs)
  • Asaad Mahmood (Tarides)

For the work on the designs and bringing them to life on the frontend!

  • Christine Rose (OCaml Labs)
  • Isabella Leandersson (OCaml Labs)

For the work on the new content and reviewing the existing one!

We'd also like to thank the major funders who supported work on revamping the website: grants from the Tezos Foundation and Jane Street facilitated the bulk of the work. Thank you, and if anyone else wishes to help support it on an ongoing basis then donations to the OCaml Software Foundation and grants to the maintenance teams mentioned above are always welcomed.

Moving forward, updates on the v3 website will be taken over by @tmattio, who has kindly volunteered to run a community video chat "AMA" about how you can get involved and contribute, and to give your feedback directly. He will post here with more details when timezones are all worked out. We would, of course, be delighted to also use other community channels / podcasts / Twitch / Discords / etc to reach out and get feedback and ideas.

On a personal note, it's incredible to see this stream of hard work combine with the recent multicore OCaml merge to provide a modern, welcoming interface to the new users who will appear. I'm most excited about the future of OCaml we are embarking on with 5.0 – thank you to all who have been involved for being such wonderful collaborators.

New release of Windows DKML with system compiler and easy Opam switch creation

jbeckford announced

v0.3.3 has been released. There are no new features for Windows but it does restore the behavior that was present in v0.3.0 (the ANN announcement) but was broken in unannounced versions 0.3.1 and 0.3.2. It also contains a couple bug fixes which help the installation on older Windows machines.

Cross-compiling OCaml with GitHub Actions

jbeckford announced

For those that are interested in cross-compiling, there is:

  • a GitHub Actions workflow with an example workflow run that creates an OCaml cross-compiler from:
    1. macOS x86_64 host into macOS arm64 target executables (to make universal binaries, for example, on non-Apple Silicon hardware)
    2. Linux x86_64 host into Android arm64 (v8)
    3. Linux x86_64 host into Android arm32 (v7a)
    4. Linux x86_64 host into Android x86_64
  • internally there are some patches to the OCaml 4.12.1 source code to create a cross-compiling OCaml compiler
  • a document I wrote to help me understand what was happening: https://diskuv.gitlab.io/diskuv-ocaml/doc/CompilingInDepth.html

For example, the GitHub Actions workflow contains a test that illustrates how to use it. When the following is run on 64-bit AMD/Intel Ubuntu Linux:

$ dist/android_arm32v7a-on-linux_x86/opt/mlcross/android_arm32v7a/bin/ocamlopt.opt \
  hello_world.ml -o hello_world.opt.exe

the hello_world.opt.exe should run on Android arm32 (v7a):

$ file hello_world.opt.exe
hello_world.opt.exe: ELF 32-bit LSB shared object, ARM, EABI5 version 1 (SYSV), dynamically linked, interpreter
/system/bin/linker, with debug_info, not stripped

This is just a preview and I'm not generating binary packages at the moment. But if it is useful enough to you that you will test it out (ex. copy/paste the GitHub workflow, or do it manually on your mac or Ubuntu machine), please tell me if you have any problems. Be aware it will likely be months before I package it up in a simpler form because it will take time to upstream patches into the OCaml compiler trunk.

This is a continuation of the closed topic https://discuss.ocaml.org/t/cross-compiling-implementations-how-they-work/8686 . Thanks EduardoRFS, Antonio Nuno Monteiro and Romain Beauxis for showing me the technique!

First announcement of Bechamel

Calascibetta Romain announced

Bechamel, an agnostic micro-benchmarking tool

I'm glad to announce the release of Bechamel.0.2.0. Bechamel is a framework to do micro-benchmark. As a MirageOS project, the core library does not depends on Unix syscalls (hence the term "agnostic"). It provides:

  • an extensible way to record metrics
  • different views of results

Indeed, we know that it can be difficult to make a béchamel sauce. Adding the milk while adding the flour and mixing it all together requires at least three hands. The observability of the operation is difficult and can therefore, in view of our abilities, interfere with the expected result.

This is the reason why Bechamel exists. It allows to make this mixture and ensures that the results are more or less correct. It performs the desired function in a restricted and controlled context in order to remove interference. A touch of machine learning allows us to determine the true outcome of metrics such as time, words allocated in the minor heap or more exotic metrics such as those available via the Linux kernel.

Finally, the presentation of the results counts as the presentation of your lasagne. Thus, Bechamel offers several ways to present the results depending on what you want. We can offer you:

  • An interface in your terminal
  • A Web 3.0 page which is a full report of your experiment

You can see an example of this report here.

Extensibility of metrics

Depending on your runtime context, you can get few metrics from the kernel. For instance, Linux comes with the perf tools which is able to record some metrics such as:

  • the cpu-clock: this reports the CPU clock, a high-resolution per-CPU timer.
  • the page-faults: this reports the number of page faults
  • etc.

They are available via the bechamel-perf package which can be linked with your benchmark. You can see a simple example into the distribution: sqrt.ml

The HTML output

The HTML + Javascript is pretty simple to generate. Let's say that you have:

let benchmark () : (Bechamel_js.ols_result * Bechamel_js.raws) =
  let ols = Analyze.ols ~bootstrap:0 ~r_square:true ~predictors:Measure.[| run |] in
  let instances = Instance.[ minor_allocated; major_allocated; monotonic_clock ] in
  let cfg =
    Benchmark.cfg ~limit:2000 ~stabilize:true ~quota:(Time.second 0.5)
      ~kde:(Some 1000) () in
  let raw_results =
    Benchmark.all cfg instances
      (Test.make_grouped ~name:"factorial" ~fmt:"%s %s" [ test0; test1 ]) in
  let results = List.map (fun instance -> Analyze.all ols instance raw_results) instances in
  let results = Analyze.merge ols instances results in
  (results, raw_results)

You just need to "emit" results into the JSON format:

let compare k0 k1 =
  let a = ref 0 and b = ref 0 in
  Scanf.sscanf k0 "%s %s %d" (fun _ _ a' -> a := a');
  Scanf.sscanf k1 "%s %s %d" (fun _ _ b' -> b := b');
  !a - !b

let nothing _ = Ok ()

let () =
  let results = benchmark () in
  let results =
    let open Bechamel_js in
    emit ~dst:(Channel stdout) nothing ~compare ~x_label:Measure.run
      ~y_label:(Measure.label Instance.monotonic_clock)
      results in
  match results with Ok () -> () | Error (`Msg err) -> invalid_arg err

And a simple intrumentation of dune is enough to generate the HTML + Javascript page via bechamel-html:

(executable
 (name fact)
 (modules fact)
 (public_name bechamel-js.examples.fact)
 (package bechamel-js)
 (libraries bechamel bechamel-js))

(rule
 (targets fact.json)
 (action
  (with-stdout-to
   %{targets}
   (run ./fact.exe))))

(rule
 (targets fact.html)
 (mode promote)
 (action
  (system "%{bin:bechamel-html} < %{dep:fact.json} > %{targets}")))

You can see a full example here.

Kernel Density Estimation

The report can show the histogram and/or the KDE of the given distribution of times to check if it's a normal distribution - and ensure that the set given as arguments of our function considers all possibilities.

Resources

The micro-benchmark can be useful to ensure assumptions about syscalls. But they can require some resources. In that situation, Bechamel allows the user to define an allocation function which is executed before the benchmark.

This resource will be used by your test and will be released then at the end of the benchmark. For instance, Bechamel allows to record metrics for, for instance, io_uring.

Micro-benchmark, disclaimer

We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil – Donald Knuth

Micro-benchmark should not be an argument to micro-optimize some parts of your code. Indeed, Bechamel mostly wants to report some observable values and ensure to avoid the Schrödinger's cat case (where the tool affect results by the observation).

Bechamel wants to help the developper to assert some assumptions but it should not be an argument to say that your implementation is faster than an other one - at least, it helps you on this way.

An Update on the State of the PPX Ecosystem and ppxlib's Transition

Continuing this thread, Sonja Heinze announced

After some while, we now have a pretty exciting update on this: the ppx_import port to ppxlib has been merged. So no need for the "exception"-appendix anymore in the sentence "all packages on that list have been ported with the exception of one". :partying_face:

Become an Outreachy Mentor: support the growth and diversity of the OCaml community

Patrick Ferris announced

The call for open-source communities (and mentors for those communities) to participate in the May 2022 Outreachy round has just started :tada:

Hopefully the OCaml community will participate again given the success of the first round and the current winter batch. There must be some good OCaml 5 projects people are thinking about ;)) ?

By getting the ball rolling nice and early it will hopefully give more time to generate ideas and convince more people to (co-)mentor. Please ask questions, share ideas for projects etc. on this thread. Looking forward to hearing your ideas!

Cmon 0.1, a printer that shares

Frédéric Bour announced

I am happy to announce that the first version of Cmon is available.

Cmon stands for "CaMl Object Notation", it is a library for printing values with OCaml syntax.

The unusual feature is that the printer represents sharing by introducing let-binders. It tries to put them at "visually pleasing" positions using the ideas described here.

Printing with let-binders allow handling structures whose serialised representation is exponentially larger than the in-memory one, or where printing wouldn't terminate because of cyclic values. It is convenient to dump the internal state of tools that make use of sharing a lot, a situation that is common in program analysis tools.

# #install_printer Cmon.format;;
# let rec too_polite =
    lazy Cmon.(cons (string "thank you") (of_lazy too_polite))
  in Cmon.of_lazy too_polite;;
- : Cmon.t = let rec v0 = "thank you" :: v0 in
             v0

The actual formatting is handled by Pprint.

Note that no parser is provided: it is meant only for outputting (with debugging and logging in mind). When used carefully, copy-pasting to an OCaml top-level is enough to recover a value.

A few more examples are provided in the README.

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.