T
Thomas Leonard
roscidus.com · Personal blog · on HN since 2009
Thomas Leonard, a developer behind 0install and MirageOS work, writes about OCaml, unikernels, and secure systems on QubesOS.
What HN saysHN commenters recommend his Python-to-OCaml retrospective as the best article of its kind and a model for gradual rewrites.
82HN people shared it
48linked it in comments
51stories submitted
2.2Kstory points
4 months agolast shared
2009people per year2026
Most-shared posts
- 1Python to OCaml: Retrospective22 people · 434 points · first shared 2014 · 71 comments on HN
- 2Choosing a Python replacement for 0install18 people · 46 points · first shared 2013 · 9 comments on HN
- 3OCaml: what you gain10 people · 198 points · first shared 2014 · 118 comments on HN
- 4A Unikernel Firewall for QubesOS7 people · 162 points · first shared 2016 · 10 comments on HN
- 5Qubes-Lite with KVM and Wayland6 people · 141 points · first shared 2021 · 48 comments on HN
- 6CueKeeper: Gitting Things Done in the Browser6 people · 49 points · first shared 2015 · 1 comments on HN
- 7Polymorphism for beginners5 people · 15 points · first shared 2013 · discussion on HN
- 8Replacing Python4 people · 173 points · first shared 2013 · 139 comments on HN
- 9Ocaml objects4 people · first shared 2013
- 10Using TLA+ to Understand Xen Vchan3 people · 148 points · first shared 2019 · 12 comments on HN
- 11Isolating Xwayland in a VM3 people · 114 points · first shared 2021 · 51 comments on HN
- 12My first unikernel3 people · 26 points · first shared 2014 · discussion on HN
- 13Asynchronous Python vs OCaml3 people · 15 points · first shared 2013 · discussion on HN
- 14OCaml: The Bugs So Far2 people · 79 points · first shared 2014 · 15 comments on HN
- 15Vulkan Graphics in OCaml vs. C2 people · 4 points · first shared 2025 · discussion on HN
What HN people wrote when they linked it
tlavoie · 2025-09-20
I'd love to see software adopt strong capabilities-based models that enforce boundaries even within parts of a program. That is, with the principle of least authority (POLA), code that you call is passed only the capabilities you wish (e.g. opening a file, or a network socket), and not everything that the current process has access to. Thomas Leonard's post (https://roscidus.com/blog/blog/2023/04/26/lambda-capabilities/) covers this in great detail, and OCaml's newer Eio effect system will has aspects of this too.
The Emily language (locked-down subset of OCaml) was also interesting for actively removing parts of the standard library to get rid of the escape hatches that would enable bypassing the controls.
Modified3019 · 2024-09-20
Yeah I ended up with the same issue. While I’m technically inclined, I’m not nearly to the point where I can handle the fire hose of (badly named) abstraction at all levels like some people.
I could never have pulled off what this guy did https://roscidus.com/blog/blog/2021/03/07/qubes-lite-with-kvm-and-wayl… though ironically his journal is probably one of the best “how nix actually works” tutorials I’ve ever seen, even though it isn’t intended for that or complete for such a purpose. He’s the only reason I know that a derivation is basically an intermediate build object.
hawski · 2018-12-15
A rewrite can also mean a gradual change. A great example of this is the rewrite of 0install in OCaml from Python [0]. With such an approach you change module by module with old code and new code working side by side. It is of course not so easy, but it makes it possible to do on-line. A bit like with bits of Rust code that go in Firefox with each version.
I would like to know if anyone participated in a similar gradual rewrite and how it went.
It may be very hard for some architectures and also sometimes wrong architecture (prototype became production, some features were dropped along the way, a new feature is dog slow) may require big rewrite, even breaking APIs, then it would be impossible. But if one keeps API one can at least do comparison tests as more features are implemented.
[0] http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospective…
CodeArtisan · 2018-10-07
there is such a list for Go here
https://github.com/golang/go/wiki/FromXToGo
The best article of this kind that i have seen is by far
http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospective…
emmelaich · 2018-07-12
Ocaml, in comparison to other functional statically typed languages has had many successful Unix applications.
For a great tour of going to Ocaml (from Python), see Thomas Leonard's blog.
A retrospective is here but read the whole lot.
http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospective…
krat0sprakhar · 2017-01-24
Absolutely! If you're looking for fast, GC'd, native functional language I'd say OCaml is a great option. There's actually a very comprehensive set of blog posts migrating an open-source python based project to OCaml, that I'd recommend reading if you're looking for a more thorough comparison - http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospective…
Personally, I used OCaml while at university to write a programming language (http://jsjs-lang.org) and totally loved it. Real world OCaml is a great resource and I'd definitely recommend giving OCaml a try. My only regret is that I don't get to write OCaml as much as I want to due to the kind of projects I work on, but given that Bucklescript[0] and Reason[1] are moving ahead in full steam, that might change shortly too :)
[0]- https://bloomberg.github.io/bucklescript/
[1] - https://facebook.github.io/reason/
lacampbell · 2017-01-08
Constructive criticism is nothing to shy away from or be defensive about. Having criticism for something doesn't mean I think it's spam or off topic.
Again, for an example of a language X-to-language-Y rewrite story with some substance, that did a lot to boost the image of the language in many peoples eyes, see:
http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospective…
I'd love to something like that the next time "X rewritten in rust" etc gets to the front page of hacker news. A re-write in of itself tells me nothing.
lmm · 2016-06-08
Rust's type system is a bit less awful, and it's better oriented towards immutability-by-default. Its concurrency model is more explicit (which is to say, more verbose to use, but gives you a lot more control).
In a situation where Go is acceptable (i.e. GC is acceptable) you should probably be looking at OCaml (probably what I'd recommend; http://roscidus.com/blog/blog/2013/06/09/choosing-a-python-replacement… may be worth a look) or Haskell rather than Rust though. If you're talking about a long-running server process then I'd add Scala/Ceylon/F# to the list.
bru · 2016-03-31
Some differences are outlined in this insightful post: http://roscidus.com/blog/blog/2013/06/09/choosing-a-python-replacement…
Overall I'd say that OCaml is more pragmatic.
melling · 2016-03-02
I recently started to learn OCaml. This blog post convinced me that it was worth learning:
http://roscidus.com/blog/blog/2014/02/13/ocaml-what-you-gain/
I'm putting my notes on github, in case anyone wants a head start.
https://github.com/melling/ComputerLanguages/blob/master/ocaml.org
amirmc · 2014-08-16
People might also find the following post of interest.
Polymorphism for beginners - http://roscidus.com/blog/blog/2013/12/20/polymorphism-for-beginners/
wyatwerp · 2019-05-15
Off-hand, Mirage OS comes to mind - it completely upends how you would "build" and "run" back-end services, and it is written solely in a GC'ed language - OCaml. And all GC'ed languages are not equal; see https://roscidus.com/blog about a Linux package manager ported from Python to OCaml for performance reasons (followed by an OCaml reimplementation of a component in a virtualized OS).
Some infrastructure, e.g. database engines, is ubiquitous, but all instances are of the same few software products written in C/C++/Java. Those ubiquitous instances have banged most bugs out of those codebases, so it is an uphill battle there to convince incumbents and upstarts alike, of the value of a new implementation. But Rust & Pony are marvelously positioned to march up that hill, especially if you throw in multi-threading.
My impression is that only a minority of widely-programmed back-end infrastructure that suits Rust is written in C/C++ (say, map-reduce kernels). The code-base size & the data flow complexity inside those components is pretty limited, and Rust should be tractable at that scale.
Most widely-programmed infrastructure software - in the back-end and on cell phone OS'es - have been merrily using Java/Python/Ruby/Erlang. OCaml is quoted as being used in the management component of VMware. These are much larger applications; is there any evidence or hint that Rust isn't onerous to develop larger systems in? Without that evidence, I feel (not think) that a disciplined…
the_af · 2016-11-26
Over other languages in general? That's hard to say about any language :)
OCaml is a language in the ML family, is backed by INRIA and is the main language of Jane Street Capital (so it definitely has "real world" use!), which also contribute a lot to it. OCaml is pretty good for functional programming, and unlike Clojure, it's statically typed. If you like static typing -- which I personally think is the way to go -- that's a huge reason to prefer it over Clojure. You may also check out Haskell if you go that way.
An interesting case study about going to OCaml from another language (Python, in this case) was posted to HN many times already: http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospective… I recommend you read it if you want to learn more about why would one choose this language.
Why not choose a language in the ML family? Well, if not having C-like syntax is a deal breaker for you, then OCaml is going to frustrate you. A real programmer shouldn't let syntax stop them from learning new languages, though :)
Ultimately one has to try doing something with this kind of language, even if it's just a toy project. Just reading about it won't enlighten you much, and you will end up focusing on its syntax instead and deciding it looks too unfamiliar.
masklinn · 2016-01-26
If you read the original article[0] it did very well on the speed/size bench (5/5) but took a big hit on ease of writing (1/5) ending up with 48 between C# (47) and Haskell (49) and the following summary note:
> Everything would be incredibly fast, but getting new contributors would be very difficult due to the learning curve. There’s a risk of crashes as the library is not entirely memory safe, and there are likely to be changes ahead to the language. Probably writing the whole thing in ATS would be too much work for anyone.
ATS didn't make it to round 2[1] on grounds of use difficulty and difficulty of separating memory-safe and memory-unsafe code.
That seems prescient as the original ATS1 (ATS/Anairiats) was replaced by ATS2 (ATS/Postiats) a few months later, I don't know how compatible the two are but the FAQ puts ATS1 and ATS2 in different categories[2]
[0] http://roscidus.com/blog/blog/2013/06/09/choosing-a-python-replacement…
[1] http://roscidus.com/blog/blog/2013/06/20/replacing-python-round-2/
[2] https://github.com/githwxi/ATS-Postiats/wiki/ATS-implementations#ats1
ziotom78 · 2016-01-09
As camgunz said, emitting C code makes your compiler far more portable, as you can find C compilers for virtually every target (e.g., AFAIK, the current version of LLVM does not support SPARC architectures).
Another theoretical advantage of generating C code is that it should be easy to try adding bits of code written in these new languages to existing C/C++ projects. In this way you can test the new language on real life projects without the need of rewriting everything from scratch. (I have never followed this approach, although I have heard of people having done this [1].)
[1] http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospective… The languages here were quite different, though (Python/OCaml): but the author followed the idea of slowly converting a project to a new language by first rewriting parts of it. Had the OCaml compiler emitted Python code, I bet the task would have been easier.
talex5 · 2014-09-20
The list of publicly-known packages can be found on the default mirror site: http://roscidus.com/0mirror/
In general, though, if there's some package you want and you look for it there you're likely to be disappointed. 0install is probably more interesting to people wanting to publish software (and particularly, collections of related software).
Good use cases would be:
- Using it to build a package manager for a programming language (Rust would have been a good fit, I think, though like most languages they prefer to build their own language-specific system).
- Distributing applications for a desktop environment (the ROX desktop was the original motivation to create 0install).
- Managing plugins for a large application (Drupal, etc).
It might be best to think of it as a platform on which you can build a package manager or community.
Of course, people use it for individual applications too, but then you pay the cost of having to explain to your users what it is the first time. With a larger collection, the payoff is better.
tikhonj · 2013-09-29
I think the important insight from these articles is not which language the author ends up using (OCaml[1]), but rather which languages he's managed to rule out by now. In particular, I think it's good advice to avoid both ATS (however much I like dependent types) and Go, both for completely different reasons. You probably wouldn't want to use Rust in the short term either.
[1]: http://roscidus.com/blog/blog/2013/09/28/ocaml-objects/
ATS makes everything more difficult than it's worth except for some very specific use cases. Unlike some of the other languages like Haskell and OCaml, I don't think this is just because it's different; rather, it's because ATS is simply so much more demanding. It gives you extremely solid static guarantees and high performance, but it's a tool that really sacrifices expressiveness and programmability to get there. Haskell and OCaml may be difficult to learn, but ATS is actually difficult to use--a very different concept.
Go, on the other hand, is neither difficult to learn nor difficult to use. But, more generally, Go has very little to commend itself and--compared to the other options--quite a few shortcomings. If you're willing to put in a little bit of effort to learn something new, there are a whole bunch of options which are simply better. And you should be willing to put in the effort: your programming language is your single most important tool; it affects not only how you write your code and how you maintain it but even how you…
ralph · 2009-02-08
They hate D&D on the systems you've seen them use. I've seen them use it for many years on an OS called RISC OS, written by Acorn, designers of the ARM chip. There, users loved it. Everything supported it on the desktop. You had `filer' windows, and to save an application would just pop up a little window with a file icon and a text box for the leafname. Enter `foo' and drop it on the filer window where you wanted it.
But better than that, you could drop it on another application. Consequently, you could create and edit a pixmap, and drop it into a vector drawing program where it would become an embedded object. Want to edit it again? Drag it from there back to the pixmap editing program's icon on the icon bar. Neither of these touched the disc; it was in memory transfers. And the program code didn't need to know the difference between saving to another app., or saving to disc through a filer window.
Other aspects of the desktop were also novel and worked well. It had a three button mouse. A proper one. No silly scroll wheel. The right button did what the left button did, but altered in some way. So you'd pop up a context sensitive menu with the middle button. Select an item with L and the menu would disappear. With R the menu would stay there. Great for when you want to do several menu items in a row, e.g. adjusting an object's attributes.
Scrollbars worked better. Firstly, the mouse cursor on the screen only moved in one dimension once a drag with L…
transpute · 2025-06-04
On Xen, QubeOS uses vchan for inter-VM shared memory communication, https://roscidus.com/blog/blog/2019/01/01/using-tla-plus-to-understand…
Virtio on Xen is still a work in progress, https://wiki.xenproject.org/wiki/Virtio_On_Xen
ylk · 2024-11-08
In what way are [1] not “full OSes”? They’re minimal templates, but afaik they still run systemd, the kernel, etc. needed to boot the standard Linux systems they are.
When I clicked the link I was expecting something like a unikernel, eg https://roscidus.com/blog/blog/2016/01/01/a-unikernel-firewall-for-qub…
walterbell · 2023-10-23
MirageOS unikernels run directly on Xen, e.g. http://roscidus.com/blog/blog/2016/01/01/a-unikernel-firewall-for-qube…
> I replace the [QubesOS] Linux firewall VM with a MirageOS unikernel. The resulting VM uses safe (bounds-checked, type-checked) OCaml code to process network traffic, uses less than a tenth of the memory of the default FirewallVM, boots several times faster, and should be much simpler to audit or extend.
NanoVMs has OSS tools for golang unikernels on multiple hypervisors and cloud platforms, https://nanovms.com/dev/tutorials/running-go-unikernels
yawaramin · 2023-05-27
You could always try it out and see for yourself :-)
Here's a pretty good article about the transition: https://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospectiv…
ParetoOptimal · 2023-03-06
> The lack of Haskell's popularity is a clear indication that the abstractions added are not as valuable to programmers as the abstractions removed.
No it's not. At most it's an indication that of the group programmers familiar with Hakell's abstractions that they aren't enough to try the language more.
For it to be a clear indication those programmers would actually have to learn to effectively use Haskell's abstractions and compare it to a version in their former language that doesn't utilize the abstractions.
Almost nearly no one does this however... I can recall one instance that comes close:
http://roscidus.com/blog/blog/2013/06/09/choosing-a-python-replacement…
However that's not a comparision of abstractions.
3np · 2022-08-01
I have also been keeping an eye on [0] and [1]. Super interesting but just it seems like a deeper rabbit hole to get production-ready that I'm willing to bargain for at this point.
[0]: https://roscidus.com/blog/blog/2021/03/07/qubes-lite-with-kvm-and-wayl…
[1]: https://github.com/talex5/wayland-proxy-virtwl
VTimofeenko · 2021-12-22
Firejail with spawning nested Xorg works fine for me, including text-only copypaste between "host" and "guest" and automatic file synchronization through bind-like mounts. For some firejails I also use Linux network namespaces to control traffic going through taps. My introduction to this approach was the alternative Gentoo handbook by Sakaki[1], but the principles would apply on any distro.
There's also a very interesting read on Qubes-like experience on NixOs with Wayland and XWayland[2,3].
[1]: https://wiki.gentoo.org/wiki/User:Sakaki/Sakaki%27s_EFI_Install_Guide/…
[2]: https://roscidus.com/blog/blog/2021/03/07/qubes-lite-with-kvm-and-wayl…
[3]: https://roscidus.com/blog/blog/2021/10/30/xwayland/
LeonidasXIV · 2021-11-05
Not from Python to Haskell but Thomas Leonard[1] has a very nice series of blog posts about migrating 0install away from Python to OCaml, of which many points also apply to Haskell which he evaluated as a choice as well.
[1]: https://roscidus.com/blog/blog/2013/06/09/choosing-a-python-replacemen…
mlinksva · 2021-03-21
There's a larger amount of overlap with https://spectrum-os.org/ (which builds on Nix). https://roscidus.com/blog/blog/2021/03/07/qubes-lite-with-kvm-and-wayl… is also really interesting (and discusses Nix and SpectrumOS) and itself was discussed at https://news.ycombinator.com/item?id=26378854
hwayne · 2020-02-23
I wrote a few case studies here: https://www.hillelwayne.com/post/business-case-formal-methods/#why-use… They're case studies that are targeted towards bosses, so focus on how it saves time and money. A couple more I know of:
* https://andy.hammerhartes.de/finding-bugs-in-systems-through-formaliza…
* http://roscidus.com/blog/blog/2019/01/01/using-tla-plus-to-understand-…
* https://www.youtube.com/watch?v=oMSmkRGzQ64
agumonkey · 2019-06-12
dropbox, considering their size, is really in a position for a solid rewrite.
ocaml ? http://roscidus.com/blog/blog/2014/06/06/python-to-ocaml-retrospective…
nim ? rust ? go ?