HNHacker News
TopNewBestAskShowJobs

kcsrk

214 karma · joined February 10, 2015

https://kcsrk.info
submissionscomments
kcsrk··on An O(x)Caml book that runs
We don't even have the capability to build a _32-bit_ Unikernel now! That said, we _can_ boot 64-bit MirageOS unikernels on baremetal platforms. We use this capability in FIDES, which boots MirageOS unikernels on a bare-metal, security-enhanced, soft-core RISC-V processor: https://kcsrk.info/papers/fides_asiaccs_2026.pdf.

OCaml 4.x does support 32-bit native compilation, and I don't think it should be too hard to be able to boot them in the browser using v86.

kcsrk··on An O(x)Caml book that runs
Super interesting. Thanks for sharing.

I have used Jupyter notebooks with a Docker deployment in my prior courses for OCaml and Prolog, with support for auto grading (using nbgrader). Jupyter notebooks aren’t great for version control. Otherwise, it worked pretty well across multiple iterations of the course with new professors coming in and independently being able to use the infra.

kcsrk··on An O(x)Caml book that runs
Author of the post here.

I need a Linux VM to illustrate a couple of things in the last few lectures. Showing C undefined behaviour, memory safety issues and how that becomes security issues, compiling OCaml program to show test coverage, and being able to build unikernels. So can’t completely do away with Linux VMs.

For Unikernels, currently v86 is 32-bit only and OCaml 5 has dropped support for native 32-bit backends. In order to boot 64-bit unikernels, I’d need qemu. All of this could be done, but (a) this is likely to be quite slow (and the current emulation already is) and (b) the learning objectives are probably not improved a lot with the additional infrastructure. Hence, dropped it.

kcsrk··on O(x)Caml in Space
What’s surprised me in the last few months is that agents are great at producing OCaml 5+ and OxCaml code, not much of which is out there in the training data. OxCaml’s strong types and modes seem to serve as great testable oracles to guide the agents.

I taught a course on concurrent programming based on OCaml 5 and OxCaml where almost all of the code in the teaching materials were vibe coded. I reviewed all of the code (because I was teaching it to a class of 50+ students) and frankly the agent writes better O(x)Caml (mostly) than me.

kcsrk··on Control structures in programming languages: from goto to algebraic effects
Not necessarily. You can implement them using a monad. See https://dl.acm.org/doi/10.1145/2804302.2804319. That said, in GHC Haskell the implementation on top of stack switching seems to outperform other implementation strategies. See https://github.com/ghc-proposals/ghc-proposals/blob/master/p....

In OCaml 5, we’ve made it quite fast: https://kcsrk.info/papers/drafts/retro-concurrency.pdf. For us, the goal is to implement concurrent programming, for which a stack switching implementation works well. If you use OCaml effect handlers to implement state effect, it is going to be slower than using mutable state directly. And that’s fine. We’re not aiming to simulate all effects using effect handlers, only non-local control flow primitives like concurrency, generators, etc.

kcsrk··on Evolving the OCaml Programming Language (2025) [pdf]
It was overlooked because I didn't know!

Great to hear about virt-v2v. I will reach out to you by email.

kcsrk··on Evolving the OCaml Programming Language (2025) [pdf]
It is often hard to see the shape of these things before a serious PR attempt is made. Each of the PRs reveals more of the shape of the problem being solved. Hard to skip them in practice, especially for new contributors.
kcsrk··on Evolving the OCaml Programming Language (2025) [pdf]
You are right that the dynamic arrays story does not read like a straightforward “how to inspire contributions.” But part of what I wanted to do in the talk was to show things as they actually unfolded. In OCaml compiler development, there is a very strong emphasis on correctness and long-term stability. That can make contributions, especially to core language features, feel harder than they might in faster-moving ecosystems.

The dynamic arrays case is a good illustration. What began as a small PR grew into years of design iterations, debates about representation, performance, and multicore safety, and eventually a couple of thousand lines of code and more than 500 comments before it landed. From one perspective, that looks discouraging. From another, it shows the weight we place on getting things right, because once a feature ships, it is very hard to undo.

That tension, between wanting to be open and encouraging contributions but also needing to protect stability, is something I think we should be talking about openly. My hope is that by making the process more visible we can demystify it and help contributors understand not just what happened, but why.

kcsrk··on Evolving the OCaml Programming Language (2025) [pdf]
I am the author of the talk here o/.

This talk is a _subjective_ take on how the OCaml programming language evolves, based on my observations over the last 10 years I've been involved with it. My aim/hope is to demystify the compiler development process and the tradeoffs involved and encourage more developers to take a shot at contributing to the OCaml compiler.

Happy to answer questions, but also, more importantly, hear your comments and criticisms around the compiler development process, ideas to make it more approachable, etc.

kcsrk··on OCaml Programming: Correct and Efficient and Beautiful
Kcas is the Haskell STM analogue in OCaml https://github.com/ocaml-multicore/kcas/
kcsrk··on OCaml 5.0 Multicore is out
Right. It is hard in general to compare performance or generated code across languages as they make different trade offs. Table 3 and 5 show compilation of our memory model to X86 and ARMv7. The compilation and the related work section discusses trade offs.

To summarise, atomic read and write in OCaml is more expensive than C++ since C++ SC atomics only establish total order between SC operations on not operations that are weaker but related to SC operations by happens before. We need stronger atomics for local data race freedom.

Our non atomic are also stronger than non atomics on C++ and Java. That said, The non atomic operations are free on X86 (compiled to plain loads and stores) and involve a lightweight fence before stores on weaker architectures such as ARM, Power and RISC-V. The performance results show that extra fences before stores have a barely noticeable impact on ARM and Power.

kcsrk··on OCaml 5.0 Multicore is out
See examples in the second section and the results in the paper: https://kcsrk.info/papers/pldi18-memory.pdf
kcsrk··on OCaml 5.0 Multicore is out
Still early days, but I had done some exploratory work in the past on Reagents, a composable lock-free library [1]. Now that OCaml 5 is released, we're reviving this work.

It's semantics is weaker than STM -- unlike STM, it doesn't provide serializability but Reagents can compile down to multi-word compare and swap operations, which can be implemented with the help of hardware transactions (when present) or efficient software implementations of it [2]. Hence, Reagent programs should be faster than STM.

[1] https://github.com/ocaml-multicore/reagents [2] https://arxiv.org/pdf/2008.02527.pdf

kcsrk··on OCaml 5.0 Multicore is out
The local types are less invasive than the full support for typed effects. In particular, they are opt-in and associated complexity is pay-as-you-go. In my initial experiments, they seemed pretty nice to program with.
kcsrk··on OCaml 5.0 Multicore is out
Here are some parallel benchmarks from the Sandmark continuous benchmarking service: https://sandmark.tarides.com/?app=Parallel+Benchmarks&parall...
kcsrk··on OCaml 5.0 Multicore is out
Rather than a full effect system, we're very likely to have lexically scoped "checked" effects with the help of modal types. I briefly talked about it at the end of my ICFP keynote: https://icfp22.sigplan.org/details/icfp-2022-papers/48/Retro...

There are other cool stuff that is being worked on, which I am very excited about: https://discuss.ocaml.org/t/jane-street-compiler-development.... Hopefully, we will see many of these make it into OCaml 6.

kcsrk··on OCaml 5.0 Alpha Release
For nested parallel computations (think Scientific Programming, where one would use OpenMP, Rust Rayon, etc), we have domainslib [1]. Eio, a direct-style, effect-based IO library is pretty competitive against Rust Tokio [2]. The performance will only get better as we get closer to the 5.0 release.

[1] https://github.com/ocaml-multicore/domainslib

[2] See the http server performance graphs at https://tarides.com/blog/2022-03-01-segfault-systems-joins-t...

kcsrk··on OCaml 5.0 Alpha Release
Parallelism [1] and native-support for concurrency through effect handlers [2].

[1] https://kcsrk.info/webman/manual/parallelism.html

[2] https://kcsrk.info/webman/manual/effects.html

kcsrk··on OCaml 5.0 Alpha Release
I would also recommend reading the effect handlers tutorial in OCaml 5.0 manual: https://kcsrk.info/webman/manual/effects.html.
kcsrk··on OCaml Multicore merged upstream
> it seems it provides sequential consistency when using atomics and acquire/release semantics when not.

(author of the said paper here) This is wrong. I suggest reading the paper closely. If not, the morning paper has a good summary [1,2].

[1] https://blog.acolyer.org/2018/08/09/bounding-data-races-in-s...

[2] https://blog.acolyer.org/2018/08/10/bounding-data-races-in-s...

kcsrk··on PR to Merge Multicore OCaml
Effect handlers are a foundation of all non-local control flow abstractions. Anything that requires fancy control-flow can be implemented with effect handlers. This includes green threads, async/await, generators (or iterators as some languages call it), but also higher-level applications such as algorithmic differentiation, probabilistic programming, model checking and fuzzing of parallel programs, etc.

A few of these applications were discovered only very recently. The aim is that this language primitive will inspire further discoveries for expressing useful abstractions elegantly.

Some of these ideas are summarised in this talk: https://m.youtube.com/watch?v=VEhkhxoGJSk

kcsrk··on Adapting the OCaml Ecosystem for Multicore OCaml
We don't compare against Go pervasively. Benchmarking across languages is hard generally, but here is a result on a specific benchmark comparing several versions of OCaml benchmarks against Go and Rust on a Http server benchmark: https://github.com/ocaml-multicore/retro-httpaf-bench/pull/1....

If there are suggestions to make the Go and Rust versions, please feel free to tell us how in the issue tracker.

kcsrk··on Multicore OCaml: April 2021
Yes, exactly. The reason why monadic concurrency libraries such as Lwt and Async is that the OCaml language does not support concurrency natively. If it did, we would have built something similar to the `ocaml-aeio` library.

Btw there is a modern instantiation of `ocaml-aeio` called `eieio` [1] which supports Linux's io-uring. Eventually, this will be extended to support all the modern I/O stacks on different platforms, and also support performing I/O on multiple cores.

[1] https://github.com/ocaml-multicore/eioio

kcsrk··on Multicore OCaml: April 2021
Abandoned is perhaps too strong a term :-). Effect handlers in the language are supported by fibers, lightweight stacklets managed by the runtime. The details of the implementation can be found in the upcoming research paper in PLDI'21 conference [1]. The effect handlers in Multicore OCaml today do not provide effect safety. Programs are not statically guaranteed to handle all the effects they may perform. This is only as bad as exceptions in OCaml and every other mainstream language with exceptions.

We are working on developing an effect system, which will ensure effect safety i.e, the compiler ensures that all the effects performed are caught. You also get a nice inferred type that says what effects a particular function may perform; if it performs none, then it is a pure function! This implementation would still use the current fiber support in the runtime. Leo White, one of the developers of Multicore OCaml had given a talk on this new effect system a few years ago [2]. That's the best place today to learn about the new effect handlers.

The plan is to first add the fiber runtime support to OCaml without the syntax extensions for effect handlers, and then introduce syntax along with the effect system.

[1] https://arxiv.org/abs/2104.00250

[2] https://www.janestreet.com/tech-talks/effective-programming/

kcsrk··on Multicore OCaml: April 2021
(One of the Multicore OCaml devs here)

We have prototyped offloading CPU intensive computations in Lwt programs using Multicore OCaml [1]. We're currently working with Lwt maintainers to upstream it.

[1] https://sudha247.github.io/2020/10/01/lwt-multicore/

kcsrk··on Multicore OCaml: April 2021
(One of the authors of the mentioned paper [1])

Firstly, if you are using high-level synchronisation mechanisms such as mutexes and condition variables, or higher-level concurreny libraries such as java.util.concurrent, you shouldn't worry about the memory model. C++, Java and OCaml ensure that properly synchronised programs do not exhibit surprising behaviours. Such programs have sequentially consistent semantics i.e, the observed behaviour is one of the permitted interleavings of the threads in the program. Rust inherits C++ memory model [2], but if you are using the safe subset, then you will never have to think about it. Memory model is important only to those who write the concurrency libraries. If you are still keen, read on.

The OCaml memory model is certainly simpler than the C++ and Java memory model, but being more efficient is not one of our goals. C++ memory model permits a partially-ordered lattice of stronger memory accesses starting from access to non-atomic memory locations to sequentially consistent access with increasing cost as you move up the lattice. OCaml memory model only provides two -- atomic and non-atomic, representing approximately the top and the bottom of the lattice.

OCaml memory model is also stronger than Java in that our data races are bound not-only in space like Java (data races on certain variables don't affect behaviours on other variables) but also in time (surprising behaviours stop affecting the program after the race ends unlike Java; see example 2 from [1]). This permits modular reasoning of racy and non-racy parts of the program which is not the case with C++ and Java.

The catch is that we have to disallow load-to-store reordering to get the stronger guarantees. Relaxed memory models such as ARM and Power do in fact permit these reorderings, and we have to compile OCaml code (including sequential one) such that the load-to-store reordering is disallowed. This can be done fairly cheaply. It is free on x86 which doesn't perform load-to-store reorderings, and has a small cost (up to 3%) on ARM and Power architectures whose memory models permit load-to-store reorderings.

[1] https://kcsrk.info/papers/pldi18-memory.pdf

[2] https://doc.rust-lang.org/nomicon/atomics.html

kcsrk··on Parallel ray tracing benchmark for functional programming languages
Having optimised the Multicore OCaml implementation, this benchmark benefits heavily from inlining and unboxing. MLton style aggressive inlining and unboxing is the way to go here. MPL builds on MLton and it works out great!

Multicore OCaml compiler doesn’t yet use the new flambda2 optimisation passes. We witnessed good improvements with flambda2 on stock OCaml on the tight loops in this program; the compiler was doing all the right things. It seemed not worthwhile to continue with hand optimising the implementation leading to non-idiomatic FP code. We hope to get back to this once flambda2 Passes are integrated with Multicore OCaml compiler.

kcsrk··on Parallel Programming in Multicore OCaml
> but these are unlikely to scale as well under ParMinor

To be clear, the said systems programs are not going to see slowdown when run in a sequential setting (which is what I expect the majority of use cases will be). It is unlikely that these systems programs will immediately want to take advantage of parallelism. Moreover, Multicore OCaml aims to add support for shared-memory parallel programming to increase throughput of the program. Getting high throughput and maintaining very low latency is a big challenge generally, and can't just be solved by the runtime system. It needs a different way of writing programs altogether.

> Indeed, with the latter, it is not going to be possible to have a low-latency domain and a non-low-latency domain coexist: the whole program has to be written in the low-latency style.

This is wrong. If the low-latency code is written as it is (no allocations), then in ParMinor the low-latency domain will be responsive at the cost of increasing the latency on non-low-latency domain. Of course, no GC safe points should be inserted in those low-latency code. This design is not ossified.

Another details to remember is that ParMinor is a stop-the-world parallel minor collector. The major collection is concurrent mark-and-sweep which keeps the latency low. I'd recommend checking out the new concurrent GC for GHC which uses concurrent collection for the major heap, and parallel collection for the minor heap [1], which is similar to ParMinor.

Ultimately, Multicore OCaml aims to offer an easy way of helping 95% of the programs to take advantage of parallel execution for increasing throughput without compromising latency. It is quite hard to fully support different expert cases especially since they rely on the details of the existing runtime system, which may no longer hold when the runtime system changes.

[1] https://dl.acm.org/doi/pdf/10.1145/3381898.3397214

kcsrk··on Parallel Programming in Multicore OCaml
No breaking changes with the parallel minor collector (ParMinor). This is the design which will be upstreamed. See https://arxiv.org/pdf/2004.11663.pdf for details.
kcsrk··on Parallel Programming in Multicore OCaml
Better throughput, and almost no impact on latency overall. See https://arxiv.org/abs/2004.11663 section 6.2 for parallel performance evaluation.
Page 1 of 2Next →