Skip to content

Commit c6b6cc5

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

12 files changed

+1637
-2
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
title: 'Database Testing in OCaml: From CRUD to Connection Pool Stress Testing'
3+
description: 'Building a comprehensive database testing suite for Chaufr: integration
4+
tests, transaction verification, migration rollback testing, connection pool stress
5+
tests, and performance benchmarks using Alcotest, Lwt, and Caqti'
6+
url: https://fearful-odds.rocks/blog/database-testing-for-chaufr
7+
date: 2025-09-21T00:00:00-00:00
8+
preview_image: /static/images/default-og.jpg
9+
authors:
10+
- Chukwuma Akunyili
11+
source:
12+
ignore:
13+
---
14+
15+
Building a comprehensive database testing suite for Chaufr: integration tests, transaction verification, migration rollback testing, connection pool stress tests, and performance benchmarks using Alcotest, Lwt, and Caqti
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
---
2+
title: Shipping a robust DB migration runner for Chaufr (OCaml + Caqti + Lwt)
3+
description: 'Implemented a production-minded database migration system for Chaufr:
4+
CLI, tracking, checksum validation, rollback, and safe SQL execution.'
5+
url: https://fearful-odds.rocks/blog/db-migration-runner-for-chaufr
6+
date: 2025-09-14T00:00:00-00:00
7+
preview_image: /static/images/default-og.jpg
8+
authors:
9+
- Chukwuma Akunyili
10+
source:
11+
ignore:
12+
---
13+
14+
Implemented a production-minded database migration system for Chaufr: CLI, tracking, checksum validation, rollback, and safe SQL execution.
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
---
2+
title: OCaml Weekly News, 16 Sep 2025
3+
description:
4+
url: https://alan.petitepomme.net/cwn/2025.09.16.html
5+
date: 2025-09-16T12: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.09.16.html#1">Dune dev meeting</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#2">Dune 3.20</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#3">OCaml compiler office hours? (preparation thread)</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#4">Second beta release of OCaml 5.4.0</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#5">Unicode 17.0.0 update for Uucd, Uucp, Uunf and Uuseg</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#6">Scope Image File Viewer</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#7">OCaml security team</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#8">Testo 0.2.0 - test library with support for snapshots, parallel runs, xfails, timeouts</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#9">tinyfiledialogs bindings</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#10">RFC: ~for...in~ construct</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#11">dead_code_analyzer 1.0.0</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#12">Relocatable OCaml</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#13">FUN OCaml is live on YouTube and Twitch</a></li><li><a href="https://alan.petitepomme.net/cwn/2025.09.16.html#14">Other OCaml News</a></li></ol>
Lines changed: 209 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,209 @@
1+
---
2+
title: A first foray into agentic coding
3+
description: "I\u2019ve been largely steering clear of the AI bandwagon up to now,
4+
mainly because the last thing I needed while working on Relocatable OCaml was to
5+
be trying to learn a new tool at the same time as finishing something which felt
6+
desperately late and which, at times, I myself didn\u2019t fully understand! However,
7+
as the buzz of the announcement dies down, I had a first go at pointing Claude Code
8+
to the OCaml compiler codebase, and thought I\u2019d add to the general noise of
9+
AI memoirs\u2026"
10+
url: https://www.dra27.uk/blog/platform/2025/09/17/late-to-the-party.html
11+
date: 2025-09-17T00:00:00-00:00
12+
preview_image:
13+
authors:
14+
- ""
15+
source:
16+
ignore:
17+
---
18+
19+
<p>I’ve been largely steering clear of the AI bandwagon up to now, mainly because
20+
the last thing I needed while working on <a href="https://www.dra27.uk/(/blog/platform/2025/09/15/relocatable-ocaml.html)">Relocatable OCaml</a>
21+
was to be trying to learn a new tool at the same time as finishing something
22+
which felt desperately late and which, at times, I myself didn’t fully
23+
understand! However, as the buzz of <a href="https://discuss.ocaml.org/t/relocatable-ocaml/17253">the announcement</a>
24+
dies down, I had a first go at pointing <a href="https://claude.ai/">Claude Code</a> to the
25+
OCaml compiler codebase, and thought I’d add to the general noise of AI
26+
memoirs…</p>
27+
28+
<p>These are just my observations at this “day 1” stage, so there’ll be
29+
inadequacies in the way I’m doing things, and so forth. The result can be seen <a href="https://github.com/dra27/ocaml/compare/535463082ea48f71fac945bdc242ab0774a6f18b...dra27:ocaml:f364eade826314b1b066597e6e126f12e9f8b29a?expand=1">on my OCaml fork</a>.</p>
30+
31+
<p>The task I had a play with is related to an interest I have in ultimately being
32+
able to use OCaml as a scripting language within OCaml programs themselves. Many
33+
of the things I do <em>to</em> OCaml often end up being curiously related or having
34+
seemingly unrelated tasks, and one of the things implied by this goal is
35+
unifying the bytecode and native runtime libraries (<code class="language-plaintext highlighter-rouge">libcamlrun</code> and
36+
<code class="language-plaintext highlighter-rouge">libasmrun</code>). At the moment, these are separately compiled, with some files
37+
which are just for the bytecode runtime or just for the native runtime, most
38+
files which are shared between the two, and some files which are peppered with
39+
<code class="language-plaintext highlighter-rouge">#ifdef NATIVE_CODE</code>-style sections for the bits which are slightly different
40+
between the two implementations.</p>
41+
42+
<p>I’m pleased to say that in my few hours of playing with this, I managed not to
43+
edit any files, so every change in each commit is physically Claude’s.</p>
44+
45+
<p>As a warm-up, I got Claude to produce a very simple plugin demo (the fourth
46+
commit). I was particularly impressed at Claude’s understanding how to use a
47+
compiler build in-tree, without having to install it. Although it slipped up
48+
occasionally on where directories were relatively, it was inferring quite
49+
readily the need for <code class="language-plaintext highlighter-rouge">-I ../stdlib</code> (because the compiler isn’t installed) and
50+
so forth and although it didn’t grasp the need to pass bytecode programs
51+
directly to the interpreter (you have, for example, to run
52+
<code class="language-plaintext highlighter-rouge">../runtime/ocamlrun ../ocamlc</code> rather than <code class="language-plaintext highlighter-rouge">../ocamlc</code>), there was an
53+
impressive lack of going-in-circles when I suggested alternate commands
54+
(incidentally, the <code class="language-plaintext highlighter-rouge">Makefile</code> is hideous because I requested it to be a
55+
complete expansion without variables and extraneous rubbish, not because it was
56+
offered by default!).</p>
57+
58+
<p>So far, so interesting, but what about actually working on the compiler itself?
59+
Interesting side-line with this - there’s a reasonable amount of scepticism
60+
about LLM-based contributions in OCaml core development at the moment. This
61+
branch isn’t ever heading upstream, but if it were to be opened as a PR, I need
62+
to sign off on literally every edit that’s been made as being owned by
63+
me - which means I wasn’t expecting ever to leave Claude in “auto mode”. More on
64+
that later.</p>
65+
66+
<p>We started exploring a few of the source files which differ between bytecode and
67+
native code. <em>I</em> suggested the first two commits while examining
68+
<code class="language-plaintext highlighter-rouge">backtrace_byt.c</code>, <code class="language-plaintext highlighter-rouge">backtrace_nat.c</code> and <code class="language-plaintext highlighter-rouge">backtrace.c</code>, but Claude readily did
69+
the work. I changed my mind about what I wanted to look at at that point and
70+
decided to explore something different, so looked at a file which is shared, but
71+
which has different implementations of the bytecode and native code versions of
72+
the same functions - <code class="language-plaintext highlighter-rouge">callback.c</code>. The functions here are what are used from C
73+
code to be able to call back into the OCaml runtime. That’s an very interesting
74+
thing to look at when unifying the code, because it’s an entry-point from user
75+
code into OCaml - i.e. the functions themselves will need to know whether
76+
they’re operating on bytecode or native code.</p>
77+
78+
<p>We did it in two stages: the first part was to tweak the representation of
79+
closures in the runtime to allow the closures to describe if they are bytecode
80+
or native code. Claude unquestionably shone at this stage. I’m aware at a
81+
high-level of <a href="https://github.com/ocaml/ocaml/pull/9619">ocaml/ocaml#9619</a> (I
82+
remember very well the meeting where it was discussed, because it’s also the
83+
meeting where I first aired the idea for Relocatable OCaml!), but I certainly
84+
didn’t have it at the front of my mind. Claude was able in a very short amount
85+
of time both to remind me how the closure representation works (with reference
86+
to the runtime code) and furthermore produced an explanation which - for me,
87+
knowing how it works - was convincing that a bit could be stolen from the
88+
environment offset in the descriptor to be able to record whether a closure is
89+
actually bytecode (pass the first field to <code class="language-plaintext highlighter-rouge">caml_bytecode_interpreter</code>) or is
90+
native code (execute it directly, via one of the assembly callback stubs).</p>
91+
92+
<p>Getting the runtime updated and building was quite painless. There were two
93+
interesting bits after that: the build failed quite a way in with segfaults
94+
coming from the compiler. While I was impressed that Claude had inferred how
95+
our bytecode bootstrap procedure works (perhaps it was trained on one of our
96+
compiler courses!), that was a “yeah, but no” moment - bytecode closures are
97+
always constructed at runtime, so how could <code class="language-plaintext highlighter-rouge">boot/ocamlc</code> be involved (“You’re
98+
so right!”). The next suggestion was to attempt to start gdb. At that point, we
99+
used the human brain instead of the LLM - I ran the build myself and could see
100+
the command that what was actually segfaulting was not <code class="language-plaintext highlighter-rouge">ocamlc</code> but
101+
<strong><code class="language-plaintext highlighter-rouge">ocamlc.opt</code></strong>, and for me there was an instant crashing-sound of a penny on
102+
the floor. Claude had dutifully updated the runtime for this new closure
103+
representation, and bytecode was therefore fine - but the native code compiler
104+
<em>does</em> emit closures at compile-time and needed updating.</p>
105+
106+
<p>This part I must say was terribly impressive. I merely had to prompt that the
107+
native compiler hadn’t been updated and Claude had leapt to
108+
<code class="language-plaintext highlighter-rouge">asmcomp/cmm_helpers.ml</code> before I’d had a chance to remember the filename. The
109+
build then worked and we moved on to running the testsuite.</p>
110+
111+
<p>Only one failure - again, Claude was very ready to start going into gdb and to
112+
use all sorts of other sledgehammers, but it was clear to the human brain that
113+
this was just a reference file which needed updating.</p>
114+
115+
<p>Quite impressive - we committed the work so far. Less impressive was Claude’s
116+
ability to craft two commits from the working directory. I confess I got bored
117+
trying to persuade it to unstage a single hunk.</p>
118+
119+
<p>Having updated the representation, we then tackled the much bigger job of
120+
merging the functions. I was unimpressed by Claude’s suggestions about how it
121+
might structure the changes, but it was very impressive at inferring the
122+
connection between the stated target and my suggestions about what to do
123+
instead.</p>
124+
125+
<p>The refactor here has a small subtlety: beforehand, the files are being compiled
126+
with one version where <code class="language-plaintext highlighter-rouge">NATIVE_CODE</code> is <code class="language-plaintext highlighter-rouge">#define</code>‘d, and another where it’s not.
127+
Although the ultimate aim is to have just one function, it doesn’t actually
128+
reduce it to just one version of the code. We still have two: one of them is the
129+
version of OCaml where both bytecode and native are available, but there is
130+
another where there is no native code version at all. Claude readily inferred
131+
why I wanted <code class="language-plaintext highlighter-rouge">BYTECODE_ONLY</code> to be introduced for this second case (and, if you
132+
look at the <code class="language-plaintext highlighter-rouge">bytecode_callbackN_exn</code> and similar declarations which are
133+
<code class="language-plaintext highlighter-rouge">#ifdef</code>‘d with this, you can see the idea), but when further problems happened
134+
in the build, it too readily wanted to reach back for <code class="language-plaintext highlighter-rouge">#ifdef NATIVE_CODE</code>. This
135+
kind of refactoring I describe as “infectious” - there’s a relatively small
136+
first change in one file, but then further non-trivial changes have to be made
137+
to propagate <em>the semantics</em> of that update. There were four changes needed to
138+
make this one work:</p>
139+
140+
<ol>
141+
<li>Some bytecode-only shim versions of some native code functions are needed,
142+
in order to be able to link the native code support object (<code class="language-plaintext highlighter-rouge">amd64.S</code> et al)
143+
in the bytecode runtime.</li>
144+
<li>The fiber stack C declarations need to be unified between bytecode and
145+
native code, as they use different pointer types.</li>
146+
<li>Some native-only functions, while not needed in the bytecode runtime, need to
147+
be available just so that other code links. This is to support the code path
148+
of invoking a native code closure on the bytecode runtime. It’s not going to
149+
happen (yet), but the code still needs to compile.</li>
150+
<li>Some native-code shim versions of some bytecode functions are needed for the
151+
dual reason of 1! Noteworthy because…</li>
152+
</ol>
153+
154+
<p>Claude inferred none of these steps, always preferring to go back to
155+
<code class="language-plaintext highlighter-rouge">NATIVE_ONLY</code>. <em>But</em> it was very good at executing the changes when I suggested
156+
them, and inferring how they were alternate solutions to the problem.</p>
157+
158+
<p>We got through those changes fairly painlessly and, at this point, the
159+
distribution built. Claude seems desperately keen to ignore the testsuite and
160+
write test programs of its own, but I worried that its fingers would wear out
161+
and dogmatically kept saying, “no, run the testsuite”. A lot of failures. Again,
162+
not the greatest insights from it straight-away. At this stage, the human brain
163+
was doing some staring at the code (maybe in the future I’d more readily let it
164+
sit there crunching tokens). It turns out both the human brain and the LLM had
165+
made a silly mistake with the header change and forgotten about pointer
166+
arithmetic. <em>Nil point</em> to Claude for the lack of inference originally - but I
167+
was certainly impressed that the prompt “The failing tests are all in bytecode.
168+
I’m wondering if you made a mistake with the change to the header” which
169+
<em>immediately</em> caused the LLM to identify that the switch from <code class="language-plaintext highlighter-rouge">value *</code> to
170+
<code class="language-plaintext highlighter-rouge">void *</code> had totally omitted the need for more pointer casts (this is a large
171+
part of what I don’t like about the change at the moment, but it’s a WIP… I
172+
often find when hacking these ideas that it’s necessary to go through some very
173+
ugly intermediate C states!).</p>
174+
175+
<p>After a fair bit of “think very hard”, all casts were updated and the entire
176+
testsuite passed. As soon as that happened, Claude wanted to re-test the tree
177+
with a bytecode-only build (to verify that the new <code class="language-plaintext highlighter-rouge">BYTECODE_ONLY</code> version was
178+
working correctly too). And at that point we committed this little foray.</p>
179+
180+
<p>Impressions, perhaps to revisit in a few months:</p>
181+
<ul>
182+
<li>Claude was excellent at getting the first version up and putting the outline
183+
plan for the change together. It was certainly slower (than me) at editing the
184+
files having done it. That, in fairness, fits with my experience of pair
185+
programming, and perhaps reflects more on me than Claude.</li>
186+
<li>The first ideas Claude wanted to make for how to proceed were almost always
187+
dreadful, and given the complexity of the code, I’m not sure I’d ever want to
188+
leave it doing large amounts of work on its own. That probably says a lot
189+
about my “prompt engineering”.</li>
190+
<li>In these few hours of “vibing”, I poked at builds, viewed source files on my
191+
own in order to agree, but didn’t edit anything directly myself. Will
192+
certainly be interesting to see what happens if Claude’s doing less of the
193+
editing, but watching and doing more of the analysis.</li>
194+
<li>Given the need to sign off personally on every change made, while the task
195+
felt like it took longer, it should be tempered with the fact I would feel
196+
less need to review the change afterwards (although the final commit is still
197+
not at a state which would be submitted in a PR).</li>
198+
<li>It’s possible that left to its own devices, Claude would have arrived at a
199+
working version of this small step without intervention. However, based on
200+
its attempt to describe a high-level plan of an earlier bigger idea, I dread
201+
to think what the code would have looked like!</li>
202+
<li>Its response to error messages and the speed with which it gets to a
203+
resolution definitely makes the process “feel” faster, even though it was
204+
actually slower than doing it myself (a social media, echo-chambery feeling)</li>
205+
</ul>
206+
207+
<p><em>The commits referenced on my GitHub fork of OCaml in this post are included for
208+
information and illustration only, and are not intended to be upstreamed to
209+
OCaml.</em></p>

0 commit comments

Comments
 (0)