Skip to content

Commit 44fcebc

Browse files
sabinegithub-actions[bot]
authored andcommitted
[scrape.yml] New OCaml Planet blog posts and videos
1 parent acf1656 commit 44fcebc

8 files changed

+246
-0
lines changed
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
---
2+
title: Functional Networking for Millions of Docker Desktops
3+
description:
4+
url: https://dl.acm.org/doi/10.1145/3747525
5+
date: 2025-08-01T00:00:00-00:00
6+
preview_image:
7+
authors:
8+
- Anil Madhavapeddy
9+
source:
10+
ignore:
11+
---
12+
13+
14+
Docker is a developer tool used by millions of developers to build, share and
15+
run software stacks. The Docker Desktop clients for Mac and Windows have long
16+
used a novel combination of virtualisation and OCaml unikernels to seamlessly
17+
run Linux containers on these non-Linux hosts.
18+
19+
We reflect on a decade of shipping this functional OCaml code into production
20+
across hundreds of millions of developer desktops, and discuss the lessons
21+
learnt from our experiences in integrating OCaml deeply into the container
22+
architecture that now drives much of the global cloud. We conclude by observing
23+
just how good a fit for systems programming that the unikernel approach has
24+
been, particularly when combined with the OCaml module and type system.
25+
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
title: mlgpx is the first Tangled-hosted package available on opam
3+
description:
4+
url: https://anil.recoil.org/notes/tangled-and-ci
5+
date: 2025-08-17T00:00:00-00:00
6+
preview_image:
7+
authors:
8+
- Anil Madhavapeddy
9+
source:
10+
ignore:
11+
---
12+
13+
<p>Since I wrote about the new <a href="https://anil.recoil.org/notes/disentangling-git-with-bluesky">ATProto-powered Tangled Git forge</a> a few months ago, it's come along by leaps and bounds!</p>
14+
<p>First, and most excitingly, they've added <a href="https://blog.tangled.sh/ci">continuous integration via Spindles</a> which are built in a nice ATProto style:</p>
15+
<blockquote>
16+
<p>When you push code or open a pull request, the knot hosting your repository
17+
emits a pipeline event (sh.tangled.pipeline). Running as a dedicated service,
18+
spindle subscribes to these events via websocket connections to your knot.</p>
19+
</blockquote>
20+
<p>The pipelines are Nix-only right now, so I braved using it<sup><a href="https://anil.recoil.org/news.xml#fn-1" role="doc-noteref" class="fn-label">[1]</a></sup> for a new <a href="https://tangled.sh/@anil.recoil.org/ocaml-gpx">GPS Exchange Format library in OCaml</a> that I wrote. The <a href="https://tangled.sh/@anil.recoil.org/ocaml-gpx/pipelines">pipelines</a> should look familiar, and the <a href="https://tangled.sh/@anil.recoil.org/ocaml-gpx/blob/main/.tangled/workflows/build.yml">description format</a> very straightforward.</p>
21+
<p>Secondly, the service has <a href="https://blog.tangled.sh/stacking">added</a> support for <a href="https://github.com/jj-vcs/jj">JJ</a> stacked pull requests, which are the closest I've seen to the <a href="https://blog.janestreet.com/ironing-out-your-release-process/">Jane Street Iron diff workflow</a> which I've been wanting to try in open source for ages. You can see the interdiff review process on a recent PR by <a href="https://tangled.sh/@winter.bsky.social">Winter</a> who add support for <a href="https://tangled.sh/@tangled.sh/core/pulls/423">engine-agnostic Spindle workflows</a>, which should pave the path for a Docker or BuildKit engine alongside the existing Nixery-based one.</p>
22+
<p>And thirdly, the general quality-of-life of the web frontend has improved dramatically, with a nice <a href="https://tangled.sh/">timeline</a>, <a href="https://tangled.sh/@anil.recoil.org?tab=repos">repo list</a>, and <a href="https://tangled.sh/@anil.recoil.org">profile pages</a>. I'm running two knots right now (one on Recoil, and one in the Cambridge Computer Lab), and both have been very painfree. I wrote one of the earliest <a href="https://tangled.sh/@anil.recoil.org/knot-docker">Dockerfiles</a> for it, but there's now a <a href="https://tangled.sh/@tangled.sh/knot-docker">community-maintained Knot Docker</a> setup which I've switched to. Doesn't take very long at all; give it a try!</p>
23+
<p>Because I've been using Tangled so much, I <a href="https://github.com/ocaml/dune/pull/12197">added support for Tangled metadata</a> to Dune to make OCaml package maintainence easier. This will appear in Dune 3.21 in a few months, but in the meanwhile enjoy the first <a href="https://ocaml.org/p/mlgpx/latest">Tangled.sh package on opam</a>. It's a simple GPX library I used in my <a href="https://anil.recoil.org/notes/owntracks-and-lifecycle">recent trip</a> to Botswana. All you need in your <code>dune-project</code> will be:</p>
24+
<pre><code>(lang dune 3.21)
25+
(name mlgpx)
26+
(generate_opam_files true)
27+
(source (tangled @anil.recoil.org/ocaml-gpx))
28+
</code></pre>
29+
<p>The only major thing I'm missing from Tangled is support for private repositories now, but I'm very content using it for public content today. Beware as usual that it's still in alpha, so don't trust super-ultra-mega-important stuff to it unless you've git mirrored elsewhere.</p>
30+
<section role="doc-endnotes"><ol>
31+
<li>
32+
<p>...with the help of my trusty local Nixer <a href="https://ryan.freumh.org" class="contact">Ryan Gibb</a>. Noone should ever Nix by themselves.</p>
33+
<span><a href="https://anil.recoil.org/news.xml#ref-1-fn-1" role="doc-backlink" class="fn-label">↩︎︎</a></span></li></ol></section>
34+
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
title: OCaml Weekly News, 12 Aug 2025
3+
description:
4+
url: https://alan.petitepomme.net/cwn/2025.08.12.html
5+
date: 2025-08-12T12:00:00-00:00
6+
preview_image:
7+
authors:
8+
- Caml Weekly News
9+
source:
10+
ignore:
11+
---
12+
13+
<ol><li><a href="https://alan.petitepomme.net/cwn/2025.08.12.html#1">Slipshow!</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.08.12.html#2">Miou, a simple scheduler for OCaml 5</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.08.12.html#3">Dream development open video call</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.08.12.html#4">Other OCaml News</a></li></ol>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
title: OCaml Weekly News, 19 Aug 2025
3+
description:
4+
url: https://alan.petitepomme.net/cwn/2025.08.19.html
5+
date: 2025-08-19T12:00:00-00:00
6+
preview_image:
7+
authors:
8+
- Caml Weekly News
9+
source:
10+
ignore:
11+
---
12+
13+
<ol><li><a href="https://alan.petitepomme.net/cwn/2025.08.19.html#1">httpcats, ocaml-h1, vif, and hurl: a webstack for OCaml 5</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.08.19.html#2">Why Lean 4 replaced OCaml as my Primary Language</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.08.19.html#3">Reminder: You Can Still Come to Warsaw for FUN OCaml</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.08.19.html#4">Other OCaml News</a></li></ol>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
title: An OCaml MCP server
3+
description:
4+
url: https://jon.recoil.org/blog/2025/08/ocaml-mcp-server.html
5+
date: 2025-08-20T00:00:00-00:00
6+
preview_image:
7+
authors:
8+
- Jon Ludlam
9+
source:
10+
ignore:
11+
---
12+
13+
<section><h1><a href="https://jon.recoil.org/atom.xml#an-ocaml-mcp-server" class="anchor"></a>An OCaml MCP server</h1><ul class="at-tags"><li class="published"><span class="at-tag">published</span> <p>2025-08-20</p></li></ul><ul class="at-tags"><li class="notanotebook"><span class="at-tag">notanotebook</span> </li></ul><p>LLMs are proving themselves superbly capable of a variety of coding tasks, having been trained against the enormous amount of code, tutorials and manuals available online. However, with smaller languages like OCaml there simply isn't enough training material out there, particularly when it comes to new language features like <a href="https://ocaml.org/manual/5.3/effects.html">effects</a> or new packages that haven't had time to be widely used. With my colleagues <a href="https://anil.recoil.org/">Anil</a>, <a href="https://ryan.freumh.org/">Ryan</a> and <a href="https://toao.com/">Sadiq</a> we've been exploring ways to <a href="https://anil.recoil.org/notes/cresting-the-ocaml-ai-hump">improve this situation</a>. One way we can mitigate these challenges is to provide a Model Context Protocol (<a href="https://modelcontextprotocol.io">MCP</a>) server that's capable of providing up-to-date info on the current state of the OCaml world.</p><p>The <a href="https://docs.anthropic.com/en/docs/mcp">MCP specification</a> was released by Anthropic at the end of last year. Since then it has become an astonishingly popular mechanism for extending the capabilities of LLMs, allowing them to become incredibly powerful agents capable of much more than simply chatting. There are now a huge variety of MCP servers, from one that provides <a href="https://github.com/r-huijts/firstcycling-mcp">professional cycling data</a> to one that can <a href="https://github.com/GongRzhe/Gmail-MCP-Server">do your email</a>. The <a href="https://github.com/punkpeye/awesome-mcp-servers">awesome mcp server list</a> already lists hundreds, and these are just the <em>awesome</em> ones!</p><p>I've been working with <a href="https://toao.com/">Sadiq</a> to make an <a href="https://github.com/sadiqj/odoc-llm/">MCP server for OCaml</a>, with an initial focus on building it such that it can be hosted for everyone rather than something that is run locally. Our plan is to start with a service that can help with choosing OCaml libraries, by taking advantage of the work done by <a href="https://github.com/ocurrent/ocaml-docs-ci/">ocaml-docs-ci</a> which is the tool used to generate the documentation for all packages in <a href="https://github.com/ocaml/opam-repository">opam-repository</a> and is served by <a href="https://ocaml.org/">ocaml.org</a>. As well as producing HTML docs, we can also extract a number of other formats from the pipeline, including a newly created <a href="https://github.com/ocaml/odoc/pull/1341">markdown backend</a>. Using this, we can get markdown-formatted documentation for the every version of every package in the OCaml ecosystem.</p></section><p>Continue reading <a href="https://jon.recoil.org/blog/2025/08/ocaml-mcp-server.html">here</a></p>

data/planet/jonludlam/week-33.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
title: Week 33
3+
description:
4+
url: https://jon.recoil.org/blog/2025/08/week33.html
5+
date: 2025-08-19T00:00:00-00:00
6+
preview_image:
7+
authors:
8+
- Jon Ludlam
9+
source:
10+
ignore:
11+
---
12+
13+
<section><h1><a href="https://jon.recoil.org/atom.xml#week-33" class="anchor"></a>Week 33</h1><ul class="at-tags"><li class="published"><span class="at-tag">published</span> <p>2025-08-19</p></li></ul><ul class="at-tags"><li class="libs"><span class="at-tag">libs</span> <p>cohttp yojson jsonm</p></li></ul><p>More work this week on the OCaml MCP server. Sadiq and I met before I went away on holiday and discussed the next steps to 'park' the work on the MCP server. The final steps are:</p><ul><li>Write a README</li><li>Write and run a small script to fix a problem with module-type names</li><li>Write up and publish a blog post</li></ul><p>Not much, right? As always though, writing things up lead to a whole load more work.</p><p>The first problem occurred when writing up how it parsed the input docs. It turned out that when converting the repo so that it took markdown formatted files (using a <a href="https://github.com/jonludlam/odoc/tree/odoc-llm-markdown">slightly tweaked</a> version of <a href="https://github.com/ocaml/odoc/pull/1341">davesnx's PR</a>), Claude had decided that the way to do this was to first convert the markdown into HTML, and then use the HTML parser it had already built. Whilst tidying this up, Claude was remarkably keen to just use regexps to parse the markdown rather than using a pre-existing markdown library, so it took a little persuasion to get it into a state I was happy with.</p><p>The second issue was that the script that form the bulk of the repo had been written at different times, and therefore Claude didn't really take into account any of the decisions it had made in one script when building the next. So most of the command-line arguments were slightly different, which made writing up a mini 'howto' in the README quite a jarring experience.</p><p>Thirdly, and most importantly, we had decided that we needed a few example searches to show how the system worked. We'd already had a <a href="https://jon.recoil.org/07/week28.html" title="week28">useful experience</a> with this when Anil had tried to search for a 'time and date parsing and formatting' library, so it shouldn't really have been a surprise that trying a few more examples showed some more interesting behaviour. Specifically, the searches I wanted to do were for an "HTTP client", "JSON parser", "Cryptographic Hash" and Anil's time-and-date query, and in actually trying these searches and critically examining the results, I had to go back and figure out why they weren't giving me the results I had expected.</p><p>The first of these searches I had anticipated would be quite interesting, as this is a query that should show the OCaml ecosystem <a href="https://discuss.ocaml.org/t/simple-modern-http-client-library/11239">missing an obvious HTTP client</a>. However, even with this in mind one of the top results was one of Cohttp's module types, <a href="https://jon.recoil.org/reference/cohttp/cohttp/Cohttp/Generic/Client/module-type-S/index.html"><code>Cohttp.Generic.Client.S</code></a>. This, of course, isn't much use if you're looking for an HTTP client, as module-types aren't going to give you an implementation to actually use. So I decided that we'd exclude module-types from the results. This turned out to be slightly more tricky than I anticipated as we'd lost the distinction between modules and module types further back in the pipeline, so Claude had to do some plumbing to ensure we had this information at the point we were doing the search.</p><p>The cryptographic hash search gave some plausible looking results, so I moved on to the JSON search. I was expecting to see <a href="https://jon.recoil.org/reference/yojson/yojson/Yojson/index.html"><code>Yojson</code></a> somewhere near the top of the list as that's a very popular library. I was also expecting to see <a href="https://jon.recoil.org/reference/jsonm/jsonm/Jsonm/index.html"><code>Jsonm</code></a> somewhere near the top - or at least I'd like to be able to find it by searching for a 'streaming parser' as that's one of its key strengths. However, searching for "JSON parser" yielded some less than brilliant answers. The top 5 results were for modules in the packages <code>yojson-five</code>, <code>decoders-yojson</code>, <code>decoders-jsonaf</code>, <code>ocplib-json-typed-browser</code> and <code>ppx_protocol_conv_jsonm</code>. While all of these are clearly in the same realm as I was after, having <code>jsonm</code> show up literally 99th in the list, and <code>yojson</code> itself not in the top 100 wasn't a great result.</p><p>Some investigation showed that yojson had a particularly bad showing because the description of the module <a href="https://jon.recoil.org/reference/yojson/yojson/Yojson/Basic/index.html"><code>Yojson.Basic</code></a> was the empty string! This turned out to be because of some bad error-handling logic in the summariser script, which ended up turning some errors into a blank description. Since running the summariser costs actual money, I didn't want to just rerun the whole thing, so I asked Claude for a script to find these problems and rerun them. The problem is not totally trivial as the summaries of child modules are used when generating the summary for parents, so when one is regenerated we should regenerate the summaries of all ancestors too. Given my recent experiences with Claude I'd like to look this over quite carefully before letting it loose on my data, so I've run it on yojson, which seemed to do the right thing, but not yet on the rest of the packages.</p><p>Having fixed this, I still found that <code>jsonm</code> was making a very poor showing. This turned out to be because the description it gives itself is a "Non-blocking streaming JSON codec for OCaml" which had a fairly low similarity with "JSON parser". I was using a fairly small embedding model for the queries - Qwen/Qwen3-Embedding-0.6B, so I thought I might address this by using a larger one, and opted for Qwen/Qwen3-Embedding-8B. The machine I had been using for the MCP server has no GPU and had taken a while to do the embeddings using the 0.6B model, so I switched to generating them on my M4 macbook. This went <i>much</i> faster, though since I have about 70Mb of module summaries it still took quite a while. This improved the situation somewhat, but it was still not high in the list.</p><p>So I took a step back and had a think about the problem some more. Searching for a JSON parser is really quite a high-level search, and when evaluating the results I realised I was really thinking in terms of packages rather than modules. So I thought we could split the search in two - a package search and a module search. The package search would be used for the broad queries where you're interested in pulling in whole chunks of functionality, and the module search is for more low-level queries. In fact, the 'time and dating formatting' query is somewhere in between, so I might need to have some more example queries for the module search functions. In addition, the module search could be restricted to the set of packages you're using, which might make it even more useful.</p><p>Part of the split meant that I needed a different source of 'popularity' for the packages than the occurrences data that came out of docs ci, as that was per-module and I needed something per-package. The obvious thing is to look at reverse dependencies in opam. I have this kind-of working, but it's currently not particularly smart, so this will need a little more attention. For example, it currently thinks that <a href="https://melange.re/v5.0.0/">melange</a> has over 3000 reverse dependencies.</p><p>With these changes in place, a package search for 'JSON parser' now returns <code>yojson</code> as number one, followed by <code>ppx_deriving_yojson</code>, <code>ezjsonm</code>, <code>ocplib-json-typed</code> and <code>jsonaf</code>. Unfortunately <code>jsonm</code> is still languishing in 27th place, so there's still some tweaking to do.</p></section><p>Continue reading <a href="https://jon.recoil.org/blog/2025/08/week33.html">here</a></p>

0 commit comments

Comments
 (0)