Attn: Development Editor, Latest OCaml Weekly News

Alan Schmitt <[email protected]> Tue, 28 Apr 2026 09:59:30 +0200
Newsgroups gmane.comp.lang.caml.inria
Message-ID <[email protected]>
--===-=-=
Content-Type: multipart/mixed; boundary="=-=-="

--=-=-=
Content-Type: multipart/alternative; boundary="==-=-="

--==-=-=
Content-Type: text/plain; charset=utf-8
Content-Transfer-Encoding: base64

SGVsbG8NCg0KSGVyZSBpcyB0aGUgbGF0ZXN0IE9DYW1sIFdlZWtseSBOZXdzLCBmb3IgdGhlIHdl
ZWsgb2YgQXByaWwgMjEgdG8gMjgsDQoyMDI2Lg0KDQpUYWJsZSBvZiBDb250ZW50cw0K4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCkNsb3Npbmcg
T2xkIEJ1Z3MgV2l0aCBUZXN0czogQSBEdW5lIENvbnRyaWJ1dGlvbiBTdG9yeQ0Kb2NhbWwtd2ly
ZTogYSBCaW5hcnkgd2lyZSBmb3JtYXQgRFNMIHdpdGggRXZlclBhcnNlIDNEIG91dHB1dA0KdmFs
a2V5OiBtb2Rlcm4gVmFsa2V5IGNsaWVudCBmb3IgT0NhbWwgNSArIEVpbywgb24gb3BhbQ0KVW5p
ZmllZFNjcmlwdF97U3RkLFRvcH0gLSBsaXRlcmF0ZSB0ZXN0aW5nDQpvcGVucm91dGVyX2FwaTog
QW4gT3BlblJvdXRlciBjbGllbnQgbGlicmFyeQ0KQ2FsbCBmb3IgcHJlc2VudGF0aW9uczogQ2Ft
bCBpbiB0aGUgQ2FwaXRhbCBJSQ0KT2xkIENXTg0KDQoNCkNsb3NpbmcgT2xkIEJ1Z3MgV2l0aCBU
ZXN0czogQSBEdW5lIENvbnRyaWJ1dGlvbiBTdG9yeQ0K4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2ZToNCiAgPGh0dHBzOi8vZGlzY3Vz
cy5vY2FtbC5vcmcvdC9jbG9zaW5nLW9sZC1idWdzLXdpdGgtdGVzdHMtYS1kdW5lLWNvbnRyaWJ1
dGlvbi1zdG9yeS8xODAwOC8xPg0KDQoNClJvYmluIEJhdGUgQm9lcm9wIGFubm91bmNlZA0K4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgSSByZWNlbnRseSBzdGFydGVkIGNvbnRyaWJ1dGlu
ZyB0byBEdW5lIHdpdGggbm8gcHJpb3IgZmFtaWxpYXJpdHkgd2l0aA0KICB0aGUgY29kZSBiYXNl
LiBPbmUgdGhpbmcgSSBmb3VuZCByZXdhcmRpbmcgd2FzIGNsb3Npbmcgb2xkIGlzc3VlcyDigJQN
CiAgc29tZSBmaWxlZCBhcyBmYXIgYmFjayBhcyAyMDE4IOKAlCBhbmQgSSB3YW50ZWQgdG8gc2hh
cmUgdGhlIGFwcHJvYWNoIEkNCiAgdXNlZC4NCg0KDQpUaGUgTWV0aG9kOiBDbG9zZSBXaXRoIGEg
VGVzdA0K4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM
4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWM4pWMDQoNCiAgTWFueSBvcGVuIGlzc3Vl
cyBkZXNjcmliZSBiZWhhdmlvdXIgdGhhdCBoYXMgYWxyZWFkeSBiZWVuIGZpeGVkLCBvcg0KICBi
ZWhhdmlvdXIgdGhhdCBpcyB3b3JraW5nIGNvcnJlY3RseSBidXQgd2FzIG5ldmVyIHZlcmlmaWVk
IHdpdGggYQ0KICB0ZXN0LiBNeSBhcHByb2FjaDogd3JpdGUgYSBjcmFtIHRlc3QgdGhhdCBkZW1v
bnN0cmF0ZXMgdGhlIGV4cGVjdGVkDQogIGJlaGF2aW91ciwgbGluayB0aGUgUFIgdG8gdGhlIGlz
c3VlIHdpdGggYGZpeGVzICNOTk5OJywgYW5kIGxldCB0aGUNCiAgbWVyZ2UgY2xvc2UgdGhlIGlz
c3VlIGF1dG9tYXRpY2FsbHkuDQoNCiAgVGhpcyBoYXMgc2V2ZXJhbCBhZHZhbnRhZ2VzIG92ZXIg
c2ltcGx5IGNsb3NpbmcgYW4gaXNzdWUgd2l0aCBhDQogIGNvbW1lbnQgbGlrZSAidGhpcyB3b3Jr
cyBub3ciOg0KDQogIOKAoiAqSXQncyB2ZXJpZmlhYmxlLiogQW55b25lIGNhbiByZWFkIHRoZSB0
ZXN0IGFuZCBzZWUgZXhhY3RseSB3aGF0DQogICAgIGJlaGF2aW91ciBpcyBiZWluZyBhc3NlcnRl
ZC4gVGhlcmUncyBubyBhcmd1bWVudCBhYm91dCB3aGV0aGVyIHRoZQ0KICAgICBpc3N1ZSBpcyB0
cnVseSByZXNvbHZlZC4NCiAg4oCiICpJdCBwcmV2ZW50cyByZWdyZXNzaW9ucy4qIElmIHRoZSBi
ZWhhdmlvdXIgYnJlYWtzIGFnYWluIGluIHRoZQ0KICAgICBmdXR1cmUsIHRoZSB0ZXN0IGZhaWxz
LiBUaGUgaXNzdWUgZG9lc24ndCBzaWxlbnRseSByZW9wZW4g4oCUIHRoZSBDSQ0KICAgICBjYXRj
aGVzIGl0Lg0KICDigKIgKkl0IGdyb3dzIHRoZSB0ZXN0IHN1aXRlLiogRXZlcnkgY2xvc2VkIGlz
c3VlIGxlYXZlcyBiZWhpbmQgYSB0ZXN0DQogICAgIHRoYXQgZG9jdW1lbnRzIGEgcmVhbC13b3Js
ZCBzY2VuYXJpbyBzb21lb25lIGNhcmVkIGFib3V0Lg0KICDigKIgKkl0IHJlc3BlY3RzIHRoZSBy
ZXBvcnRlci4qIFNvbWVvbmUgdG9vayB0aGUgdGltZSB0byBmaWxlIHRoZQ0KICAgICBpc3N1ZS4g
QSB0ZXN0IHRoYXQgY2FwdHVyZXMgdGhlaXIgY29uY2VybiBpcyBhIGJldHRlcg0KICAgICBhY2tu
b3dsZWRnZW1lbnQgdGhhbiBhIGRyaXZlLWJ5IGNsb3NlLg0KDQogIEFmdGVyIGEgZmV3IHdlZWtz
IG9mIGNvbnRyaWJ1dGluZyB0ZXN0IFBScyBhbmQgYnVnIGZpeGVzLCBJIHdhcyBnaXZlbg0KICB0
cmlhZ2VyIGFuZCB0aGVuIG1haW50YWluZXIgc3RhdHVzIG9uIHRoZSBwcm9qZWN0LiBUaGlzIGxl
dCBtZSBjbG9zZQ0KICBpc3N1ZXMgZGlyZWN0bHkgd2hlbiB0aGV5IHdlcmUgY2xlYXJseSByZXNv
bHZlZCwgYW5kIG1lcmdlIG15IG93biB0ZXN0DQogIFBScy4gQmVmb3JlIHRoYXQsIHRoZSBleGlz
dGluZyBtYWludGFpbmVycyBtZXJnZWQgdGhlbSBvbiBteSBiZWhhbGYuDQoNCiAgSG9uZXN0bHks
IEkgcmVncmV0IGNsb3NpbmcgaXNzdWVzIHdoZXJlIEkgY291bGQgaGF2ZSB1c2VkIHRoaXMgbWV0
aG9kDQogIGJ1dCBkaWRuJ3QuIFRoZSBtZXRob2QgaXMgbXVjaCBzdXBlcmlvciB0byBzaW1wbHkg
YWRkaW5nIHRvIGEgR2l0SHViDQogIGRpc2N1c3Npb24gYWJvdXQgdGhlIGJ1ZyBhbmQgdGhlbiBj
bG9zaW5nIHRoZSBpc3N1ZS4NCg0KDQpJc3N1ZXMgSSBIZWxwZWQgQ2xvc2UNCuKVjOKVjOKVjOKV
jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjA0KDQog
IEhlcmUncyBhbiBhY2NvdW50aW5nIG9mIHdoYXQgSSBoZWxwZWQgY2xvc2UsIGdyb3VwZWQgYnkg
d2hhdCBpdCB0b29rOg0KDQoNCuKXiiBDb25maXJtZWQgcmVzb2x2ZWQ7IGNsb3NlZCBkaXJlY3Rs
eQ0KDQogIFRoZXNlIGlzc3VlcyBkZXNjcmliZWQgcHJvYmxlbXMgdGhhdCBubyBsb25nZXIgZXhp
c3RlZCBvbiBtYWluLiBJbg0KICBzb21lIGNhc2VzIEkgY29uZmlybWVkIHRoaXMgbXlzZWxmLCBp
biBvdGhlcnMgc29tZW9uZSBlbHNlIGhhZCBhbHJlYWR5DQogIHZlcmlmaWVkIGl0LiBBcyBhIHRy
aWFnZXIvbWFpbnRhaW5lciBJIHdhcyBhYmxlIHRvIGNsb3NlIHRoZW06DQoNCiAg4oCiIFsjMTk3
NF0g4oCUIGBAYWxsJyB0YXJnZXQgZG9lc24ndCBpbnRlcmFjdCB3ZWxsIHdpdGggYChpbmNsdWRl
X3N1YmRpcnMNCiAgICAuLi4pJyAoZmlsZWQgMjAxOSkNCiAg4oCiIFsjMzE3M10g4oCUIENhbid0
IHByb21vdGUgaW50byBhIGRpcmVjdG9yeSBzdGFydGluZyB3aXRoIHVuZGVyc2NvcmUNCiAgICAo
ZmlsZWQgMjAyMCkNCiAg4oCiIFsjMzgwNV0g4oCUIE5vIHN1Y2ggZmlsZSBvciBkaXJlY3Rvcnkg
d2hlbiBgRFVORV9CVUlMRF9ESVInIGlzIHNldA0KICAgIGR1cmluZyB0ZXN0IChmaWxlZCAyMDIw
KQ0KICDigKIgWyM4MjQyXSDigJQgVmVyeSBzbG93IGVtYWNzIGNvbXBpbGF0aW9uIGJ1ZmZlciB1
cGRhdGVzIChmaWxlZCAyMDIzKQ0KICDigKIgWyMxMDM2MF0g4oCUIGBleGVjdXRhYmxlc19pbXBs
aWNpdF9lbXB0eV9pbnRmJyBleHBlY3RzIGR1bmUgPj0gMi45IGJ1dA0KICAgIHdhcyBvbmx5IGFk
ZGVkIGluIDMuMCAoZmlsZWQgMjAyNCkNCg0KDQogIFsjMTk3NF0gPGh0dHBzOi8vZ2l0aHViLmNv
bS9vY2FtbC9kdW5lL2lzc3Vlcy8xOTc0Pg0KDQogIFsjMzE3M10gPGh0dHBzOi8vZ2l0aHViLmNv
bS9vY2FtbC9kdW5lL2lzc3Vlcy8zMTczPg0KDQogIFsjMzgwNV0gPGh0dHBzOi8vZ2l0aHViLmNv
bS9vY2FtbC9kdW5lL2lzc3Vlcy8zODA1Pg0KDQogIFsjODI0Ml0gPGh0dHBzOi8vZ2l0aHViLmNv
bS9vY2FtbC9kdW5lL2lzc3Vlcy84MjQyPg0KDQogIFsjMTAzNjBdIDxodHRwczovL2dpdGh1Yi5j
b20vb2NhbWwvZHVuZS9pc3N1ZXMvMTAzNjA+DQoNCg0K4peKIENsb3NlZCB3aXRoIGEgdGVzdCBQ
Ug0KDQogIFRoZXNlIGlzc3VlcyB3ZXJlIHJlc29sdmVkIGJ5IHdyaXRpbmcgYSB0ZXN0IHRoYXQg
ZGVtb25zdHJhdGVzIHRoZQ0KICBjb3JyZWN0IGJlaGF2aW91ci4gTm8gY29kZSBjaGFuZ2VzIHdl
cmUgbmVlZGVkIOKAlCB0aGUgdGVzdCBpdHNlbGYNCiAgY2xvc2VkIHRoZSBpc3N1ZToNCg0KICDi
gKIgWyMyMzcwXSDigJQgYC5oJyBmaWxlcyBjb3BpZWQgdG8gYF9idWlsZCcgd2l0aG91dCBmb3Jl
aWduIHN0dWJzIChmaWxlZA0KICAgIDIwMTksIHRlc3Q6IFsjMTQxNzJdKQ0KICDigKIgWyMzMzYy
XSDigJQgQ2Fubm90IHVzZSBgJXtsaWI6Li4ufScgaW4gdGhlIGBmbGFncycgc3RhbnphIChmaWxl
ZCAyMDIwLA0KICAgIHRlc3Q6IFsjMTQxNDZdKQ0KICDigKIgWyMzNDg0XSDigJQgUHJvbW90aW5n
IG92ZXIgYSBydW5uaW5nIGJpbmFyeSAoZmlsZWQgMjAyMCwgdGVzdDoNCiAgICBbIzE0MTczXSkN
CiAg4oCiIFsjMTExMTBdIOKAlCBMaWJleGVjIHNpdGUgaW5zdGFsbCBkb2Vzbid0IHNldCBleGVj
dXRhYmxlIGJpdCAoZmlsZWQNCiAgICAyMDI0LCB0ZXN0OiBbIzE0MTcxXSkNCg0KDQogIFsjMjM3
MF0gPGh0dHBzOi8vZ2l0aHViLmNvbS9vY2FtbC9kdW5lL2lzc3Vlcy8yMzcwPg0KDQogIFsjMTQx
NzJdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9wdWxsLzE0MTcyPg0KDQogIFsjMzM2
Ml0gPGh0dHBzOi8vZ2l0aHViLmNvbS9vY2FtbC9kdW5lL2lzc3Vlcy8zMzYyPg0KDQogIFsjMTQx
NDZdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9wdWxsLzE0MTQ2Pg0KDQogIFsjMzQ4
NF0gPGh0dHBzOi8vZ2l0aHViLmNvbS9vY2FtbC9kdW5lL2lzc3Vlcy8zNDg0Pg0KDQogIFsjMTQx
NzNdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9wdWxsLzE0MTczPg0KDQogIFsjMTEx
MTBdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9pc3N1ZXMvMTExMTA+DQoNCiAgWyMx
NDE3MV0gPGh0dHBzOi8vZ2l0aHViLmNvbS9vY2FtbC9kdW5lL3B1bGwvMTQxNzE+DQoNCg0K4peK
IENsb3NlZCB3aXRoIGEgdGVzdCBhbmQgYSBjb2RlIGZpeA0KDQogIFRoZXNlIHJlcXVpcmVkIGJv
dGggYSB0ZXN0IGFuZCBhIGNvZGUgY2hhbmdlIHRvIHJlc29sdmU6DQoNCiAg4oCiIFsjODc4XSDi
gJQgYGR1bmUgc3Vic3QnIGFkZHMgZHVwbGljYXRlIHZlcnNpb24gZmllbGQgaW4gb3BhbSAoZmls
ZWQNCiAgICAyMDE4LCBmaXg6IFsjMTQxMzZdKQ0KICDigKIgWyMyNDQ1XSDigJQgZHVuZSBzZW5k
cyBTSUdLSUxMIHdpdGhvdXQgcHJpb3IgU0lHVEVSTSAoZmlsZWQgMjAxOSwNCiAgICBmaXhlczog
WyMxNDE3MF0sIFsjMTQyMjRdKQ0KICDigKIgWyMzOTE2XSDigJQgRHVwbGljYXRlIGJvdW5kcyBp
biBhdXRvZ2VuZXJhdGVkIG9wYW0gZmlsZXMgKGZpbGVkIDIwMjAsDQogICAgZml4OiBbIzE0MTc1
XSkNCiAg4oCiIFsjNjE0OF0g4oCUIGByb290X21vZHVsZScgZ2VuZXJhdGVzIGR1cGxpY2F0ZSBt
b2R1bGUgZGVmaW5pdGlvbiAoZmlsZWQNCiAgICAyMDIyLCBmaXg6IFsjMTQxMzVdKQ0KICDigKIg
WyM5NzU3XSDigJQgYGR1bmUgcnVudGVzdCcgZG9lc24ndCBleGVjdXRlIGJ5dGUtb25seSBpbmxp
bmUgdGVzdHMNCiAgICAoZmlsZWQgMjAyNCwgZml4OiBbIzE0MTc0XSkNCiAg4oCiIFsjMTA3MDdd
IOKAlCBNaXNzaW5nIG1lbmhpciBsb3dlciBib3VuZCBpbiBnZW5lcmF0ZWQgb3BhbSBmaWxlcyAo
ZmlsZWQNCiAgICAyMDI0LCBmaXg6IFsjMTQxNjhdKQ0KICDigKIgWyMxMTAwMl0g4oCUIG9wYW0g
ZmlsZSBnZW5lcmF0aW9uIGVycm9yLXByb25lIChmaWxlZCAyMDI0LCBmaXg6DQogICAgWyMxNDEz
Nl0pDQogIOKAoiBbIzExMTA2XSDigJQgUmVkdW5kYW50IGR1bmUgdmVyc2lvbiBjb25zdHJhaW50
IGluIG9wYW0gZmlsZXMgKGZpbGVkDQogICAgMjAyNCwgZml4OiBbIzE0MTc1XSkNCiAg4oCiIFsj
MTIwMDddIOKAlCBgZHVuZSBidWlsZCBAb2NhbWwtaW5kZXgnIGJ1aWxkcyB0b28gbWFueSBmaWxl
cyAoZmlsZWQNCiAgICAyMDI1LCBwYXJ0aWFsbHkgZml4ZWQgd2l0aCBbIzE0MTM3XSkNCiAg4oCi
IFsjMTQwODldIOKAlCBJbmNyZW1lbnRhbCBidWlsZHMgd2l0aCBgKHdyYXBwZWQgKHRyYW5zaXRp
b24gLi4uKSknDQogICAgYnJva2VuIChmaWxlZCAyMDI2LCB0ZXN0OiBbIzE0MDg4XSwgZml4OiBb
IzE0MDkwXSkNCg0KDQogIFsjODc4XSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL2R1bmUvaXNz
dWVzLzg3OD4NCg0KICBbIzE0MTM2XSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL2R1bmUvcHVs
bC8xNDEzNj4NCg0KICBbIzI0NDVdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9pc3N1
ZXMvMjQ0NT4NCg0KICBbIzE0MTcwXSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL2R1bmUvcHVs
bC8xNDE3MD4NCg0KICBbIzE0MjI0XSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL2R1bmUvcHVs
bC8xNDIyND4NCg0KICBbIzM5MTZdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9pc3N1
ZXMvMzkxNj4NCg0KICBbIzE0MTc1XSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL2R1bmUvcHVs
bC8xNDE3NT4NCg0KICBbIzYxNDhdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9pc3N1
ZXMvNjE0OD4NCg0KICBbIzE0MTM1XSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL2R1bmUvcHVs
bC8xNDEzNT4NCg0KICBbIzk3NTddIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9pc3N1
ZXMvOTc1Nz4NCg0KICBbIzE0MTc0XSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL2R1bmUvcHVs
bC8xNDE3ND4NCg0KICBbIzEwNzA3XSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL2R1bmUvaXNz
dWVzLzEwNzA3Pg0KDQogIFsjMTQxNjhdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9w
dWxsLzE0MTY4Pg0KDQogIFsjMTEwMDJdIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwvZHVuZS9p
c3N1ZXMvMTEwMDI+DQoNCiAgWyMxMTEwNl0gPGh0dHBzOi8vZ2l0aHViLmNvbS9vY2FtbC9kdW5l
L2lzc3Vlcy8xMTEwNj4NCg0KICBbIzEyMDA3XSA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL2R1
bmUvaXNzdWVzLzEyMDA3Pg0KDQogIFsjMTQxMzddIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwv
ZHVuZS9wdWxsLzE0MTM3Pg0KDQogIFsjMTQwODldIDxodHRwczovL2dpdGh1Yi5jb20vb2NhbWwv
ZHVuZS9pc3N1ZXMvMTQwODk+DQoNCiAgWyMxNDA4OF0gPGh0dHBzOi8vZ2l0aHViLmNvbS9vY2Ft
bC9kdW5lL3B1bGwvMTQwODg+DQoNCiAgWyMxNDA5MF0gPGh0dHBzOi8vZ2l0aHViLmNvbS9vY2Ft
bC9kdW5lL3B1bGwvMTQwOTA+DQoNCg0KV2hhdCBJIExlYXJuZWQNCuKVjOKVjOKVjOKVjOKVjOKV
jOKVjOKVjOKVjOKVjOKVjOKVjOKVjOKVjA0KDQogICpXcml0aW5nIHRlc3RzIGlzIGEgZ29vZCB3
YXkgdG8gbGVhcm4gYWJvdXQgYSBjb2RlIGJhc2UuKiBFYWNoIHRlc3QNCiAgIGZvcmNlZCBtZSB0
byB1bmRlcnN0YW5kIGhvdyBhIGZlYXR1cmUgYWN0dWFsbHkgd29ya3Mg4oCUIG5vdCB0aGUNCiAg
IGFyY2hpdGVjdHVyZSBpbiB0aGUgYWJzdHJhY3QsIGJ1dCB0aGUgY29uY3JldGUgYmVoYXZpb3Vy
IGluIHNwZWNpZmljDQogICBzY2VuYXJpb3MuIFRoZSB1bmRlcnN0YW5kaW5nIGNvbXBvdW5kZWQu
DQoNCiAgKkR1bmUncyBjcmFtIHRlc3RzIG1ha2UgdGhpcyBlYXN5LiogRWFjaCB0ZXN0IGlzIGEg
c2VsZi1jb250YWluZWQNCiAgIHNoZWxsIHNjcmlwdCB3aXRoIGV4cGVjdGVkIG91dHB1dCwgY2hl
Y2tlZCBpbnRvIHRoZSByZXBvIGFzIGEgYC50Jw0KICAgZmlsZS4gVGhlIGJhcnJpZXIgdG8gd3Jp
dGluZyBhIHRlc3QgaXMgbG93LCB3aGljaCBpcyBleGFjdGx5IHdoYXQgeW91DQogICB3YW50IHdo
ZW4geW91ciBnb2FsIGlzIHRvIGNsb3NlIGlzc3VlcyBieSB0ZXN0aW5nIHRoZW0uIFRoaXMNCiAg
IG9jY2FzaW9uYWxseSBiYWNrZmlyZWQgYnkgYmVpbmcgInRvbyBlYXN5IiAtIHdoZW4gSSB3cm90
ZSB0ZXN0cyB0bw0KICAgd2hpY2ggbWFpbnRhaW5lcnMgb2JqZWN0ZWQgYmVjYXVzZSBJIGhhZCBu
b3QgZG9uZSBzbyBpbiBhDQogICBEdW5lLWlkaW9tYXRpYyB3YXk7IGJ1dCB0aGlzIHdhcyBzdGls
bCBuZXQgcG9zaXRpdmUgZm9yIHN1cmUuDQoNCiAgKkNvbnNpc3RlbnQgcHJlc2VuY2UgbWF0dGVy
cy4qIEkgY29udHJpYnV0ZWQgbmVhcmx5IGV2ZXJ5IGRheSBvdmVyDQogICBzZXZlcmFsIHdlZWtz
LiBJIHRoaW5rIHRoYXQgdGhpcyBoZWxwZWQgbWFpbnRhaW5lcnMgZmVlbCB0aGF0IEkgd2FzDQog
ICAicHJlc2VudCIgLSB0aGF0IGVmZm9ydHMgdGhhdCB0aGV5IG1hZGUgdG8gaGVscCBtZSB3ZXJl
IGludmVzdG1lbnRzOw0KICAgc28gdGhleSB3ZXJlIGxlc3MgcHJvbmUgdG8gaG9sZGluZyBiYWNr
IHJldmlld3MuDQoNCg0Kb2NhbWwtd2lyZTogYSBCaW5hcnkgd2lyZSBmb3JtYXQgRFNMIHdpdGgg
RXZlclBhcnNlIDNEIG91dHB1dA0K4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ
4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2ZToNCiAgPGh0dHBz
Oi8vZGlzY3Vzcy5vY2FtbC5vcmcvdC9hbm4tb2NhbWwtd2lyZS1hLWJpbmFyeS13aXJlLWZvcm1h
dC1kc2wtd2l0aC1ldmVycGFyc2UtM2Qtb3V0cHV0LzE4MDA5LzE+DQoNCg0KVGhvbWFzIEdhemFn
bmFpcmUgYW5ub3VuY2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi
lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KICBJJ20gaGFwcHkg
dG8gYW5ub3VuY2UgdGhlIHJlbGVhc2Ugb2YgYG9jYW1sLXdpcmUgMC45LjAnIHRvIG9wYW0hDQoN
CiAgYG9jYW1sLXdpcmUnIGlzIGEgc2V0IG9mIGNvbWJpbmF0b3JzIHRvIGRlc2NyaWJlIGJpbmFy
eSBwcm90b2NvbHMgaW4NCiAgT0NhbWwuICJCaW5hcnkiIGFzIGluIGZpeGVkLWxheW91dDogc2l6
ZXMgYW5kIHNoYXBlcyBhcmUgbW9zdGx5IGtub3duDQogIHVwIGZyb250LCBzbyB5b3UncmUgcmVh
ZGluZyBmaWVsZHMgYXQga25vd24gb2Zmc2V0cyByYXRoZXIgdGhhbg0KICBwYXJzaW5nIGEgZnJl
ZS1mb3JtIGdyYW1tYXIgKGxpa2UgaW4gTWVuaGlyKS4gVGhlcmUgYXJlIGFscmVhZHkgbWFueQ0K
ICBnb29kIGJpbmFyeSBwYXJzZXIgZnJhbWV3b3JrcyBpbiBPQ2FtbCDigJMgaGVyZSdzIHdoYXQn
cyBkaWZmZXJlbnQgaW4NCiAgYG9jYW1sLXdpcmUnOg0KDQogIOKAoiBUaGUgY2VudHJhbCBkYXRh
IHN0cnVjdHVyZSBpcyBFdmVyUGFyc2UncyBbM0QgZ3JhbW1hcl0uIFRoZSBPQ2FtbA0KICAgIGNv
bWJpbmF0b3JzIGRlc2NyaWJlIGEgM0Qgc3RydWN0dXJlLiBGb2xsb3dpbmcgW0RhbmllbCdzIHRh
Z2dlZA0KICAgIGZpbmFsIGVuY29kaW5nIGFwcHJvYWNoXSwgeW91IGJ1aWxkIGEgY29kZWMgdGhh
dCBkZXNjcmliZXMgYSBzdHJ1Y3QNCiAgICBhbmQgaG93IHRvIHNlcmlhbGlzZS9kZXNlcmlhbGlz
ZSBpdCBmcm9tIGFuIE9DYW1sIHZhbHVlLg0KICDigKIgV2hpY2ggbWVhbnMgZXZlcnkgZGVzY3Jp
cHRpb24gY2FuIGNvbXBpbGUgZG93biB0byBhIC4zZCBmaWxlIGFuZA0KICAgIGZyb20gdGhlcmUg
dG8gQyB2aWEgRXZlclBhcnNlIOKAkyBhbmQgdGhlIGdlbmVyYXRlZCBDIGNvbXBpbGVzIGNsZWFu
bHkNCiAgICB3aXRoIGAtc3RkPWM5OSAtV2FsbCAtV2Vycm9yJy4gU28geW91IGNvdWxkLCBpbiB0
aGVvcnkgKEkgaGF2ZW4ndA0KICAgIHB1c2hlZCBvbiB0aGlzIHRvbyBmYXIgZm9yIG5vdyksIGJ1
aWxkIGFuZCBsaW5rIGEgY29tcGxleCBzdGFjayBhcw0KICAgIGFuIHN0YW5kYWxvbmUsIGV4dGVy
bmFsIEMgcGFyc2VyIHdob3NlIG1lbW9yeSBzYWZldHksIHNpbmdsZS1wYXNzDQogICAgYmVoYXZp
b3VyLCBhbmQgY29uZm9ybWFuY2UgdG8gdGhlIDNEIHNwZWMgYXJlIHByb3ZlbiBpbiBGKihFdmVy
UGFyc2UNCiAgICBkb2Vzbid0IGdpdmUgeW91IHNlcmlhbGlzZXJzLCB1bmZvcnR1bmF0ZWx5KS4N
CiAg4oCiIElmIHlvdSBwcmVmZXIsIHlvdSBjYW4gc3RpbGwgdXNlIHRoZSBPQ2FtbCBwYXJzZXJz
L3ZlcmlmaWVycywgd2hpY2gNCiAgICBoYXZlIGJlZW4gbWFkZSByZWFzb25hYmx5IGZhc3QgKGku
ZS4gbm8gZXh0cmEgYWxsb2NhdGlvbnMgb24gdGhlIGhvdA0KICAgIHBhdGgpLCBhbmQgYXMgdGhl
eSBhcmUgc3RyZWFtaW5nIGNvZGVjcyB5b3UgY2FuIGp1c3QgcmVhZCBvciB3cml0ZSBhDQogICAg
c2luZ2xlIGZpZWxkIG9mIHRoZSBzdHJ1Y3R1cmUgd2l0aG91dCBwYXJzaW5nIHRoZSB3aG9sZSB0
aGluZy4gVGhleQ0KICAgIGFsc28gY29tcGlsZSB0cml2aWFsbHkgdG8gSmF2YVNjcmlwdCB2aWEg
YGpzX29mX29jYW1sJywgaWYgeW91IG5lZWQNCiAgICB0byBwYXJzZSB0aGUgc2FtZSBmb3JtYXQg
aW4gdGhlIGJyb3dzZXIuDQoNCiAgQSBzbWFsbCBleGFtcGxlIOKAkyBhIHBhY2tldCB3aXRoIHR3
byBuaWJibGUtd2lkZSBmaWVsZHMsIGEgYmlnLWVuZGlhbg0KICBsZW5ndGgsIGFuZCBhIHZhcmlh
YmxlLXNpemUgcGF5bG9hZCB3aG9zZSBsZW5ndGggaXMgcmVhZCBmcm9tIHRoZQ0KICBMZW5ndGgg
ZmllbGQ6DQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBvcGVuIFdpcmUNCiAg4pSCIA0KICDi
lIIgdHlwZSBwYWNrZXQgPSB7IHZlcnNpb24gOiBpbnQ7IGZsYWdzIDogaW50OyBsZW5ndGggOiBp
bnQ7IHBheWxvYWQgOiBzdHJpbmcgfQ0KICDilIIgDQogIOKUgiBsZXQgZl92ZXJzaW9uID0gRmll
bGQudiAiVmVyc2lvbiIgKGJpdHMgfndpZHRoOjQgVTgpDQogIOKUgiBsZXQgZl9mbGFncyAgID0g
RmllbGQudiAiRmxhZ3MiICAgKGJpdHMgfndpZHRoOjQgVTgpDQogIOKUgiBsZXQgZl9sZW5ndGgg
ID0gRmllbGQudiAiTGVuZ3RoIiAgdWludDE2YmUNCiAg4pSCIGxldCBmX3BheWxvYWQgPSBGaWVs
ZC52ICJQYXlsb2FkIiAoYnl0ZV9hcnJheSB+c2l6ZTooRmllbGQucmVmIGZfbGVuZ3RoKSkNCiAg
4pSCIA0KICDilIIgbGV0IGNvZGVjID0NCiAg4pSCICAgbGV0IG9wZW4gQ29kZWMgaW4NCiAg4pSC
ICAgdiAiUGFja2V0IiAoZnVuIHZlcnNpb24gZmxhZ3MgbGVuZ3RoIHBheWxvYWQgLT4geyB2ZXJz
aW9uOyBmbGFnczsgbGVuZ3RoOyBwYXlsb2FkIH0pDQogIOKUgiAgICAgWyBmX3ZlcnNpb24gJCAo
ZnVuIHAgLT4gcC52ZXJzaW9uKTsNCiAg4pSCICAgICAgIGZfZmxhZ3MgICAkIChmdW4gcCAtPiBw
LmZsYWdzKTsNCiAg4pSCICAgICAgIGZfbGVuZ3RoICAkIChmdW4gcCAtPiBwLmxlbmd0aCk7DQog
IOKUgiAgICAgICBmX3BheWxvYWQgJCAoZnVuIHAgLT4gcC5wYXlsb2FkKSBdDQogIOKUlOKUgOKU
gOKUgOKUgA0KDQogIGBGaWVsZC5yZWYgZl9sZW5ndGgnIGlzIHRoZSBkZXBlbmRlbnQtc2l6ZSBi
aXQ6IHRoZSBwYXlsb2FkJ3MgbGVuZ3RoDQogIGNvbWVzIGZyb20gdGhlIGBmX2xlbmd0aCcgZmll
bGQgcmVhZCBlYXJsaWVyIGluIHRoZSBzYW1lIHN0cnVjdC4gVGhhdA0KICBzYW1lIGNvZGVjIHZh
bHVlIGlzIHdoYXQgeW91IGhhbmQgdG8gYEV2ZXJwYXJzZS5zY2hlbWEnIHRvIGdldCB0aGUgM0QN
CiAgZmlsZSBvdXQsIGFuZCB3aGF0IGJhY2tzIGBDb2RlYy5nZXQnIC8gYENvZGVjLnNldCcgZm9y
IHN0cmVhbWluZyBmaWVsZA0KICBhY2Nlc3MgZnJvbSBPQ2FtbC4gYG9jYW1sLXdpcmUnIGFsc28g
c2hpcHMgdGhlIGluZnJhc3RydWN0dXJlIGZvcg0KICBnZW5lcmF0aW5nIEZGSSBzdHVicyBhbmQg
Zm9yIGRpZmZlcmVudGlhbCB0ZXN0aW5nIHRvIG1ha2Ugc3VyZSB0aGUNCiAgdmVyaWZpZWQgQyBh
bmQgaGFuZC13cml0dGVuIE9DYW1sIHBhcnNlcnMgYWdyZWUuIFNvIGZhciB0aGV5IHNlZW0gdG8N
CiAgOi0pDQoNCiAgWW91IGNhbiByZWFkIG1vcmUgYWJvdXQgaXQgaGVyZToNCiAgPGh0dHBzOi8v
Z2F6YWduYWlyZS5vcmcvYmxvZy8yMDI2LTAzLTMxLW9jYW1sLXdpcmUuaHRtbD4uDQoNCiAgVG8g
dHJ5IGl0OiBgb3BhbSBpbnN0YWxsIHdpcmUnDQoNCiAgRmVlZGJhY2sgdmVyeSB3ZWxjb21lIFtv
biB0aGUgaXNzdWUgdHJhY2tlcl0gKG9yIGJlbGxvdykhDQoNCg0KWzNEIGdyYW1tYXJdDQo8aHR0
cHM6Ly9wcm9qZWN0LWV2ZXJlc3QuZ2l0aHViLmlvL2V2ZXJwYXJzZS8zZC5odG1sI2xhbmd1YWdl
LXJlZmVyZW5jZT4NCg0KW0RhbmllbCdzIHRhZ2dlZCBmaW5hbCBlbmNvZGluZyBhcHByb2FjaF0N
CjxodHRwczovL2dpdGh1Yi5jb20vZGJ1ZW56bGkvanNvbnQvYmxvYi9tYWluL3BhcGVyL3NvdXAu
cGRmPg0KDQpbb24gdGhlIGlzc3VlIHRyYWNrZXJdIDxodHRwczovL2dpdGh1Yi5jb20vcGFyc2lt
b25pLWxhYnMvb2NhbWwtd2lyZT4NCg0KDQp2YWxrZXk6IG1vZGVybiBWYWxrZXkgY2xpZW50IGZv
ciBPQ2FtbCA1ICsgRWlvLCBvbiBvcGFtDQrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZlOg0KICA8aHR0cHM6Ly9kaXNjdXNzLm9j
YW1sLm9yZy90L2Fubi12YWxrZXktbW9kZXJuLXZhbGtleS1jbGllbnQtZm9yLW9jYW1sLTUtZWlv
LW9uLW9wYW0vMTgwMTAvMT4NCg0KDQpBdmkgRmVuZXNoIGFubm91bmNlZA0K4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgSGkg
ZXZlcnlvbmUsDQoNCiAgSSB3YW50ZWQgdG8gc2hhcmUgdGhhdCBgdmFsa2V5JyAwLjIuMCBpcyBu
b3cgb24gb3BhbToNCg0KICDigKIgb3BhbTogPGh0dHBzOi8vb3BhbS5vY2FtbC5vcmcvcGFja2Fn
ZXMvdmFsa2V5L3ZhbGtleS4wLjIuMC8+DQogIOKAoiBSZXBvIGFuZCBHZXR0aW5nIFN0YXJ0ZWQ6
DQogICAgPGh0dHBzOi8vZ2l0aHViLmNvbS9hdmlmZW5lc2gvb2NhbWwtdmFsa2V5L2Jsb2IvbWFp
bi9kb2NzL2dldHRpbmctc3RhcnRlZC5tZD4NCg0KICBUaGUgbWFpbiB0aGluZyBJIHdhbnRlZCB3
aXRoIHRoaXMgcHJvamVjdCB3YXMgdG8gZm9jdXMgb24gdGhlIGN1cnJlbnQNCiAgVmFsa2V5IHN0
YWNrIHdpdGggdGhlIG5ld2VyIE9DYW1sIHN0YWNrLg0KDQogIFNvIGB2YWxrZXknIGlzIGJ1aWx0
IGFyb3VuZDoNCg0KICDigKIgT0NhbWwgNQ0KICDigKIgRWlvLW5hdGl2ZSBkaXJlY3Qtc3R5bGUg
Y29uY3VycmVuY3kNCiAg4oCiIFJFU1AzIG9ubHkNCiAg4oCiIE1vZGVybiBWYWxrZXkgZmVhdHVy
ZXMgYW5kIHJlYWwgY2x1c3RlciBiZWhhdmlvcg0KDQogIEEgZmV3IHBhcnRzIEknbSBoYXBweSB3
aXRoOg0KDQogIOKAoiBDbHVzdGVyIHN1cHBvcnQgd2l0aCBhIHN0cm9uZyBmb2N1cyBvbiBkdXJh
YmlsaXR5IGFuZCBoaWdoDQogICAgYXZhaWxhYmlsaXR5OiB0b3BvbG9neSByZWZyZXNoLCBwZXJp
b2RpYyBiYWNrZ3JvdW5kIHJlZnJlc2gsIGBNT1ZFRCcNCiAgICAvIGBBU0snIC8gYENMVVNURVJE
T1dOJyBoYW5kbGluZywgcmVwbGljYS1hd2FyZSByZWFkcywgQVotYXdhcmUNCiAgICByb3V0aW5n
LCBhbmQgZmFpbG92ZXItYXdhcmUgc2hhcmRlZCBwdWIvc3ViIHJlcGxheQ0KICDigKIgY29ubmVj
dGlvbi9ydW50aW1lIGJlaGF2aW9yOiBjaXJjdWl0IGJyZWFrZXIsIHJlY29ubmVjdCBoYW5kbGlu
ZywNCiAgICBrZWVwYWxpdmUsIFRMUywgYW5kIG9wdGlvbmFsIHNlcGFyYXRpb24gYmV0d2VlbiBz
b2NrZXQgSS9PIGFuZA0KICAgIHBhcnNpbmcgdmlhIGBFaW8uRG9tYWluX21hbmFnZXInLCBzbyBv
bmUgc2lkZSBvZiB0aGUgc3lzdGVtIGRvZXMgbm90DQogICAgYmxvY2sgdGhlIG90aGVyDQogIOKA
oiBiYXRjaCBzdXBwb3J0OiBzY2F0dGVyLWdhdGhlciBhY3Jvc3Mgc2xvdHMsIGF0b21pYyBzaW5n
bGUtc2xvdCBmbG93cw0KICAgIHdpdGggYFdBVENIJyAvIGBNVUxUSScgLyBgRVhFQycsIG11bHRp
LXNsb3QgaGVscGVycywgYW5kIGluIGAwLjIuMCcNCiAgICBhbHNvIFdBVENIIGd1YXJkcyBmb3Ig
cmVhZC1tb2RpZnktd3JpdGUgQ0FTIHBsdXMgY3Jvc3Mtc2xvdA0KICAgIGBwZmNvdW50X2NsdXN0
ZXInDQogIOKAoiBjb21tYW5kIHN1cmZhY2U6IHR5cGVkIGhlbHBlcnMgYWNyb3NzIGEgcHJldHR5
IGJyb2FkIHNldCBvZg0KICAgIGNvbW1hbmRzLCBgQ2xpZW50LmN1c3RvbScgL35jdXN0b21fbXVs
dGl+IGZvciBjdXN0b20gY29tbWFuZHMgYW5kDQogICAgbXVsdGktbm9kZSBleGVjdXRpb24sIGFu
ZCBuYW1lZCBjb21tYW5kcyBzbyB5b3UgY2FuIHJlZ2lzdGVyIGNvbW1hbmQNCiAgICB0ZW1wbGF0
ZXMgb25jZSBhbmQgcmV1c2UgdGhlbSBsYXRlcg0KICDigKIgc2NyaXB0aW5nOiBsb2NhbCBzY3Jp
cHQgY2FjaGluZyBhbmQgb3B0aW1pc3RpYyBgRVZBTFNIQScgaGFuZGxpbmcNCiAgICB3aXRoIGF1
dG9tYXRpYyBmYWxsYmFjay9yZXRyeSBvbiBgTk9TQ1JJUFQnLCBzbyBjYWxsZXJzIGRvbid0IG5l
ZWQNCiAgICB0byBtYW5hZ2UgdGhhdCBmbG93IHRoZW1zZWx2ZXMNCg0KICBUaGVyZSBpcyBhbHNv
IGFscmVhZHkgYSBwcmV0dHkgZ29vZCBhbW91bnQgb2YgdmFsaWRhdGlvbiBhcm91bmQgaXQ6DQog
IGludGVncmF0aW9uIHRlc3RzLCBwcm9wZXJ0eSB0ZXN0cywgZnV6emluZywgY2hhb3MgdGVzdGlu
ZywgZXhhbXBsZXMsDQogIGFuZCBndWlkZXMuDQoNCiAgUGVyZm9ybWFuY2Utd2lzZSwgaXQgYWxz
byBjYW1lIG91dCBwcmV0dHkgbmljZWx5OiBpbiBzZXZlcmFsIHNjZW5hcmlvcw0KICBpdCBnZXRz
IHRvIDkwJSsgb2YgdGhlIEMgcmVmZXJlbmNlIGNsaWVudC4NCg0KICDilIzilIDilIDilIDilIAN
CiAg4pSCIG9wYW0gdXBkYXRlDQogIOKUgiBvcGFtIGluc3RhbGwgdmFsa2V5IGVpb19tYWluDQog
IOKUlOKUgOKUgOKUgOKUgA0KDQogIEN1cnJlbnQgbmV4dCBzdGVwcyBvbiB0aGUgcm9hZG1hcCBh
cmUgdGhpbmdzIGxpa2U6DQoNCiAg4oCiIGNsaWVudC1zaWRlIGNhY2hpbmcNCiAg4oCiIGNvbm5l
Y3Rpb24gcG9vbHMgLyBibG9ja2luZyBwb29scw0KICDigKIgYElBTScgKyBgbVRMUycNCiAg4oCi
IFZhbGtleSBtb2R1bGUgc3VwcG9ydCAoSlNPTiwgc2VhcmNoLCBibG9vbSkNCg0KICBJZiB0aGVy
ZSdzIGEgZmVhdHVyZSBwZW9wbGUgY2FyZSBhYm91dCwgSSdkIGJlIHZlcnkgaGFwcHkgdG8NCiAg
cmVwcmlvcml0aXplIHRoZSByb2FkbWFwIGFyb3VuZCByZWFsIGludGVyZXN0Lg0KDQogIEknZCBh
bHNvIHJlYWxseSBsb3ZlIGZlZWRiYWNrIGZyb20gdGhlIE9DYW1sIGNvbW11bml0eSBvbiB0aGUg
QVBJLA0KICBlcmdvbm9taWNzLCBkb2NzLCBhbmQgZ2VuZXJhbCBkZXNpZ24uDQoNCiAgSSdtIHZl
cnkgZmFtaWxpYXIgd2l0aCB0aGUgVmFsa2V5IHdvcmxkLCBidXQgT0NhbWwgaXMgbW9yZSBvZiBh
IHNpZGUNCiAgZnVuIGZvciBtZSB0aGFuIG15IGRhaWx5IGxhbmd1YWdlLCBzbyBmZWVkYmFjayBm
cm9tIHBlb3BsZSB3aG8gcmVhbGx5DQogIGxpdmUgaW4gdGhlIE9DYW1sIGVjb3N5c3RlbSBpcyBl
c3BlY2lhbGx5IHZhbHVhYmxlIHRvIG1lLg0KDQogIElmIHlvdSB0cnkgaXQsIEknZCBsb3ZlIHRv
IGhlYXIgd2hhdCB5b3UgdGhpbmsuDQoNCg0KVW5pZmllZFNjcmlwdF97U3RkLFRvcH0gLSBsaXRl
cmF0ZSB0ZXN0aW5nDQrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZlOg0KICA8aHR0cHM6Ly9kaXNj
dXNzLm9jYW1sLm9yZy90L2Fubi11bmlmaWVkc2NyaXB0LXN0ZC10b3AtbGl0ZXJhdGUtdGVzdGlu
Zy8xODAxMy8xPg0KDQoNCmpiZWNrZm9yZCBhbm5vdW5jZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKU
gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIEkgYW0gcGxlYXNlZCB0
byBpbnRyb2R1Y2UgdGhlIGBVbmlmaWVkU2NyaXB0X1N0ZCcgYW5kDQogIGBVbmlmaWVkU2NyaXB0
X1RvcCcgcGFja2FnZXMuIFVuaWZpZWQgc2NyaXB0cyBhcmUgYSB3YXkgdG8gd3JpdGUgdGVzdHMN
CiAgYW5kIGRvY3VtZW50YXRpb24gc2ltdWx0YW5lb3VzbHkuIENyYW0gdGVzdHMgYW5kIFtNRFgg
c2NyaXB0c10gYXJlDQogIGJvdGggc2ltaWxhciB0byB1bmlmaWVkIHNjcmlwdHMsIGJ1dCB1bmlm
aWVkIHNjcmlwdHMgYXJlbid0IHRpZWQgdG8NCiAgTWFya2Rvd24gKE1EWCkgb3IgdGllZCB0byBQ
T1NJWCBzaGVsbCBjb21tYW5kcyAoY3JhbSB0ZXN0cykuDQoNCiAgRXhhbXBsZXM6DQoNCiAg4oCi
IC9NYXJrZG93biBleGFtcGxlLzogSGVyZSBhcmUgdGhlIHppbGxpb25zIG9mIHRlc3RzIGZyb20g
YG9jYW1sLXJlJw0KICAgIGNvbnZlcnRlZCBpbnRvIE1hcmtkb3duOiBbb2NhbWwtcmUvRVhBTVBM
RVMubWRdLiBDdXN0b20gT0NhbWwgUkVQTA0KICAgIHByaW50ZXJzIGFyZSB1c2VkIHNvIHRoYXQg
bWFueSBvZiB0aGUgdGVzdHMgYXJlIHByaW50ZWQgYXMgTWFya2Rvd24NCiAgICB0YWJsZXMuIC9h
c2lkZTogV291bGRuJ3QgaXQgYmUgbmljZSBpZiB0ZXN0cyB5b3UgYXJlIGFscmVhZHkgd3JpdGlu
Zw0KICAgIGJlY2FtZSBkb2N1bWVudGF0aW9uPyBUaGF0IHdhcyBhIDQgeWVhciBmb2xsb3ctdXAg
dG8NCiAgICA8aHR0cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90L3doYXQtYXJlLXRoZS1iaWdnZXN0
LXJlYXNvbnMtbmV3Y29tZXJzLWdpdmUtdXAtb24tb2NhbWwvMTA5NTgvMTM/dT1qYmVja2ZvcmQ+
Lw0KICDigKIgL2AubWwnIGV4YW1wbGUvOiBUaGUgZm9sbG93aW5nIGlzIGEgc25pcHBldCBmcm9t
IFthIHJlZ3VsYXIgT0NhbWwNCiAgICBgLm1sJyBtb2R1bGVdIHdoZXJlIHRoZSBgKCogLi4uICop
JyBjb21tZW50cyBhcmUgT0NhbWwgUkVQTCB0b3BsZXZlbA0KICAgIHJlc3BvbnNlcyBtYWludGFp
bmVkIGJ5IHRoZSB1bmlmaWVkIHRvb2xzLg0KICAgIOKUjOKUgOKUgOKUgOKUgA0KICAgIOKUgiBs
ZXQgbHlyaWNzID0NCiAgICDilIIgICAiRXZlcnlib2R5IHN0ZXAgdG8gdGhlIGxlZnQuIg0KICAg
IOKUgiAgICgqIHZhbCBseXJpY3MgOiBzdHJpbmcgPSAiRXZlcnlib2R5IHN0ZXAgdG8gdGhlIGxl
ZnQuIiAqKVtAb2NhbWxmb3JtYXQgImRpc2FibGUiXQ0KICAgIOKUgiANCiAgICDilIIgbGV0IChf
IDogc3RyaW5nKSA9DQogICAg4pSCICAgUHJpbnRmLnNwcmludGYgIk5vdyBsZXQncyBzaW5nOiAl
cyIgbHlyaWNzDQogICAg4pSCICAgKCogLSA6IHN0cmluZyA9ICJOb3cgbGV0J3Mgc2luZzogRXZl
cnlib2R5IHN0ZXAgdG8gdGhlIGxlZnQuIiAqKVtAb2NhbWxmb3JtYXQgImRpc2FibGUiXQ0KICAg
IOKUlOKUgOKUgOKUgOKUgA0KDQogIERvY3MgYXJlIGF0IFtkay9kb2NzL1VOSUZJRURfU0NSSVBU
Uy5tZF0gKG9mIGNvdXJzZSBnZW5lcmF0ZWQgYnkgdGhlDQogIHVuaWZpZWQgdG9vbHMpLg0KDQog
IEluc3RhbGwgdGhlIHRvb2xzIHdpdGg6DQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBvcGFt
IHBpbiBhZGQgVW5pZmllZFNjcmlwdF9TdGQgaHR0cHM6Ly9naXRsYWIuY29tL2RrbWwvYnVpbGQt
dG9vbHMvTWxGcm9udC8tL3JlbGVhc2VzL3Blcm1hbGluay9sYXRlc3QvZG93bmxvYWRzL01sRnJv
bnQudGFyLmd6DQogIOKUgiBvcGFtIHBpbiBhZGQgVW5pZmllZFNjcmlwdF9Ub3AgaHR0cHM6Ly9n
aXRsYWIuY29tL2RrbWwvYnVpbGQtdG9vbHMvTWxGcm9udC8tL3JlbGVhc2VzL3Blcm1hbGluay9s
YXRlc3QvZG93bmxvYWRzL01sRnJvbnQudGFyLmd6DQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIEFm
dGVyIGZlZWRiYWNrIEknbGwgcmVsZWFzZSB0aGVtIG9mZmljaWFsbHkgdG8gb3BhbS4gSSB3b3Vs
ZCBsaWtlDQogIGZlZWRiYWNrIG92ZXJhbGwgYW5kIGFsc28gc3BlY2lmaWNhbGx5IG9uIHRoZSBb
YWdlbnQgc2tpbGwgdGhhdA0KICBjb252ZXJ0cyBleHBlY3QgdGVzdHMgdG8gdW5pZmllZCB0ZXN0
c10uDQoNCg0KW01EWCBzY3JpcHRzXSA8aHR0cHM6Ly9naXRodWIuY29tL3JlYWx3b3JsZG9jYW1s
L21keD4NCg0KW29jYW1sLXJlL0VYQU1QTEVTLm1kXQ0KPGh0dHBzOi8vZ2l0aHViLmNvbS9qb25h
aGJlY2tmb3JkL29jYW1sLXJlL2Jsb2IvN2RiZmM0NDZiZDU5NDMwM2FkZDAwZjQ0M2JkZWEyMDZi
MDg1MTFjMi9FWEFNUExFUy5tZD4NCg0KW2EgcmVndWxhciBPQ2FtbCBgLm1sJyBtb2R1bGVdDQo8
aHR0cHM6Ly9naXRsYWIuY29tL2RrbWwvYnVpbGQtdG9vbHMvTWxGcm9udC8tL2Jsb2IvMzc0YmJh
Yzc3MDAzY2Q4Y2VlNTZmMDY2NGNlYzk3NGFhMzE0YzY0OC9zcmMvVW5pZmllZFNjcmlwdF9Ub3Av
cGxhaW5tb2R1bGUubWw+DQoNCltkay9kb2NzL1VOSUZJRURfU0NSSVBUUy5tZF0NCjxodHRwczov
L2dpdGh1Yi5jb20vZGlza3V2L2RrL2Jsb2IvZmZhMTMwYTFkYmVmY2QxMzRiMGQxNWYxMTJmZDZk
NmM5OWRjMGZjOC9kb2NzL1VOSUZJRURfU0NSSVBUUy5tZD4NCg0KW2FnZW50IHNraWxsIHRoYXQg
Y29udmVydHMgZXhwZWN0IHRlc3RzIHRvIHVuaWZpZWQgdGVzdHNdDQo8aHR0cHM6Ly9naXRodWIu
Y29tL2pvbmFoYmVja2ZvcmQvb2NhbWwtcmUvYmxvYi9tYWtlLWxpdGVyYXRlLXRlc3RzLy5jbGF1
ZGUvc2tpbGxzL21ha2UtbGl0ZXJhdGUtdGVzdHMvU0tJTEwubWQ+DQoNCg0Kb3BlbnJvdXRlcl9h
cGk6IEFuIE9wZW5Sb3V0ZXIgY2xpZW50IGxpYnJhcnkNCuKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV
kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkA0KDQog
IEFyY2hpdmU6DQogIDxodHRwczovL2Rpc2N1c3Mub2NhbWwub3JnL3QvYW5uLW9wZW5yb3V0ZXIt
YXBpLWFuLW9wZW5yb3V0ZXItY2xpZW50LWxpYnJhcnkvMTgwMTYvMT4NCg0KDQptdF9jYXJldCBh
bm5vdW5jZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU
gOKUgOKUgA0KDQogIEknbSBoYXBweSB0byBhbm5vdW5jZSB0aGUgZmlyc3QgdmVyc2lvbiAodjAu
MC4xKSBvZiBgb3BlbnJvdXRlcl9hcGknLA0KICBhIGxpYnJhcnkgZm9yIHF1ZXJ5aW5nIGxhcmdl
IGxhbmd1YWdlIG1vZGVscyB2aWEgT3BlblJvdXRlciwgYSBzZXJ2aWNlDQogIHdoaWNoIHByb3Zp
ZGVzIGFjY2VzcyB0byBhIHZhcmlldHkgb2YgbW9kZWxzIHVuZGVyIGEgdW5pZmllZCBBUEkuDQoN
CiAg4oCiIG9wYW06IDxodHRwczovL29wYW0ub2NhbWwub3JnL3BhY2thZ2VzL29wZW5yb3V0ZXJf
YXBpLz4NCiAg4oCiIEdpdEh1YjogW2h0dHBzOi8vZ2l0aHViLmNvbS9tdC1jYXJldC9vcGVucm91
dGVyLW9jYW1sXQ0KICDigKIgZG9jczoNCiAgICA8aHR0cHM6Ly9tdC1jYXJldC5naXRodWIuaW8v
b3BlbnJvdXRlci1vY2FtbC9vcGVucm91dGVyX2FwaS9pbmRleC5odG1sPg0KDQogIEkndmUgYmVl
biB1c2luZyB0aGlzIGxpYnJhcnkgaW4gbXkgcGVyc29uYWwgcHJvamVjdHMgd2hlbmV2ZXIgSSB3
YW50DQogIHRvIGludGVncmF0ZSBhbiBBSSBtb2RlbCwgYW5kIEkndmUgZm91bmQgaXQgcXVpdGUg
dXNlZnVsOyBJIGhvcGUNCiAgb3RoZXJzIHdpbGwgZmluZCBpdCB1c2VmdWwgYXMgd2VsbC4gSXNz
dWVzIGFuZCBjb250cmlidXRpb25zIGFyZQ0KICB3ZWxjb21lLg0KDQoNCltodHRwczovL2dpdGh1
Yi5jb20vbXQtY2FyZXQvb3BlbnJvdXRlci1vY2FtbF0NCjxodHRwczovL2dpdGh1Yi5jb20vbXQt
Y2FyZXQvb3BlbnJvdXRlci1vY2FtbD4NCg0KDQpDYWxsIGZvciBwcmVzZW50YXRpb25zOiBDYW1s
IGluIHRoZSBDYXBpdGFsIElJDQrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi
lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZl
Og0KICA8aHR0cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90L2NhbGwtZm9yLXByZXNlbnRhdGlvbnMt
Y2FtbC1pbi10aGUtY2FwaXRhbC1paS8xNzk1OS8yPg0KDQoNCkNvbnRpbnVpbmcgdGhpcyB0aHJl
YWQsIFNhY2hhIEF5b3VuIGFubm91bmNlZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA
4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgRGF0
ZSBhbmQgbG9jYXRpb24gaGF2ZSBiZWVuIGNvbmZpcm1lZCEgSnVuZSAzcmQgYXQgdGhlIEphbmUg
U3RyZWV0DQogIG9mZmljZSEhICBJIGhhdmUgdXBkYXRlZCB0aGUgcG9zdC4NCg0KICBXZSdyZSBz
dGlsbCBvcGVuIGZvciBwcmVzZW50YXRpb24gcHJvcG9zYWxzIGFzIHdlbGwhDQoNCg0KT2xkIENX
Tg0K4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgSWYgeW91IGhhcHBlbiB0byBtaXNzIGEgQ1dO
LCB5b3UgY2FuIFtzZW5kIG1lIGEgbWVzc2FnZV0gYW5kIEknbGwgbWFpbA0KICBpdCB0byB5b3Us
IG9yIGdvIHRha2UgYSBsb29rIGF0IFt0aGUgYXJjaGl2ZV0gb3IgdGhlIFtSU1MgZmVlZCBvZiB0
aGUNCiAgYXJjaGl2ZXNdLg0KDQogIElmIHlvdSBhbHNvIHdpc2ggdG8gcmVjZWl2ZSBpdCBldmVy
eSB3ZWVrIGJ5IG1haWwsIHlvdSBtYXkgc3Vic2NyaWJlDQogIHRvIHRoZSBbY2FtbC1saXN0XS4N
Cg0KICBbQWxhbiBTY2htaXR0XQ0KDQoNCltzZW5kIG1lIGEgbWVzc2FnZV0gPG1haWx0bzphbGFu
LnNjaG1pdHRAcG9seXRlY2huaXF1ZS5vcmc+DQoNClt0aGUgYXJjaGl2ZV0gPGh0dHBzOi8vYWxh
bi5wZXRpdGVwb21tZS5uZXQvY3duLz4NCg0KW1JTUyBmZWVkIG9mIHRoZSBhcmNoaXZlc10gPGh0
dHBzOi8vYWxhbi5wZXRpdGVwb21tZS5uZXQvY3duL2N3bi5yc3M+DQoNCltjYW1sLWxpc3RdIDxo
dHRwczovL3N5bXBhLmlucmlhLmZyL3N5bXBhL2luZm8vY2FtbC1saXN0Pg0KDQpbQWxhbiBTY2ht
aXR0XSA8aHR0cHM6Ly9hbGFuLnBldGl0ZXBvbW1lLm5ldC8+DQoNCg==
--==-=-=
Content-Type: text/html
Content-Disposition: inline

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
<head>
<!-- 2026-04-28 Tue 09:58 -->
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<title>OCaml Weekly News</title>
<meta name="generator" content="Org Mode" />
<style type="text/css">
  #content { max-width: 60em; margin: auto; }
  .title  { text-align: center;
             margin-bottom: .2em; }
  .subtitle { text-align: center;
              font-size: medium;
              font-weight: bold;
              margin-top:0; }
  .todo   { font-family: monospace; color: red; }
  .done   { font-family: monospace; color: green; }
  .priority { font-family: monospace; color: orange; }
  .tag    { background-color: #eee; font-family: monospace;
            padding: 2px; font-size: 80%; font-weight: normal; }
  .timestamp { color: #bebebe; }
  .timestamp-kwd { color: #5f9ea0; }
  .org-right  { margin-left: auto; margin-right: 0px;  text-align: right; }
  .org-left   { margin-left: 0px;  margin-right: auto; text-align: left; }
  .org-center { margin-left: auto; margin-right: auto; text-align: center; }
  .underline { text-decoration: underline; }
  #postamble p, #preamble p { font-size: 90%; margin: .2em; }
  p.verse { margin-left: 3%; }
  pre {
    border: 1px solid #e6e6e6;
    border-radius: 3px;
    background-color: #f2f2f2;
    padding: 8pt;
    font-family: monospace;
    overflow: auto;
    margin: 1.2em;
  }
  pre.src {
    position: relative;
    overflow: auto;
  }
  pre.src:before {
    display: none;
    position: absolute;
    top: -8px;
    right: 12px;
    padding: 3px;
    color: #555;
    background-color: #f2f2f299;
  }
  pre.src:hover:before { display: inline; margin-top: 14px;}
  /* Languages per Org manual */
  pre.src-asymptote:before { content: 'Asymptote'; }
  pre.src-awk:before { content: 'Awk'; }
  pre.src-authinfo::before { content: 'Authinfo'; }
  pre.src-c:before { content: 'C'; }
  pre.src-C:before { content: 'C'; }
  /* pre.src-C++ doesn't work in CSS */
  pre.src-clojure:before { content: 'Clojure'; }
  pre.src-css:before { content: 'CSS'; }
  pre.src-D:before { content: 'D'; }
  pre.src-ditaa:before { content: 'ditaa'; }
  pre.src-dot:before { content: 'Graphviz'; }
  pre.src-calc:before { content: 'Emacs Calc'; }
  pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
  pre.src-fortran:before { content: 'Fortran'; }
  pre.src-gnuplot:before { content: 'gnuplot'; }
  pre.src-haskell:before { content: 'Haskell'; }
  pre.src-hledger:before { content: 'hledger'; }
  pre.src-java:before { content: 'Java'; }
  pre.src-js:before { content: 'JavaScript'; }
  pre.src-latex:before { content: 'LaTeX'; }
  pre.src-ledger:before { content: 'Ledger'; }
  pre.src-lisp:before { content: 'Lisp'; }
  pre.src-lilypond:before { content: 'Lilypond'; }
  pre.src-lua:before { content: 'Lua'; }
  pre.src-matlab:before { content: 'MATLAB'; }
  pre.src-mscgen:before { content: 'Mscgen'; }
  pre.src-ocaml:before { content: 'Objective Caml'; }
  pre.src-octave:before { content: 'Octave'; }
  pre.src-org:before { content: 'Org mode'; }
  pre.src-oz:before { content: 'OZ'; }
  pre.src-plantuml:before { content: 'Plantuml'; }
  pre.src-processing:before { content: 'Processing.js'; }
  pre.src-python:before { content: 'Python'; }
  pre.src-R:before { content: 'R'; }
  pre.src-ruby:before { content: 'Ruby'; }
  pre.src-sass:before { content: 'Sass'; }
  pre.src-scheme:before { content: 'Scheme'; }
  pre.src-screen:before { content: 'Gnu Screen'; }
  pre.src-sed:before { content: 'Sed'; }
  pre.src-sh:before { content: 'shell'; }
  pre.src-sql:before { content: 'SQL'; }
  pre.src-sqlite:before { content: 'SQLite'; }
  /* additional languages in org.el's org-babel-load-languages alist */
  pre.src-forth:before { content: 'Forth'; }
  pre.src-io:before { content: 'IO'; }
  pre.src-J:before { content: 'J'; }
  pre.src-makefile:before { content: 'Makefile'; }
  pre.src-maxima:before { content: 'Maxima'; }
  pre.src-perl:before { content: 'Perl'; }
  pre.src-picolisp:before { content: 'Pico Lisp'; }
  pre.src-scala:before { content: 'Scala'; }
  pre.src-shell:before { content: 'Shell Script'; }
  pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
  /* additional language identifiers per "defun org-babel-execute"
       in ob-*.el */
  pre.src-cpp:before  { content: 'C++'; }
  pre.src-abc:before  { content: 'ABC'; }
  pre.src-coq:before  { content: 'Coq'; }
  pre.src-groovy:before  { content: 'Groovy'; }
  /* additional language identifiers from org-babel-shell-names in
     ob-shell.el: ob-shell is the only babel language using a lambda to put
     the execution function name together. */
  pre.src-bash:before  { content: 'bash'; }
  pre.src-csh:before  { content: 'csh'; }
  pre.src-ash:before  { content: 'ash'; }
  pre.src-dash:before  { content: 'dash'; }
  pre.src-ksh:before  { content: 'ksh'; }
  pre.src-mksh:before  { content: 'mksh'; }
  pre.src-posh:before  { content: 'posh'; }
  /* Additional Emacs modes also supported by the LaTeX listings package */
  pre.src-ada:before { content: 'Ada'; }
  pre.src-asm:before { content: 'Assembler'; }
  pre.src-caml:before { content: 'Caml'; }
  pre.src-delphi:before { content: 'Delphi'; }
  pre.src-html:before { content: 'HTML'; }
  pre.src-idl:before { content: 'IDL'; }
  pre.src-mercury:before { content: 'Mercury'; }
  pre.src-metapost:before { content: 'MetaPost'; }
  pre.src-modula-2:before { content: 'Modula-2'; }
  pre.src-pascal:before { content: 'Pascal'; }
  pre.src-ps:before { content: 'PostScript'; }
  pre.src-prolog:before { content: 'Prolog'; }
  pre.src-simula:before { content: 'Simula'; }
  pre.src-tcl:before { content: 'tcl'; }
  pre.src-tex:before { content: 'TeX'; }
  pre.src-plain-tex:before { content: 'Plain TeX'; }
  pre.src-verilog:before { content: 'Verilog'; }
  pre.src-vhdl:before { content: 'VHDL'; }
  pre.src-xml:before { content: 'XML'; }
  pre.src-nxml:before { content: 'XML'; }
  /* add a generic configuration mode; LaTeX export needs an additional
     (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
  pre.src-conf:before { content: 'Configuration File'; }

  table { border-collapse:collapse; }
  caption.t-above { caption-side: top; }
  caption.t-bottom { caption-side: bottom; }
  td, th { vertical-align:top;  }
  th.org-right  { text-align: center;  }
  th.org-left   { text-align: center;   }
  th.org-center { text-align: center; }
  td.org-right  { text-align: right;  }
  td.org-left   { text-align: left;   }
  td.org-center { text-align: center; }
  dt { font-weight: bold; }
  .footpara { display: inline; }
  .footdef  { margin-bottom: 1em; }
  .figure { padding: 1em; }
  .figure p { text-align: center; }
  .equation-container {
    display: table;
    text-align: center;
    width: 100%;
  }
  .equation {
    vertical-align: middle;
  }
  .equation-label {
    display: table-cell;
    text-align: right;
    vertical-align: middle;
  }
  .inlinetask {
    padding: 10px;
    border: 2px solid gray;
    margin: 10px;
    background: #ffffcc;
  }
  #org-div-home-and-up
   { text-align: right; font-size: 70%; white-space: nowrap; }
  textarea { overflow-x: auto; }
  .linenr {
    font-size: smaller;
    @supports (content: attr(data-linenr)) {
      visibility: hidden;
      &::before { content: attr(data-linenr); visibility: visible; }
    }
  }
  .code-highlighted { background-color: #ffff00; }
  .org-info-js_info-navigation { border-style: none; }
  #org-info-js_console-label
    { font-size: 10px; font-weight: bold; white-space: nowrap; }
  .org-info-js_search-highlight
    { background-color: #ffff00; color: #000000; font-weight: bold; }
  .org-svg { }
</style>
<style type="text/css">#table-of-contents h2 { display: none } .title { display: none } .authorname { text-align: right }</style>
<style type="text/css">.outline-2 {border-top: 1px solid black;}</style>
</head>
<body>
<div id="content" class="content">
<h1 class="title">OCaml Weekly News</h1>
<p>
<a href="https://alan.petitepomme.net/cwn/2026.04.21.html">Previous Week</a> <a href="https://alan.petitepomme.net/cwn/index.html">Up</a> <a href="https://alan.petitepomme.net/cwn/2026.05.05.html">Next Week</a>
</p>

<p>
Hello
</p>

<p>
Here is the latest OCaml Weekly News, for the week of April 21 to 28, 2026.
</p>

<div id="table-of-contents" role="doc-toc">
<h2>Table of Contents</h2>
<div id="text-table-of-contents" role="doc-toc">
<ul>
<li><a href="#1">Closing Old Bugs With Tests: A Dune Contribution Story</a></li>
<li><a href="#2">ocaml-wire: a Binary wire format DSL with EverParse 3D output</a></li>
<li><a href="#3">valkey: modern Valkey client for OCaml 5 + Eio, on opam</a></li>
<li><a href="#4">UnifiedScript_{Std,Top} - literate testing</a></li>
<li><a href="#5">openrouter_api: An OpenRouter client library</a></li>
<li><a href="#6">Call for presentations: Caml in the Capital II</a></li>
<li><a href="#org93d51c4">Old CWN</a></li>
</ul>
</div>
</div>
<div id="outline-container-1" class="outline-2">
<h2 id="1">Closing Old Bugs With Tests: A Dune Contribution Story</h2>
<div class="outline-text-2" id="text-1">
<p>
Archive: <a href="https://discuss.ocaml.org/t/closing-old-bugs-with-tests-a-dune-contribution-story/18008/1">https://discuss.ocaml.org/t/closing-old-bugs-with-tests-a-dune-contribution-story/18008/1</a>
</p>
</div>
<div id="outline-container-orgf6767d6" class="outline-3">
<h3 id="orgf6767d6">Robin Bate Boerop announced</h3>
<div class="outline-text-3" id="text-orgf6767d6">
<p>
I recently started contributing to Dune with no prior familiarity with the code base. One thing I found rewarding was closing old issues &mdash; some filed as far back as 2018 &mdash; and I wanted to share the approach I used.
</p>
</div>
<div id="outline-container-orgb62fc7e" class="outline-4">
<h4 id="orgb62fc7e">The Method: Close With a Test</h4>
<div class="outline-text-4" id="text-orgb62fc7e">
<p>
Many open issues describe behaviour that has already been fixed, or behaviour that is working correctly but was never verified with a test. My approach: write a cram test that demonstrates the expected behaviour, link the PR to the issue with <code>fixes #NNNN</code>, and let the merge close the issue automatically.
</p>

<p>
This has several advantages over simply closing an issue with a comment like "this works now":
</p>

<ul class="org-ul">
<li><b>It's verifiable.</b> Anyone can read the test and see exactly what behaviour is being asserted. There's no argument about whether the issue is truly resolved.</li>
<li><b>It prevents regressions.</b> If the behaviour breaks again in the future, the test fails. The issue doesn't silently reopen &mdash; the CI catches it.</li>
<li><b>It grows the test suite.</b> Every closed issue leaves behind a test that documents a real-world scenario someone cared about.</li>
<li><b>It respects the reporter.</b> Someone took the time to file the issue. A test that captures their concern is a better acknowledgement than a drive-by close.</li>
</ul>

<p>
After a few weeks of contributing test PRs and bug fixes, I was given triager and then maintainer status on the project. This let me close issues directly when they were clearly resolved, and merge my own test PRs. Before that, the existing maintainers merged them on my behalf.
</p>

<p>
Honestly, I regret closing issues where I could have used this method but didn't. The method is much superior to simply adding to a GitHub discussion about the bug and then closing the issue.
</p>
</div>
</div>
<div id="outline-container-org4a61073" class="outline-4">
<h4 id="org4a61073">Issues I Helped Close</h4>
<div class="outline-text-4" id="text-org4a61073">
<p>
Here's an accounting of what I helped close, grouped by what it took:
</p>
</div>
<ul class="org-ul">
<li><a id="org62c651f"></a>Confirmed resolved; closed directly<br />
<div class="outline-text-5" id="text-org62c651f">
<p>
These issues described problems that no longer existed on main. In some cases I confirmed this myself, in others someone else had already verified it. As a triager/maintainer I was able to close them:
</p>

<ul class="org-ul">
<li><a href="https://github.com/ocaml/dune/issues/1974">#1974</a> &mdash; <code>@all</code> target doesn't interact well with <code>(include_subdirs ...)</code> (filed 2019)</li>
<li><a href="https://github.com/ocaml/dune/issues/3173">#3173</a> &mdash; Can't promote into a directory starting with underscore (filed 2020)</li>
<li><a href="https://github.com/ocaml/dune/issues/3805">#3805</a> &mdash; No such file or directory when <code>DUNE_BUILD_DIR</code> is set during test (filed 2020)</li>
<li><a href="https://github.com/ocaml/dune/issues/8242">#8242</a> &mdash; Very slow emacs compilation buffer updates (filed 2023)</li>
<li><a href="https://github.com/ocaml/dune/issues/10360">#10360</a> &mdash; <code>executables_implicit_empty_intf</code> expects dune &gt;= 2.9 but was only added in 3.0 (filed 2024)</li>
</ul>
</div>
</li>
<li><a id="org4ffecd5"></a>Closed with a test PR<br />
<div class="outline-text-5" id="text-org4ffecd5">
<p>
These issues were resolved by writing a test that demonstrates the correct behaviour. No code changes were needed &mdash; the test itself closed the issue:
</p>

<ul class="org-ul">
<li><a href="https://github.com/ocaml/dune/issues/2370">#2370</a> &mdash; <code>.h</code> files copied to <code>_build</code> without foreign stubs (filed 2019, test: <a href="https://github.com/ocaml/dune/pull/14172">#14172</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/3362">#3362</a> &mdash; Cannot use <code>%{lib:...}</code> in the <code>flags</code> stanza (filed 2020, test: <a href="https://github.com/ocaml/dune/pull/14146">#14146</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/3484">#3484</a> &mdash; Promoting over a running binary (filed 2020, test: <a href="https://github.com/ocaml/dune/pull/14173">#14173</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/11110">#11110</a> &mdash; Libexec site install doesn't set executable bit (filed 2024, test: <a href="https://github.com/ocaml/dune/pull/14171">#14171</a>)</li>
</ul>
</div>
</li>
<li><a id="org6a86c34"></a>Closed with a test and a code fix<br />
<div class="outline-text-5" id="text-org6a86c34">
<p>
These required both a test and a code change to resolve:
</p>

<ul class="org-ul">
<li><a href="https://github.com/ocaml/dune/issues/878">#878</a> &mdash; <code>dune subst</code> adds duplicate version field in opam (filed 2018, fix: <a href="https://github.com/ocaml/dune/pull/14136">#14136</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/2445">#2445</a> &mdash; dune sends SIGKILL without prior SIGTERM (filed 2019, fixes: <a href="https://github.com/ocaml/dune/pull/14170">#14170</a>, <a href="https://github.com/ocaml/dune/pull/14224">#14224</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/3916">#3916</a> &mdash; Duplicate bounds in autogenerated opam files (filed 2020, fix: <a href="https://github.com/ocaml/dune/pull/14175">#14175</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/6148">#6148</a> &mdash; <code>root_module</code> generates duplicate module definition (filed 2022, fix: <a href="https://github.com/ocaml/dune/pull/14135">#14135</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/9757">#9757</a> &mdash; <code>dune runtest</code> doesn't execute byte-only inline tests (filed 2024, fix: <a href="https://github.com/ocaml/dune/pull/14174">#14174</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/10707">#10707</a> &mdash; Missing menhir lower bound in generated opam files (filed 2024, fix: <a href="https://github.com/ocaml/dune/pull/14168">#14168</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/11002">#11002</a> &mdash; opam file generation error-prone (filed 2024, fix: <a href="https://github.com/ocaml/dune/pull/14136">#14136</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/11106">#11106</a> &mdash; Redundant dune version constraint in opam files (filed 2024, fix: <a href="https://github.com/ocaml/dune/pull/14175">#14175</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/12007">#12007</a> &mdash; <code>dune build @ocaml-index</code> builds too many files (filed 2025, partially fixed with <a href="https://github.com/ocaml/dune/pull/14137">#14137</a>)</li>
<li><a href="https://github.com/ocaml/dune/issues/14089">#14089</a> &mdash; Incremental builds with <code>(wrapped (transition ...))</code> broken (filed 2026, test: <a href="https://github.com/ocaml/dune/pull/14088">#14088</a>, fix: <a href="https://github.com/ocaml/dune/pull/14090">#14090</a>)</li>
</ul>
</div>
</li>
</ul>
</div>
<div id="outline-container-orgaa1471b" class="outline-4">
<h4 id="orgaa1471b">What I Learned</h4>
<div class="outline-text-4" id="text-orgaa1471b">
<p>
<b>Writing tests is a good way to learn about a code base.</b> Each test forced me to understand how a feature actually works &mdash; not the architecture in the abstract, but the concrete behaviour in specific scenarios. The understanding compounded.
</p>

<p>
<b>Dune's cram tests make this easy.</b> Each test is a self-contained shell script with expected output, checked into the repo as a <code>.t</code> file. The barrier to writing a test is low, which is exactly what you want when your goal is to close issues by testing them. This occasionally backfired by being "too easy" - when I wrote tests to which maintainers objected because I had not done so in a Dune-idiomatic way; but this was still net positive for sure.
</p>

<p>
<b>Consistent presence matters.</b> I contributed nearly every day over several weeks. I think that this helped maintainers feel that I was "present" - that efforts that they made to help me were investments; so they were less prone to holding back reviews.
</p>
</div>
</div>
</div>
</div>
<div id="outline-container-2" class="outline-2">
<h2 id="2">ocaml-wire: a Binary wire format DSL with EverParse 3D output</h2>
<div class="outline-text-2" id="text-2">
<p>
Archive: <a href="https://discuss.ocaml.org/t/ann-ocaml-wire-a-binary-wire-format-dsl-with-everparse-3d-output/18009/1">https://discuss.ocaml.org/t/ann-ocaml-wire-a-binary-wire-format-dsl-with-everparse-3d-output/18009/1</a>
</p>
</div>
<div id="outline-container-orgd62a4a5" class="outline-3">
<h3 id="orgd62a4a5">Thomas Gazagnaire announced</h3>
<div class="outline-text-3" id="text-orgd62a4a5">
<p>
I'm happy to announce the release of <code>ocaml-wire 0.9.0</code> to opam!
</p>

<p>
<code>ocaml-wire</code> is a set of combinators to describe binary protocols in OCaml. "Binary" as in fixed-layout: sizes and shapes are mostly known up front, so you're reading fields at known offsets rather than parsing a free-form grammar (like in Menhir). There are already many good binary parser frameworks in OCaml &ndash; here's what's different in <code>ocaml-wire</code>:
</p>

<ul class="org-ul">
<li>The central data structure is EverParse's <a href="https://project-everest.github.io/everparse/3d.html#language-reference">3D grammar</a>. The OCaml combinators describe a 3D structure. Following <a href="https://github.com/dbuenzli/jsont/blob/main/paper/soup.pdf">Daniel's tagged final encoding approach</a>, you build a codec that describes a struct and how to serialise/deserialise it from an OCaml value.</li>
<li>Which means every description can compile down to a .3d file and from there to C via EverParse &ndash; and the generated C compiles cleanly with <code>-std=c99 -Wall -Werror</code>. So you could, in theory (I haven't pushed on this too far for now), build and link a complex stack as an standalone, external C parser whose memory safety, single-pass behaviour, and conformance to the 3D spec are proven in F*(EverParse doesn't give you serialisers, unfortunately).</li>
<li>If you prefer, you can still use the OCaml parsers/verifiers, which have been made reasonably fast (i.e. no extra allocations on the hot path), and as they are streaming codecs you can just read or write a single field of the structure without parsing the whole thing. They also compile trivially to JavaScript via <code>js_of_ocaml</code>, if you need to parse the same format in the browser.</li>
</ul>

<p>
A small example &ndash; a packet with two nibble-wide fields, a big-endian length, and a variable-size payload whose length is read from the Length field:
</p>

<div class="org-src-container">
<pre class="src src-ocaml"><code><span style="color: #242521; font-weight: bold;">open </span><span style="color: #557400; font-weight: bold;">Wire</span>

<span style="color: #242521; font-weight: bold;">type</span> <span style="color: #444fcf; font-weight: bold;">packet</span> = { version : int; flags : int; length : int; payload : string }

<span style="color: #242521; font-weight: bold;">let</span> <span style="color: #007a9f;">f_version</span> = <span style="color: #557400; font-weight: bold;">Field.</span>v <span style="color: #ca3400;">"Version"</span> (bits <span style="color: #444fcf; font-weight: bold;">~width</span>:4 <span style="color: #242521;">U8</span>)
<span style="color: #242521; font-weight: bold;">let</span> <span style="color: #007a9f;">f_flags</span>   = <span style="color: #557400; font-weight: bold;">Field.</span>v <span style="color: #ca3400;">"Flags"</span>   (bits <span style="color: #444fcf; font-weight: bold;">~width</span>:4 <span style="color: #242521;">U8</span>)
<span style="color: #242521; font-weight: bold;">let</span> <span style="color: #007a9f;">f_length</span>  = <span style="color: #557400; font-weight: bold;">Field.</span>v <span style="color: #ca3400;">"Length"</span>  uint16be
<span style="color: #242521; font-weight: bold;">let</span> <span style="color: #007a9f;">f_payload</span> = <span style="color: #557400; font-weight: bold;">Field.</span>v <span style="color: #ca3400;">"Payload"</span> (byte_array <span style="color: #444fcf; font-weight: bold;">~size</span>:(<span style="color: #557400; font-weight: bold;">Field.</span><span style="color: #557400; font-weight: bold;">ref</span> f_length))

<span style="color: #242521; font-weight: bold;">let</span> <span style="color: #007a9f;">codec</span> =
  <span style="color: #242521; font-weight: bold;">let</span> <span style="color: #242521; font-weight: bold;">open </span><span style="color: #557400; font-weight: bold;">Codec</span> <span style="color: #242521; font-weight: bold;">in</span>
  v <span style="color: #ca3400;">"Packet"</span> (<span style="color: #006f00; font-weight: bold;">fun</span> <span style="color: #007a9f;">version</span> <span style="color: #007a9f;">flags</span> <span style="color: #007a9f;">length</span> <span style="color: #007a9f;">payload</span> -&gt; { version; flags; length; payload })
    [ f_version <span style="color: #9f0d0f;">$</span> (<span style="color: #006f00; font-weight: bold;">fun</span> <span style="color: #007a9f;">p</span> -&gt; p.version);
      f_flags   <span style="color: #9f0d0f;">$</span> (<span style="color: #006f00; font-weight: bold;">fun</span> <span style="color: #007a9f;">p</span> -&gt; p.flags);
      f_length  <span style="color: #9f0d0f;">$</span> (<span style="color: #006f00; font-weight: bold;">fun</span> <span style="color: #007a9f;">p</span> -&gt; p.length);
      f_payload <span style="color: #9f0d0f;">$</span> (<span style="color: #006f00; font-weight: bold;">fun</span> <span style="color: #007a9f;">p</span> -&gt; p.payload) ]
</code></pre>
</div>

<p>
<code>Field.ref f_length</code> is the dependent-size bit: the payload's length comes from the <code>f_length</code> field read earlier in the same struct. That same codec value is what you hand to <code>Everparse.schema</code> to get the 3D file out, and what backs <code>Codec.get</code> / <code>Codec.set</code> for streaming field access from OCaml. <code>ocaml-wire</code> also ships the infrastructure for generating FFI stubs and for differential testing to make sure the verified C and hand-written OCaml parsers agree. So far they seem to :-)
</p>

<p>
You can read more about it here: <a href="https://gazagnaire.org/blog/2026-03-31-ocaml-wire.html">https://gazagnaire.org/blog/2026-03-31-ocaml-wire.html</a>.
</p>

<p>
To try it: <code>opam install wire</code>
</p>

<p>
Feedback very welcome <a href="https://github.com/parsimoni-labs/ocaml-wire">on the issue tracker</a> (or bellow)!
</p>
</div>
</div>
</div>
<div id="outline-container-3" class="outline-2">
<h2 id="3">valkey: modern Valkey client for OCaml 5 + Eio, on opam</h2>
<div class="outline-text-2" id="text-3">
<p>
Archive: <a href="https://discuss.ocaml.org/t/ann-valkey-modern-valkey-client-for-ocaml-5-eio-on-opam/18010/1">https://discuss.ocaml.org/t/ann-valkey-modern-valkey-client-for-ocaml-5-eio-on-opam/18010/1</a>
</p>
</div>
<div id="outline-container-org64f9193" class="outline-3">
<h3 id="org64f9193">Avi Fenesh announced</h3>
<div class="outline-text-3" id="text-org64f9193">
<p>
Hi everyone,
</p>

<p>
I wanted to share that <code>valkey</code> 0.2.0 is now on opam:
</p>

<ul class="org-ul">
<li>opam: <a href="https://opam.ocaml.org/packages/valkey/valkey.0.2.0/">https://opam.ocaml.org/packages/valkey/valkey.0.2.0/</a></li>
<li>Repo and Getting Started: <a href="https://github.com/avifenesh/ocaml-valkey/blob/main/docs/getting-started.md">https://github.com/avifenesh/ocaml-valkey/blob/main/docs/getting-started.md</a></li>
</ul>

<p>
The main thing I wanted with this project was to focus on the current Valkey stack with the newer OCaml stack.
</p>

<p>
So <code>valkey</code> is built around:
</p>

<ul class="org-ul">
<li>OCaml 5</li>
<li>Eio-native direct-style concurrency</li>
<li>RESP3 only</li>
<li>Modern Valkey features and real cluster behavior</li>
</ul>

<p>
A few parts I'm happy with:
</p>

<ul class="org-ul">
<li>Cluster support with a strong focus on durability and high availability:
topology refresh, periodic background refresh, <code>MOVED</code> / <code>ASK</code> / <code>CLUSTERDOWN</code> handling, replica-aware reads, AZ-aware routing, and failover-aware sharded pub/sub replay</li>
<li>connection/runtime behavior:
circuit breaker, reconnect handling, keepalive, TLS, and optional separation between socket I/O and parsing via <code>Eio.Domain_manager</code>, so one side of the system does not block the other</li>
<li>batch support:
scatter-gather across slots, atomic single-slot flows with <code>WATCH</code> / <code>MULTI</code> / <code>EXEC</code>, multi-slot helpers, and in
<code>0.2.0</code> also WATCH guards for read-modify-write CAS plus cross-slot <code>pfcount_cluster</code></li>
<li>command surface:
typed helpers across a pretty broad set of commands, <code>Client.custom</code> /~custom_multi~ for custom commands and multi-node execution, and named commands so you can register command templates once and reuse them later</li>
<li>scripting:
local script caching and optimistic <code>EVALSHA</code> handling with automatic fallback/retry on <code>NOSCRIPT</code>, so callers don't need to manage that flow themselves</li>
</ul>

<p>
There is also already a pretty good amount of validation around it:
integration tests, property tests, fuzzing, chaos testing, examples, and guides.
</p>

<p>
Performance-wise, it also came out pretty nicely: in several scenarios it gets to 90%+ of the C reference client.
</p>

<pre class="example" id="org3bd3288">
opam update
opam install valkey eio_main
</pre>

<p>
Current next steps on the roadmap are things like:
</p>

<ul class="org-ul">
<li>client-side caching</li>
<li>connection pools / blocking pools</li>
<li><code>IAM</code> + <code>mTLS</code></li>
<li>Valkey module support (JSON, search, bloom)</li>
</ul>

<p>
If there's a feature people care about, I'd be very happy to reprioritize the roadmap around real interest.
</p>

<p>
I'd also really love feedback from the OCaml community on the API, ergonomics, docs, and general design.
</p>

<p>
I'm very familiar with the Valkey world, but OCaml is more of a side fun for me than my daily language, so feedback from people who really live in the OCaml ecosystem is especially valuable to me.
</p>

<p>
If you try it, I'd love to hear what you think.
</p>
</div>
</div>
</div>
<div id="outline-container-4" class="outline-2">
<h2 id="4">UnifiedScript_{Std,Top} - literate testing</h2>
<div class="outline-text-2" id="text-4">
<p>
Archive: <a href="https://discuss.ocaml.org/t/ann-unifiedscript-std-top-literate-testing/18013/1">https://discuss.ocaml.org/t/ann-unifiedscript-std-top-literate-testing/18013/1</a>
</p>
</div>
<div id="outline-container-org2dda97b" class="outline-3">
<h3 id="org2dda97b">jbeckford announced</h3>
<div class="outline-text-3" id="text-org2dda97b">
<p>
I am pleased to introduce the <code>UnifiedScript_Std</code> and <code>UnifiedScript_Top</code> packages. Unified scripts are a way to write tests and documentation simultaneously. Cram tests and <a href="https://github.com/realworldocaml/mdx">MDX scripts</a> are both similar to unified scripts, but unified scripts aren't tied to Markdown (MDX) or tied to POSIX shell commands (cram tests).
</p>

<p>
Examples:
</p>

<ul class="org-ul">
<li><i>Markdown example</i>: Here are the zillions of tests from <code>ocaml-re</code> converted into Markdown: <a href="https://github.com/jonahbeckford/ocaml-re/blob/7dbfc446bd594303add00f443bdea206b08511c2/EXAMPLES.md">ocaml-re/EXAMPLES.md</a>. Custom OCaml REPL printers are used so that many of the tests are printed as Markdown tables. <i>aside: Wouldn't it be nice if tests you are already writing became documentation? That was a 4 year follow-up to <a href="https://discuss.ocaml.org/t/what-are-the-biggest-reasons-newcomers-give-up-on-ocaml/10958/13?u=jbeckford">https://discuss.ocaml.org/t/what-are-the-biggest-reasons-newcomers-give-up-on-ocaml/10958/13?u=jbeckford</a></i></li>
<li><p>
<i><code>.ml</code> example</i>: The following is a snippet from <a href="https://gitlab.com/dkml/build-tools/MlFront/-/blob/374bbac77003cd8cee56f0664cec974aa314c648/src/UnifiedScript_Top/plainmodule.ml">a regular OCaml <code>.ml</code> module</a> where the <code>(* ... *)</code> comments are OCaml REPL toplevel responses maintained by the unified tools.
</p>
<div class="org-src-container">
<pre class="src src-ocaml"><code><span style="color: #242521; font-weight: bold;">let</span> <span style="color: #007a9f;">lyrics</span> =
  <span style="color: #ca3400;">"Everybody step to the left."</span>
  <span style="color: #8f6f4a; font-style: italic;">(* </span><span style="color: #8f6f4a; font-style: italic;">val lyrics : string = "Everybody step to the left."</span><span style="color: #8f6f4a; font-style: italic;"> *)</span><span style="color: #a7601f;">[@ocamlformat </span><span style="color: #ca3400;">"disable"</span><span style="color: #a7601f;">]</span>

<span style="color: #242521; font-weight: bold;">let</span> (<span style="color: #007a9f;">_</span> :<span style="color: #444fcf; font-weight: bold;"> string</span>) =
  <span style="color: #557400; font-weight: bold;">Printf.</span>sprintf <span style="color: #ca3400;">"Now let's sing: %s"</span> lyrics
  <span style="color: #8f6f4a; font-style: italic;">(* </span><span style="color: #8f6f4a; font-style: italic;">- : string = "Now let's sing: Everybody step to the left."</span><span style="color: #8f6f4a; font-style: italic;"> *)</span><span style="color: #a7601f;">[@ocamlformat </span><span style="color: #ca3400;">"disable"</span><span style="color: #a7601f;">]</span>
</code></pre>
</div></li>
</ul>

<p>
Docs are at <a href="https://github.com/diskuv/dk/blob/ffa130a1dbefcd134b0d15f112fd6d6c99dc0fc8/docs/UNIFIED_SCRIPTS.md">dk/docs/UNIFIED_SCRIPTS.md</a> (of course generated by the unified tools).
</p>

<p>
Install the tools with:
</p>

<pre class="example" id="orgfd8a8fc">
opam pin add UnifiedScript_Std https://gitlab.com/dkml/build-tools/MlFront/-/releases/permalink/latest/downloads/MlFront.tar.gz
opam pin add UnifiedScript_Top https://gitlab.com/dkml/build-tools/MlFront/-/releases/permalink/latest/downloads/MlFront.tar.gz
</pre>

<p>
After feedback I'll release them officially to opam. I would like feedback overall and also specifically on the <a href="https://github.com/jonahbeckford/ocaml-re/blob/make-literate-tests/.claude/skills/make-literate-tests/SKILL.md">agent skill that converts expect tests to unified tests</a>.
</p>
</div>
</div>
</div>
<div id="outline-container-5" class="outline-2">
<h2 id="5">openrouter_api: An OpenRouter client library</h2>
<div class="outline-text-2" id="text-5">
<p>
Archive: <a href="https://discuss.ocaml.org/t/ann-openrouter-api-an-openrouter-client-library/18016/1">https://discuss.ocaml.org/t/ann-openrouter-api-an-openrouter-client-library/18016/1</a>
</p>
</div>
<div id="outline-container-org7e22122" class="outline-3">
<h3 id="org7e22122">mt_caret announced</h3>
<div class="outline-text-3" id="text-org7e22122">
<p>
I'm happy to announce the first version (v0.0.1) of <code>openrouter_api</code>, a library for querying large language models via OpenRouter, a service which provides access to a variety of models under a unified API.
</p>

<ul class="org-ul">
<li>opam: <a href="https://opam.ocaml.org/packages/openrouter_api/">https://opam.ocaml.org/packages/openrouter_api/</a></li>
<li>GitHub: <a href="https://github.com/mt-caret/openrouter-ocaml">https://github.com/mt-caret/openrouter-ocaml</a></li>
<li>docs: <a href="https://mt-caret.github.io/openrouter-ocaml/openrouter_api/index.html">https://mt-caret.github.io/openrouter-ocaml/openrouter_api/index.html</a></li>
</ul>

<p>
I've been using this library in my personal projects whenever I want to integrate an AI model, and I've found it quite useful; I hope others will find it useful as well. Issues and contributions are welcome.
</p>
</div>
</div>
</div>
<div id="outline-container-6" class="outline-2">
<h2 id="6">Call for presentations: Caml in the Capital II</h2>
<div class="outline-text-2" id="text-6">
<p>
Archive: <a href="https://discuss.ocaml.org/t/call-for-presentations-caml-in-the-capital-ii/17959/2">https://discuss.ocaml.org/t/call-for-presentations-caml-in-the-capital-ii/17959/2</a>
</p>
</div>
<div id="outline-container-org94839a4" class="outline-3">
<h3 id="org94839a4">Continuing this thread, Sacha Ayoun announced</h3>
<div class="outline-text-3" id="text-org94839a4">
<p>
Date and location have been confirmed! June 3rd at the Jane Street office!!
I have updated the post.
</p>

<p>
We're still open for presentation proposals as well!
</p>
</div>
</div>
</div>
<div id="outline-container-org93d51c4" class="outline-2">
<h2 id="org93d51c4">Old CWN</h2>
<div class="outline-text-2" id="text-org93d51c4">
<p>
If you happen to miss a CWN, you can <a href="mailto:[email protected]">send me a message</a> and I'll mail it to you, or go take a look at <a href="https://alan.petitepomme.net/cwn/">the archive</a> or the <a href="https://alan.petitepomme.net/cwn/cwn.rss">RSS feed of the archives</a>.
</p>

<p>
If you also wish to receive it every week by mail, you may subscribe to the <a href="https://sympa.inria.fr/sympa/info/caml-list">caml-list</a>.
</p>

<div class="authorname" id="org1675bb0">
<p>
<a href="https://alan.petitepomme.net/">Alan Schmitt</a>
</p>

</div>
</div>
</div>
</div>
</body>
</html>


--==-=-=--

--=-=-=--

--===-=-=
Content-Type: application/pgp-signature; name="signature.asc"

-----BEGIN PGP SIGNATURE-----

iQFvBAEBCABZFiEE6lXof/BsSVW56ZmGBA0KO07S5ccFAmnwaOMbFIAAAAAABAAO
bWFudTIsMi41KzEuMTIsMCwzHxxhbGFuLnNjaG1pdHRAcG9seXRlY2huaXF1ZS5v
cmcACgkQBA0KO07S5ceJSAgArPiTJVJOPifsdgzYliZcHKecEs0QGt6p7C9dvgre
M/4TUajLXxIEDEjx6pIf1563OrqkeS9+ByIIaXUdpZfdKnIsZIyMiTOSSG8ywiSm
/iUprGb7/x3G0XBB6jMzpQmwmRZ/bN7tniqBswrMMMUQsMNStcx2uU/fNSxUR4Ux
jpn5yw50rF8Ly3vm/3OawZX/BBah+pC2OqDwxylibhXp1z0J9CnCJZeZWofh3kDE
Qh9y9Aqx0tOLJ3msnuS0NEuqpSOkvDko+VxksRJZS5ojkpkGiG8sDO8+MidE9MwI
e1Fm7J8tZLgu/ZqnV3Xe6w4AhfKDJOua/se05VsDJgha2Q==
=oFOc
-----END PGP SIGNATURE-----
--===-=-=--