From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Authentication-Results: plum.tunbury.org; dkim=pass (1024-bit key; unprotected) header.d=inria.fr header.i=@inria.fr header.a=rsa-sha256 header.s=dc header.b=kFefGPbd; dkim=fail reason="signature verification failed" (1024-bit key; secure) header.d=polytechnique.org header.i=@polytechnique.org header.a=rsa-sha256 header.s=svoboda header.b=oA5qyZx7; dkim-atps=neutral Received-SPF: Pass (mailfrom) identity=mailfrom; client-ip=192.134.164.83; helo=mail2-relais-roc.national.inria.fr; envelope-from=caml-list-owner@inria.fr; receiver=tunbury.org Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) (using TLSv1.2 with cipher ECDHE-ECDSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by plum.tunbury.org (Postfix) with ESMTPS id 20E58400B1 for ; Tue, 4 Nov 2025 13:21:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=inria.fr; s=dc; h=from:to:date:message-id:mime-version:subject:reply-to: sender:list-id:list-help:list-subscribe:list-unsubscribe: list-post:list-owner:list-archive; bh=76iAnkdpJgoC7wB+v97z1IlgNbos29VYSfzKT139thw=; b=kFefGPbd12Uimz3kLD8r4cwrZc+04eXCDLIWhHuRcndNJMiiOV/hji3R vOhky9uQgzCXNgHGzejK8stPfqAqsfT5M9Y3+TJZEIj6ZK1Q/A5014EOv pyLOubWdjFntmhyAEtcKMUgR9zbLRnruJ+FgoxSsI6SRxR2XJ8kuY6Iez M=; X-CSE-ConnectionGUID: 71zLTaXTSZeh/t3V7Noa2Q== X-CSE-MsgGUID: vcW21ieySB+MS3HvpWNiIQ== Received-SPF: Pass (mail2-relais-roc.national.inria.fr: domain of caml-list-owner@inria.fr designates 128.93.162.160 as permitted sender) identity=mailfrom; client-ip=128.93.162.160; receiver=mail2-relais-roc.national.inria.fr; envelope-from="caml-list-owner@inria.fr"; x-sender="caml-list-owner@inria.fr"; x-conformance=spf_only; x-record-type="v=spf1"; x-record-text="v=spf1 include:mailout.safebrands.com a:basic-mail.safebrands.com a:basic-mail01.safebrands.com a:basic-mail02.safebrands.com ip4:128.93.142.0/24 ip4:192.134.164.0/24 ip4:128.93.162.160 ip4:128.93.162.3 ip4:128.93.162.88 ip4:89.107.174.7 mx ~all" Received-SPF: None (mail2-relais-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@sympa.inria.fr) identity=helo; client-ip=128.93.162.160; receiver=mail2-relais-roc.national.inria.fr; envelope-from="caml-list-owner@inria.fr"; x-sender="postmaster@sympa.inria.fr"; x-conformance=spf_only Authentication-Results: mail2-relais-roc.national.inria.fr; spf=Pass smtp.mailfrom=caml-list-owner@inria.fr; spf=None smtp.helo=postmaster@sympa.inria.fr; dkim=hardfail (body hash did not verify [final]) header.i=@polytechnique.org X-IronPort-AV: E=Sophos;i="6.19,279,1754949600"; d="scan'208,217";a="247535886" Received: from prod-listesu18.inria.fr (HELO sympa.inria.fr) ([128.93.162.160]) by mail2-relais-roc.national.inria.fr with ESMTP; 04 Nov 2025 14:21:41 +0100 Received: by sympa.inria.fr (Postfix, from userid 20132) id CA9D6E0172; Tue, 4 Nov 2025 14:21:40 +0100 (CET) Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id C2B71E0172 for ; Tue, 4 Nov 2025 14:21:35 +0100 (CET) X-CSE-ConnectionGUID: hNabRk3dRT2I0VZEUb++2Q== X-CSE-MsgGUID: Hopsv11dT1aFJsHypWuD3w== IronPort-SDR: 6909fddd_oIXK9AoYye1x36c8dziC+Jnw4yHsCWMotKz2BwOIZN1zbM8 YcA21nr0bJSSe3FKsTJP5wUMLw6N3KAMEZLlphA== X-ThreatScanner-Verdict: Negative X-IPAS-Result: =?us-ascii?q?A0ESAQAx/AlpgSIeaIFaHQITCQMFBYIABQwBgTyBAxkBa?= =?us-ascii?q?F4zBwhJhFWDTwiOHJFNiEuCMIMVFiMVAQMBDS4BGwQBAgQBAQMBAgGCDIJ0A?= =?us-ascii?q?oxWAh8GAQQzBg4BAgQBAQEBAwIDAQEBAQEBAQEBDQEBBQEBAQIBAQIEBgECE?= =?us-ascii?q?AEBPQVJhk8NgkVRUx4UUQkGAQEBAQEBAQEBAQEBAQEiAQEBAQEBAQEBAQEBA?= =?us-ascii?q?QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQIEBAQBAgoNRUABAgYEB?= =?us-ascii?q?hMBATIGGCMDFAEGAwIRATUDARMBEhkBAYIjRYIgAgJPAwUMBpVIm0x6fzOBA?= =?us-ascii?q?YIMAQEGgQg+AgELAgIDAQ4JJQHaDIFkCYEyGAGFbIJKGgEFJUlrAoRHCYMVg?= =?us-ascii?q?R8IHw+BVUSBFTWCRG+CAj0LFwIBAYE5AwEBCEUJgyWCaYIRFXoUHYYKeIEwg?= =?us-ascii?q?X8GhlYGh1OBREszLAFVExcLBwVbgQgDKjQtbjIdgSRBGHGBFINJDxJoDwaBE?= =?us-ascii?q?oNRiSYPiTsDC209NxQblC9CGSyBbhUOCy0CAwEXGwwPBw0BAgQUBA8BCgoHD?= =?us-ascii?q?gIiKwECCAUJChUTAgEZDgECCAQJBQYDEAUGCxkFBgsCCQItA5JXCRsBAwQoA?= =?us-ascii?q?XSSO4pCk3ZtNAeEH4FeBgyJCIEmhyaOYIQEgVeFQIV8hwKRa2cimGQigjaGJ?= =?us-ascii?q?4EAClNEBQmCDkyVJBACJAYEBIVRgX4kSWIBGgMMBzMaMCIhgjMBMwlGHA+II?= =?us-ascii?q?YYJAxaDNigQgS6BJoF0O33FU0I1AQEBATgCBwEKAQEDCYViAQGMCC0FgUsBA?= =?us-ascii?q?Q?= IronPort-PHdr: A9a23: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 nkFWYJEyHfeDIkf1Q1jZ/RzzGg= IronPort-Data: A9a23:Er/RvK54ZpPzIDR8ZnhZ7gxRtO7DchMFZxGqfqrLsTDasY5as4F+v mMfXWrVa/rZMTfweognOti290hVv8KGzoI3HAE/+CwxZn8b8sCt6faxfh6hZXvKRiHgZBs6t JtGMoGowOQcFCK0SsKFa+C5xZVE/fjVAOe6UaicZ30ZqTZMEE8JkQhkl/MynrlmiN24BxLlk d7pqqUzAnf8s9JPGjxSsvPrRC9H5qyo5WpB5gBmP5ingXeH/5UrJMJHTU2OByCgKmVkNrbSb /rOyri/4lTY838FYvu5kqz2e1E9WbXbOw6DkBJ+A8BOVTAfzsCa+v9T2Ms0MS+7uR3R9zxC4 IklWaiLdOscFvakdNLx/PVvO3oW0aVuoNcrKJUk2CCZ5xWun3DEm52CAKyqVGGxFyke7Wxmr JQlxD4xgh+rh8S/yoi4EeVWup4CdPfZEb4V+TI69GSMZRomacirr6Ti4M8Bmi83gtFSEP3eY csAdDcpaw7PC/FNEg5NWdRnxLvu3SG5KGEwRFG9/cLb50Do9jcphanPHNuAJ/nfXcJRj1qVr WLA/n3kD1cdLtPKwD6M9DS3je/KnD/ncIgVCbuz++UshQGDgGsJB3X6UHPh/abk0RPgAYI3x 0o82i02trZrrUCXF9DTfQaYsWa7ozJHRI8FewE9wFrQlvSPvF7x6nI/ZjVIbdhjsM4tWRQxx 1qRlpXoAyZuufubUxqgGqy8qCPrfzASKX4eaCQESwoc/tSlp5s85v7Scjp9OK6Th9fPGmr8+ QzQjXAAtZguh41IjZzuqDgrnAmQSo71ohkdyD+/Y45IxgZpPci9YIi59VXQ7fBBNZuUCF6bs xDoevRyDshQUvlhdwTUH43h+Y1FAd7eaVUwZnY0RPEcG8yFoSLLQGypyGgWyL1V3jk4lc/BO xKP51gOvPe/zVOnZqhzbsqpDMA70aXrFdLkT+3ZJtdWeZNpHDK6ENVVTRfIhQjFyRF0+YlmY MfzTCpZJSxLYUiR5GDnH79FuVLqrwhirV7uqWfTlUX5juHDPSPIGd/o8jKmN4gE0U9Nmy2Nm /43CidA408OOAEnSniGqdwgPhoRIGIlBJv7jcVSe6TRakBlAWwtQbuZi78oZ4Uvzewfm/bq7 0ONfBZS6GP+onnbdiSMSHRoM430UbhF8HkUAC0LPHST4UYFX7qB1qklSsYITeEVz9A7lf9QZ NsZSvqEGcVKG2jm+SxCTJzTr75CVRWMhCCPNXGbfQllQYxEQlSR9/S5YADq/ygqJQi0vPsYv LeP+F76Q50CZgI6F+fQSqul4G2QtEgnutBZfhX3MPgKX2u066lsCSj6rsFvEvE2MR+Zmwerj VeHMykXtczmgtET8uCQoYumso3wMe91PnQCLlnh9bzsaBXrpDuy87RhDtSNUyvWDl7v2aOYY u5Q8fHwHdsHkHtOsKt+C7xb9r0/1fS+u45lyhlYI1uTY2SJEr9AJly07ftLvIBJxZ5bvlKSc WCL8d94J76IGZ3EFHg8GQkbVdmAhMokwmTq0fcIIUvB9HBW+piDWh5sJBWisnFWA4Z0F4IH+ t0fnvAqxTaxsTcQCebevBtorzyNClciT5QYsoorBd63qwgzlXBHT5/uKg73x5CtdN8WIhQmD QGWjYWfn79s+E7mdisiJ2nsxstYv4wF4zpR/W8BJnOIu9vLveA21xtv6gYKThxZ4xFE8uBrM E1pChFFHrqP9DJWm8RzZWCgNAVfDhm/+Eaq6V82uEDGbkuvDErhEXYcPLuTwUUn7G5sRDhX0 7WGwmLDUzyxXsXQ3DM3aHF1uc7YUt192Q3Tqv+JR/3fMcEBXgPkpauyaU4jiRjtW5oxjXKag 9haxr97bKmjOBMAp6E+NZKh6o0RbxK5P01Hf+Bq+fIYPGPbeQzq4wO0FWKKRppvKcDJoGiCM O4/AuJUVh+76jSCkSBDO44IPI1PvaAI4PgsR+rVAFAo4pqlkypRkZPP9yLBqnchbPdwnO0cd I7AVTKwPVaBpHlTmmX9o9lgPECma/kAPD/D+ue/9eEZG60+res3U0cT06S1jVqRIgBI7xKZh yKdRq70nshJ65VgoJvoKYpHXz6LENLUUP+a1SyOqPFMUI//CtjPvAYrtVXXBQRaEr8PUdBRl 77WktrI8G7anbQxCUb1poKgEvRX2MCMQ+ZnCML7A31Ely+kWsW3wR8i+Xi9GKNZguFm+cira AupWvSeLedPdY9m+0RUTCxCHzI2Kaf9NP7grBzgicW8MEEW1AifIe638XPsU3pgSRYJHJ/DE S7xheel44FJjYZLBSJcPcpcPb1DHAbBV5clJvrLjhvJPlnw1xnG8vHnmAE74D7GNmicHYyoq djZTxz5b1KptLuO0NhdtJdoswYKCGpmx9M9ZV8Z58U8ngXS4LTq9gjBGc5u5lBofi3OOFXQY SGUKnMlDTThUD9EdxTl/dmlWR2QbgDLEsmsPSQnpit4dA/vbL5swpM4nsuj35uyUjHk0eesJ MpY/yHgeB+rzfmFgM4Ns+ejj74PKuzynxo1FIOUryA2Kw4ZBaQW2XdhGgtUSCGBFNvC/KkOy a7ZWkgcKHyGpYXN/QqMtpKb9Nz1fN8i8tnwURqy/Q== IronPort-HdrOrdr: A9a23:njGBw690rMIXPfa5UzNuk+DlI+orL9Y04lQ7vn2ZKCYlEfBw8v rFoB1173HJYVoqNU3I+urhBEDjexLhHPdOiOF7AV7IZmbbUQWTQL1K3M/L/HnLGiH19OJRvJ 0QEZRWOZnXFlY/qc775WCDYrIdKTS8gcWVuds= X-Talos-CUID: 9a23:uYEEIG718UHp01ZYZtss9GgdEPomKXHn8C3xe3GKJFtjC/7PcArF X-Talos-MUID: =?us-ascii?q?9a23=3ArwY1AAyzk+vRPwPrnowjj8Zt1iyaqISpEFsTyMw?= =?us-ascii?q?Kh5CNGw5rGyaFsymbGZByfw=3D=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="6.19,279,1754949600"; d="scan'208,217";a="247535628" X-URL-ContentFilter: X-MGA-submission: =?us-ascii?q?MDFWBnOtFGGGdHTu4Deb6kb368Kr3/sCY5tGtT?= =?us-ascii?q?X1qnHlP5HArV/1JAtAEL086PmqsdeD9vbilY4AnifWaliMZxPQK0tHUo?= =?us-ascii?q?NA9CIL1GpL5NGvzhDVn0UnqbkBay3OqTeISZtXG+S8V9qrv6wvaY0P9g?= =?us-ascii?q?WNsiNTAIAGvO3G/BQ4EgDRkA=3D=3D?= Received: from mx1.polytechnique.org ([129.104.30.34]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 04 Nov 2025 14:21:33 +0100 Received: from mac-03220211.irisa.fr (mac-03220211.irisa.fr [131.254.21.249]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ssl.polytechnique.org (Postfix) with ESMTPSA id 3BF521A318; Tue, 4 Nov 2025 14:21:32 +0100 (CET) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=polytechnique.org; s=svoboda; t=1762262492; bh=hNMrlebsWOZ5Q3lG2LsPBk0JH93u/IACSwCWWbyJHdw=; h=From:To:Subject:Date:Message-ID; b=oA5qyZx75/utNmyZdBeLdLO0Ki11cx+Ue+Ku/0mSs8xKqOnbCFmKM7q5Htr7xp9Bg 7sHOJXqxWUeB2qfhCE7Om/0/jP/knzwTsSCDKuzJHJ41+fy0/1afrJegria12ywFgW vBetuQaAjBjkdhTXVvFtTurJAdqEMvEsWc9HYWn0= From: Alan Schmitt To: "lwn" , caml-list@inria.fr Date: Tue, 04 Nov 2025 14:21:30 +0100 Message-ID: MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-=-=" X-AV-Checked: ClamAV using ClamSMTP at svoboda.polytechnique.org (Tue Nov 4 14:21:32 2025 +0100 (CET)) X-Spam-Flag: Unsure, tests=bogofilter, spamicity=0.498289, queueID=5D3801A379 X-Org-Mail: alan.schmitt.1995@polytechnique.org Subject: [Caml-list] Attn: Development Editor, Latest OCaml Weekly News Reply-To: Alan Schmitt X-Loop: caml-list@inria.fr X-Sequence: 19399 Errors-To: caml-list-owner@inria.fr Precedence: list Precedence: bulk Sender: caml-list-request@inria.fr X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello Here is the latest OCaml Weekly News, for the week of October 28 to November 04, 2025. Table of Contents =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80 Caml in the Capital Ppxlib: Support for future compilers Miou, a simple scheduler for OCaml 5 Cmarkit 0.4.0 - CommonMark parser and renderer for OCaml OCaml library for Timeplus Proton timeseries streaming database Book draft: "Control structures in programming languages" oplot 0.85 - mathematical plotter QCheck 0.27 Bytesrw 0.3.0 =E2=80=93 The cryptographic edition Other OCaml News Old CWN Caml in the Capital =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90 Archive: Alistair O'Brien announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80 Hi everyone =F0=9F=91=8B We (@giltho and myself) are happy to announce the first OCaml meetup in London (Caml in the Capital)! Think of it as the British cousin of OCaml Users Meetup in Paris (OUPS). What? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C Caml in the Capital is an informal evening of talks, demos, and hacking from anyone working with or interested in OCaml. The goal is to create a friendly local space for sharing ideas, showing off projects, and connecting with other OCaml developers in the UK. When? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C We=E2=80=99re aiming for February 2026. Please fill out this short poll to help us pick a date: =F0=9F=91=89 [Doodle poll link] Options: Thu 5th Feb, Thu 12th Feb, Thu 19th Feb, Thu 26th Feb The meetup will take place in central London (venue TBA =E2=80=94 likely Imperial College), starting around 6:30pm and running until 8:30pm, with informal drinks and discussions afterwards. [Doodle poll link] What=E2=80=99s the `Fmt'? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C A mix of: =E2=80=A2 Workshop-style talks =E2=80=93 anything from an accessible intr= oduction of your work or research, a deep dive into your library, a live demo, or a tutorial. =E2=80=A2 Hacking / discussions Call for presentations? =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C If you=E2=80=99d like to give a talk, please message me or @giltho direct= ly with: =E2=80=A2 A title and short abstract =E2=80=A2 Expected time slot Once we confirm the first date, we=E2=80=99ll: =E2=80=A2 Confirm the programme and publish a new forum post =E2=80=A2 Setup website, a Zulip channel, and a Meetup page for registrat= ion Looking forward to meeting more OCaml users in person! =E2=80=93 Alistair & Sacha Ppxlib: Support for future compilers =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90 Archive: Nathan Rebours announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 *Handling future AST changes in ppxlib* The OCaml 5.2 compiler release has introduced changes in core parts of the AST types. Reflecting those changes when we bumped the internal AST used by ppxlib in [0.36.0] caused breakage in a lot of reverse dependencies. Despite [our efforts to keep the ecosystem up to date], it has lead to a split in the opam universe between packages that are compatible with 0.36.0 and above and those that aren't. Looking at the 5.3 and 5.4 AST changes, we cannot reasonably keep the same ["update the universe" approach] going forward I would like to propose a slightly different but much more stable and sustainable approach. I think it's important to have a bit of context on why ppxlib is designed the way it is and how we've been handling new compiler releases over the past few years to understand this new approach and how it's going to improve the situation. The next section of this post will summarize this. If you're already familiar with ppxlib's history and design choices, please skip ahead to the [Proposed Approach section](#proposed-approach-for-53-onward). [0.36.0] [our efforts to keep the ecosystem up to date] ["update the universe" approach] Ppxlib and compiler releases: How it works today =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C= =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C =E2=97=8A Ppxlib internal AST Before ppxlib there was [ocaml-migrate-parsetree]. OMP had the advantage of providing a stable API for ppx authors. Each ppx would select a fixed version of the AST and be implemented as a full AST rewrite, i.e. a `structure -> structure' or `signature -> signature' function. This had the advantage of making ppx-es forward compatible as omp maintainers would add support for new compiler releases in the form of a new module containing the AST types for this version and migration functions to convert to/from the types matching the previous compiler version. OMP also came with a ppx driver, i.e. a program in charge of applying a set of ppx-es on a given AST or source file and spit out the final preprocessed AST for the compiler. The driver was responsible for migrating the AST from the compiler's version to the one used by a ppx. Because each ppx could require a different AST version, it also potentially had to migrate the AST transformed by a ppx before it passing it on to the next one. This had a few disadvantages though: 1. poor performance as the AST was traversed and migrated (i.e. copied) several times through the course of a single driver run. 2. transformations semantic issues: the order in which ppx-es were applied was uncertain or rather tied to the set of ppx-es version used. That meant that updating one ppx could change its "turn" and result in a different AST returned by the driver. This also did not allow ppx-es to interact together reliably. ppxlib aimed at fixing those issues by forcing ppx-es to agree on the AST version to use. ppxlib provides its own, fixed AST version that ppx-es have to use. Its driver handles the migration to/from the current compiler and provides a smooth API to write transformations as rewriting rules. The driver then handles the AST rewrite by recursively applying those rules in the right places in a single AST traversal. [ocaml-migrate-parsetree] =E2=97=8A Support for new compilers Support for new compilers comes in two stages. =E2=97=8A Build and preprocess old code with new compiler This is the most basic support, that is making sure that one can still build and preprocess its code using the newest compiler, provided they don't use any of the new language features. To do this, we add the new AST types and migration functions, just as OMP used to do. This does not allow new features in the code because those cannot be represented with the old AST types and the migration would fail (*This was also an existing limitation of OMP*). This is usually released early on, when the compiler is still in beta and is a non breaking change, all reverse dependencies still build with this new version. =E2=97=8A Support new language features To support new language features, we bump the AST used by ppxlib. This means new features don't have to be migrated anymore and are therefore supported. This does change types that are exposed as part of ppxlib's API and can cause breakage in reverse dependencies, depending on which part of the AST were modified and which part each individual ppx uses explicitly. We provide tools that can help make ppx code more robust as they allow matching over and producing AST nodes without explicitly referencing the types themselves: `metaquot', `Ast_builder' or `Ast_pattern' for instance. That's not always enough though and eventually, those ppx-es have to be updated to be compatible with the latest version of ppxlib. As was the case for the 5.2 AST bump, when we release such a ppxlib version, we send PRs to help maintainers of our opam reverse dependencies update and carefully add upper bounds to the versions that aren't compatible anymore. This worked pretty well for a few years as the AST was relatively stable and the parts that were modified were not directly used by a lot of ppx-es. A problem with this approach is that even though we can help maintainers go through the update, we cannot release packages in their stead which means that unmaintained ppx-es aren't compatible anymore no matter how much effort we put into easing the upgrade. It is also often the case that not all ppx-es have a compatible release straight away and this results in a transition period with the opam universe split mentioned in the introduction. Proposed approach for 5.3 onward =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C= =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C The first part of this plan is to freeze ppxlib's internal AST for each major versions. That means that until we release ppxlib.1.0.0 our internal AST will always be the 5.2 AST. The second and most important part is to provide complete forward compatibility despite the AST freeze. We will allow migrating new features down to our AST by encoding them inside specific language extensions and migrating them back to their original form before returning the preprocessed AST to the compiler. This will allow existing ppx-es to be used with new compilers AND to be used in the same files as new language features as long as they don't have to directly interact with them without being updated in any way. We will also provide a stable API to allow ppx-es that would like to add special support for these new features to build and match over such nodes. You can take a look at the examples below to get an idea of what that would look like for recent language features such as the [effect syntax](#effect-syntax-example) from OCaml 5.3 or the [bivariance annotation](#bivariant-type-parameter-example) from OCaml 5.4. As part of these changes, we will deprecate ppxlib's copy of `Ast_helper' in favor of `Ast_builder', aiming to remove `Ast_helper' entirely in 1.0.0. We have been maintaining two distinct modules for quite a while now. `Ast_helper' also has a tendency to encourage its users to generate all their code with `Location.none' as their location which makes the life of their users a bit hard when they have to interpret compiler errors. This can be seen as a middle ground between the approach proposed [here] 6 years ago (/that we gave up on due to its complexity/) and the current situation. [here] =E2=97=8A Limitations Encoding new features into extension points is not always easy, only specific parts of the AST can be replaced by an extension point. To keep things under control and prevent ppx-es from generating inconsistent nodes, all new features will always be migrated into an extension point. That means that if the impacted node cannot directly be encoded that way, we will encode the first suitable parent node. In some scenarios, that can climb up the AST types quite significantly, potentially all the way to the `structure_item~/~signature_item'. This means that new features won't be equal when it comes to how easy it is to use them in conjunction with some ppx-es. It's important to keep in mind that this is still a net improvement as it was previously not possible to use them together at all. Similarly, providing a nice API to allow building and destructing encoded new features will vastly depend on the features themselves and how entangled they are with new AST types. We will likely not always expose such builder/destructor pairs and might only add some of them if the demand is high enough. It is also part of the reason why we will probably still bump our AST at some points in time even if much less frequently than we have in the past. When that eventually happens, we will be able to maintain the previous major versions for quite a while as this will just be a matter of adding our newest migrations there as well. =E2=97=8A Effect syntax example OCaml 5.3 introduced the following syntax: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 match f () with =E2=94=82 | v -> Complete v =E2=94=82 | effect (Xchg msg), k -> =E2=94=82 ... =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 This special effect pattern is represented in the 5.3 AST with the `Ppat_effect' variant: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 | Ppat_effect of pattern * pattern =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 We cannot represent this in the 5.2 AST and previously, any attempt at migrating such a node down would have failed. With this new approach we instead migrate it to something along those lines: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 [%ppxlib.migration.ppat_effect? (Xchg msg, k)] =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 and the upward migration knows to translate this to the right `Ppat_effect' node. This migration needs to work without context outside the extension so that any ppx that would unknowingly copy such a node elsewhere in the AST would not cause an uninterpreted extension error later on during the compilation. If this is passed down to an existing ppx as part of its payload and it tries to interpret it, it should fail as it won't know what to do with such an extension. *Note that ppx authors should never rely on the actual extension point encoding, we reserve ourselves the right to change that encoding as part of minor or patch releases of ppxlib. Such nodes should be left untouched or dealt with using the stable API described below.* Now if a ppx author needs to add explicit support for effects they will be able to use something like: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 val ppat_effect : loc: location -> pattern -> pattern -> pattern =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 from `Ast_builder' to generate such a node. Of course if your ppx generates an `effect' pattern with an older compiler, this will lead to a compile error as the extension won't be translated unless migrated back up. Authors will have to be mindful of this and properly document when/how they'll generate newer nodes and eventually restrict their ppx to the right range of compilers. These will likely come with a "destruct" version in `Ast_pattern'. For the `effect' pattern it should look like: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 val ppat_effect : (pattern * pattern, 'a, 'b) t -> (pattern, 'a= , 'b) t =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=97=8A Bivariant type parameter example This example is probably a bit of a stretch as it is a very niche syntax change and is highly unlikely to actually be used in the wild, but it makes a good example of a feature that is hard to encode. In OCaml 5.4, a new variant was added to the `Asttypes.variance' type: `Bivariant'. The `variance' type is used in the AST to describe how a type parameter behaves relative to the type itself. This can be manually annotated for each parameter when writing a type declaration or a class. The `Bivariant' case is a bit of a special one as a parameter can only be `Bivariant' (i.e. covariant AND contravariant) with the type if it does not actually appear in the concrete type definition, that is in cases such as: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 type 'a t =3D A =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 For reasons that we won't expand upon here, 5.4 introduced the following syntax to allow one to explicit annotate a parameter as bivariant: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 type +-'a t =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 The problem is that the variance cannot be replaced directly by an extension point, see the type `type_declaration' for instance: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 and type_declaration =3D =E2=94=82 { =E2=94=82 ptype_name: string loc; =E2=94=82 ptype_params: (core_type * (variance * injectivity)) list; =E2=94=82 ^^^^^^^^ =E2=94=82 (** [('a1,...'an) t] *) =E2=94=82 ptype_cstrs: (core_type * core_type * Location.t) list; =E2=94=82 (** [... constraint T1=3DT1' ... constraint Tn=3DTn'] *) =E2=94=82 ptype_kind: type_kind; =E2=94=82 ptype_private: private_flag; (** for [=3D private ...] *) =E2=94=82 ptype_manifest: core_type option; (** represents [=3D T] = *) =E2=94=82 ptype_attributes: attributes; (** [... [\@\@id1] [\@\@id2= ]] *) =E2=94=82 ptype_loc: Location.t; =E2=94=82 } =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 In this example we have to encode the entire parent node of the type declaration as an extension point. This means that it spreads in quite a few places, `type_declaration' can be found in `structure_items', `signature_items' and inside some `module_type' nodes as well. Given there's very little to no use for this syntax, we won't be providing any function to build or destruct such nodes initially. Miou, a simple scheduler for OCaml 5 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90 Archive: Calascibetta Romain announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80 I am delighted to announce the release of Miou version 0.5.0. This release now uses `poll(2)~/~ppoll(2)' instead of `select(3P)' in order to improve I/O management performance. Since I/O management is decoupled from the scheduler, this does not change the Miou API or the `miou.unix' library. I would particularly like to thank @backtracking for allowing us to integrate part of his [bitv] library under a different licence, as well as @haesbaert, the original author of [ocaml-iomux], for allowing us to use `poll(2)~/~ppoll(2)'. This has allowed us to go further, particularly with [vif], our web framework for OCaml 5, and our website [builder-web] has been completely rewritten to move to OCaml 5 (thanks to @reynir and @yomimono who participated in this rewrite and provided important feedbacks). This release comes with a new package, [flux] (still experimental), offering streaming abstractions that can be used with Miou. I would like to thank @rizo for his sketch [streaming] in this regard (pre-OCaml 5). This library takes advantage of the parallelism offered by Miou (with `Miou.call') as well as resource management and finalisers (with `Miou.Ownership'). A tutorial is available [here] to create a tiny `curl' with a loading bar. Finally, we are continuing to lay the groundwork for the development of unikernels with [mkernel]. We are currently experimenting with three unikernels: =E2=80=A2 [immuable], which reuses Vif to create websites in OCaml 5 in t= he form of unikernels =E2=80=A2 [chaos] (still at a very experimental stage), which aims to be = an NTP server =E2=80=A2 [dns-resolver], which is a DNS query resolver in the form of a unikernel Finally, we would also like to thank everyone who has been involved in the development of Miou and its related ecosystem, whether directly or indirectly. Happy hacking! [bitv] [ocaml-iomux] [vif] [builder-web] [flux] [streaming] [here] [mkernel] [immuable] [chaos] [dns-resolver] Cmarkit 0.4.0 - CommonMark parser and renderer for OCaml =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Daniel B=C3=BCnzli announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Hello, It's my pleasure to announce a new release of [cmarkit], an ISC-licensed CommonMark parser and renderer for OCaml. This release provides support for the latest version of the CommonMark specification, updated data for Unicode 17.0.0, a notable semantic change in the task item extension (thanks to @samoht) and a couple of bug fixes and improvements mostly in the CommonMark renderer. All the details are in the [release notes]. Thanks to everyone who reported issues. This release is brought to you by essential funding from the [OCaml software foundation] and my [donors]. =E2=80=A2 Homepage: =E2=80=A2 Docs: (or `odig doc cmarkit`) =E2=80=A2 Install: `opam install cmarkit` ([opam PR]) =E2=80=94 P.S. I'm surprised by the number of users (or rather, dissatisfied users :=E2=80=93) of the CommonMark renderer. If you are using it don't hesitate to tell how/why you are using it in this thread, just curious :=E2=80=93) [cmarkit] [release notes] [OCaml software foundation] [donors] [opam PR] OCaml library for Timeplus Proton timeseries streaming database =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Michael Freeman announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 A high-performance, feature-rich OCaml driver for [Timeplus Proton] - the streaming database built on ClickHouse. [Timeplus Proton] *Features* =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C =E2=80=A2 *Streaming Queries* - Process large datasets with constant memo= ry usage =E2=80=A2 *Async Inserts* - High-throughput data ingestion with automatic batching =E2=80=A2 *Compression* - LZ4 and ZSTD support for reduced network overhe= ad =E2=80=A2 *TLS Security* - Secure connections with certificate validation =E2=80=A2 *Connection Pooling* - Efficient resource management for high-concurrency applications =E2=80=A2 *Rich Data Types* - Full support for ClickHouse types including Arrays, Maps, Enums, DateTime64 =E2=80=A2 *Idiomatic OCaml* - Functional API leveraging OCaml's strengths Book draft: "Control structures in programming languages" =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Xavier Leroy announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 I am happy to announce that a draft of my upcoming book "Control structures in programming languages: from goto to algebraic effects" is now available at [https://xavierleroy.org/control-structures] . The book compares several programming languages from the standpoint of control structures. OCaml is used intensively to discuss control in functional programming, including continuation-passing style, control operators, exceptions, user-defined effects and effect handlers, with many examples that I hope you'll like. The book also discusses in depth a number of questions that are often raised in this forum, such as the theory and practice of algebraic effects and handlers, and the static checking of exceptions and effects. Enjoy! [https://xavierleroy.org/control-structures] oplot 0.85 - mathematical plotter =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: sanette announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80 Hello I=E2=80=99m happy to announce a new version of [oplot], a library for plo= tting mathematical functions, using openGL by default for fast rendering and animations, but also providing high quality vector graphics exports. This version has a new feature that math lovers will appreciate: `implicit_curve' plotting! For instance do you want to know what the solutions to the equation (x=C2=B2+y=C2=B2-1)=C2=B3 - x=C2=B2 y=C2=B3 =3D 0 look like? Here is the result: If you already dug into the problem of plotting implicit curves you know that it=E2=80=99s sometimes very difficult to localize in advance the various singularities of the curve. `oplot' gives you 3 ways of tuning the computation: grid size, recursive grid size for subsampling where the curvature of the curve seems high, and control over the iterations of the Newton method. There is also a pole detection, where the function changes sign but probably still doesn=E2=80=99t have a zero there. You can obtain debug information for any curve, for instance here you see the default parameters automatically detected for the above curve: initial grid (green) and subsampling (cyan): `oplot' is available in opam, doc is [here]. [oplot] [here] QCheck 0.27 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90 Archive: Jan Midtgaard announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 QCheck 0.27 is now available from the opam repository :partying_face: The 0.27 release is focused on improving the `float' shrinking support and also contains a small patch to make the package compile with OxCaml: =E2=80=A2 Add `QCheck.Shrink.float' and enable shrinking for `QCheck.floa= t' =E2=80=A2 Add `QCheck.Shrink.float_bound' and enable shrinking for `QCheck.float_bound_inclusive' and `QCheck.float_bound_exclusive' =E2=80=A2 Add `QCheck.Shrink.float_range' and enable shrinking for `QCheck.float_range' =E2=80=A2 Enable shrinking for `QCheck.{pos_float,neg_float,exponential}' =E2=80=A2 Patch `QCheck.Print.float' and `QCheck2.Print.float' to print negative nans consistently as "-nan" also on Windows and macOS, and correct documentation for `QCheck.{float,pos_float,neg_float}' in that they may produce ~nan~s since #350 from 0.26 =E2=80=A2 Eta-expand a couple of partial application to compile under OxC= aml Happy testing! :smiley: Bytesrw 0.3.0 =E2=80=93 The cryptographic edition =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Daniel B=C3=BCnzli announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Hello, It's my pleasure to announce a new release of the [bytesrw] set of ISC licensed libraries. Bytesrw extends the OCaml Bytes module with composable, memory efficient, byte stream readers and writers compatible with effect-based concurrency. Optional support for compressed, hashed and encrypted bytes depend, at your wish, on the C `zlib', `libzstd', `blake3', `libmd', `xxhash' and `mbedtls' libraries. This release adds optional libraries to support for `SHA-3' hashes, cryptographically secure pseudo-random bytes streams, TLS encrypted byte stream and low-level support for cryptographic operations on slices: =E2=80=A2 [`Bytesrw_sysrandom'] provides pseudorandom byte streams and en= tropy directly sourced from your operating system primitives. =E2=80=A2 [`Bytesrw_crypto.Psa'] provides low-level cryptographic operati= ons on byte slices via thin and safe bindings to the [TF-PSA-Crypto] C library distributed with Mbed TLS. This library is an implementation of the [PSA Crypto API Specification]. Its design is particularly suited if you care about key materiel not being seen by the OCaml GC (implementations also allow further degrees of isolation as can be read in the API's [design goals]). Besides the API is nicely and thoroughly documented. It is quite bureaucratic to use but that's what you likely want from a cryptographic library (e.g. key usages have to be declared upfront and are checked at runtime by cryptographic operations). =E2=80=A2 [`Bytesrw_crypto'] (will) provides a few higher-level operations implemented over PSA. The module is rather shallow at the moment, more will be added in the future as we abstract over our usage of PSA Crypto. For now it mostly contains an API to access the hashes provided by PSA Crypto in the way other `bytesrw' hashing modules expose their hashing service. This notably provides the `SHA-3' family of hashes which were not previously available in the set of optional `bytesrw' libraries. =E2=80=A2 [`Bytesrw_tls'] provides support for TLS encrypted streams and = the needed X.509 certificate management (including system lookups for trusted CAs). The backend is provided by the [Mbed TLS] C library. For now these streams are instantied over blocking fds, but this restriction will be lifted in the future. I also added a little tool called `certown' which you may find handy for dealing with certificates for localhost when you develop servers. Note that the binding to PSA cryptography has been used to implement a few things (e.g. the horrific passkeys specification) but has not run in production yet. However the binding is pleasantly unsophisticated, the underlying C API is straightforward to bind to. See the [release notes] for details about other changes. This release was made possible thanks to a grant from the [OCaml software foundation] and to my [donors]. =E2=80=A2 Homepage: =E2=80=A2 Docs: (or `odig doc bytesrw') =E2=80=A2 Install: `opam install bytesrw conf-=E2=80=A6' ([opam pr]) =E2=80=94 P.S. Libraries that depend on Mbed TLS need the recent 4.0.0 version which is quite fresh and may take a bit of time to trickle in system package managers. If you trust me you can use my [distribution crutch] opam repository to install it. [bytesrw] [`Bytesrw_sysrandom'] [`Bytesrw_crypto.Psa'] [TF-PSA-Crypto] [PSA Crypto API Specification] [design goals] [`Bytesrw_crypto'] [`Bytesrw_tls'] [Mbed TLS] [release notes] [OCaml software foundation] [donors] [opam pr] [distribution crutch] Other OCaml News =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 >>From the ocaml.org blog =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Here are links from many OCaml blogs aggregated at [the ocaml.org blog]. =E2=80=A2 [Supporting OCurrent: FLOSS/Fund Backs Maintenance for OCaml's Native CI Framework] =E2=80=A2 [WebAuthn & Passkeys in OCaml: Implementing Passwordless Authentication] [the ocaml.org blog] [Supporting OCurrent: FLOSS/Fund Backs Maintenance for OCaml's Native CI Framework] [WebAuthn & Passkeys in OCaml: Implementing Passwordless Authentication] Old CWN =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 If you happen to miss a CWN, you can [send me a message] and I'll mail it to you, or go take a look at [the archive] or the [RSS feed of the archives]. If you also wish to receive it every week by mail, you may subscribe to the [caml-list]. [Alan Schmitt] [send me a message] [the archive] [RSS feed of the archives] [caml-list] [Alan Schmitt] --=-=-= Content-Type: text/html; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable OCaml Weekly News

OCaml Weekly News

Previous Week<= /a> Up Next Week

Hello

Here is the latest OCaml Weekly News, for the week of October 28 to Novembe= r 04, 2025.

Caml in the Capital

Alistair O'Brien announced

Hi everyone =F0=9F=91=8B

We (@giltho and myself) are happy to announce the first OCaml meetup in Lon= don (Caml in the Capital)! Think of it as the British cousin of OCaml Users= Meetup in Paris (OUPS).

What?

Caml in the Capital is an informal evening of talks, demos, and hacking fro= m anyone working with or interested in OCaml. The goal is to create a frien= dly local space for sharing ideas, showing off projects, and connecting wit= h other OCaml developers in the UK.

When?

We=E2=80=99re aiming for February 2026. Please fill out this short poll to = help us pick a date:

=F0=9F=91=89 Doodle poll link

Options: Thu 5th Feb, Thu 12th Feb, Thu 19th Feb, Thu 26th Feb

The meetup will take place in central London (venue TBA =E2=80=94 likely Im= perial College), starting around 6:30pm and running until 8:30pm, with info= rmal drinks and discussions afterwards.

What=E2=80=99s the Fmt?

A mix of:

  • Workshop-style talks =E2=80=93 anything from an accessible introduction= of your work or research, a deep dive into your library, a live demo, or a= tutorial.
  • Hacking / discussions

Call for presentations?

If you=E2=80=99d like to give a talk, please message me or @giltho directly= with:

  • A title and short abstract
  • Expected time slot

Once we confirm the first date, we=E2=80=99ll:

  • Confirm the programme and publish a new forum post
  • Setup website, a Zulip channel, and a Meetup page for registration

Looking forward to meeting more OCaml users in person!

=E2=80=93 Alistair & Sacha

Ppxlib: Support for future compilers

Nathan Rebours announced

Handling future AST changes in ppxlib

The OCaml 5.2 compiler release has introduced changes in core parts of the = AST types. Reflecting those changes when we bumped the internal AST used by= ppxlib in 0.36.0 caused breakage in a lot of reverse dependencies. Despite our efforts to keep the ecosystem up to date, it has= lead to a split in the opam universe between packages that are compatible = with 0.36.0 and above and those that aren't.

Looking at the 5.3 and 5.4 AST changes, we cannot reasonably keep the same = "= update the universe" approach going forward I would like to propose a s= lightly different but much more stable and sustainable approach.

I think it's important to have a bit of context on why ppxlib is designed t= he way it is and how we've been handling new compiler releases over the pas= t few years to understand this new approach and how it's going to improve t= he situation.

The next section of this post will summarize this. If you're already famili= ar with ppxlib's history and design choices, please skip ahead to the [Prop= osed Approach section](#proposed-approach-for-53-onward).

Ppxlib and compiler releases: How it works today

  • Ppxlib internal AST

    Before ppxlib there was ocaml-migrate-parsetree. OMP had the advantage of providi= ng a stable API for ppx authors. Each ppx would select a fixed version of t= he AST and be implemented as a full AST rewrite, i.e. a structure -&g= t; structure or signature -> signature function.

    This had the advantage of making ppx-es forward compatible as omp maintaine= rs would add support for new compiler releases in the form of a new module = containing the AST types for this version and migration functions to conver= t to/from the types matching the previous compiler version.

    OMP also came with a ppx driver, i.e. a program in charge of applying a set= of ppx-es on a given AST or source file and spit out the final preprocesse= d AST for the compiler. The driver was responsible for migrating the AST fr= om the compiler's version to the one used by a ppx. Because each ppx could = require a different AST version, it also potentially had to migrate the AST= transformed by a ppx before it passing it on to the next one.

    This had a few disadvantages though:

    1. poor performance as the AST was traversed and migrated (i.e. copied) se= veral times through the course of a single driver run.
    2. transformations semantic issues: the order in which ppx-es were applied= was uncertain or rather tied to the set of ppx-es version used. That meant= that updating one ppx could change its "turn" and result in a different AS= T returned by the driver. This also did not allow ppx-es to interact togeth= er reliably.

    ppxlib aimed at fixing those issues by forcing ppx-es to agree on the AST v= ersion to use. ppxlib provides its own, fixed AST version that ppx-es have = to use. Its driver handles the migration to/from the current compiler and p= rovides a smooth API to write transformations as rewriting rules. The drive= r then handles the AST rewrite by recursively applying those rules in the r= ight places in a single AST traversal.

  • Support for new compilers

    Support for new compilers comes in two stages.

    • Build and preprocess old code with new compile= r

      This is the most basic support, that is making sure that one can still buil= d and preprocess its code using the newest compiler, provided they don't us= e any of the new language features.

      To do this, we add the new AST types and migration functions, just as OMP u= sed to do. This does not allow new features in the code because those canno= t be represented with the old AST types and the migration would fail (Th= is was also an existing limitation of OMP).

      This is usually released early on, when the compiler is still in beta and i= s a non breaking change, all reverse dependencies still build with this new= version.

    • Support new language features

      To support new language features, we bump the AST used by ppxlib. This mean= s new features don't have to be migrated anymore and are therefore supporte= d.

      This does change types that are exposed as part of ppxlib's API and can cau= se breakage in reverse dependencies, depending on which part of the AST wer= e modified and which part each individual ppx uses explicitly.

      We provide tools that can help make ppx code more robust as they allow matc= hing over and producing AST nodes without explicitly referencing the types = themselves: metaquot, Ast_builder or Ast_pa= ttern for instance. That's not always enough though and eventually, = those ppx-es have to be updated to be compatible with the latest version of= ppxlib.

      As was the case for the 5.2 AST bump, when we release such a ppxlib version= , we send PRs to help maintainers of our opam reverse dependencies update a= nd carefully add upper bounds to the versions that aren't compatible anymor= e.

      This worked pretty well for a few years as the AST was relatively stable an= d the parts that were modified were not directly used by a lot of ppx-es.

      A problem with this approach is that even though we can help maintainers go= through the update, we cannot release packages in their stead which means = that unmaintained ppx-es aren't compatible anymore no matter how much effo= rt we put into easing the upgrade. It is also often the case that not all p= px-es have a compatible release straight away and this results in a transit= ion period with the opam universe split mentioned in the introduction.

Proposed approach for 5.3 onward

The first part of this plan is to freeze ppxlib's internal AST for each maj= or versions. That means that until we release ppxlib.1.0.0 our internal AST= will always be the 5.2 AST.

The second and most important part is to provide complete forward compatibi= lity despite the AST freeze. We will allow migrating new features down to o= ur AST by encoding them inside specific language extensions and migrating t= hem back to their original form before returning the preprocessed AST to th= e compiler.

This will allow existing ppx-es to be used with new compilers AND to be use= d in the same files as new language features as long as they don't have to = directly interact with them without being updated in any way.

We will also provide a stable API to allow ppx-es that would like to add sp= ecial support for these new features to build and match over such nodes.

You can take a look at the examples below to get an idea of what that would= look like for recent language features such as the [effect syntax](#effect= -syntax-example) from OCaml 5.3 or the [bivariance annotation](#bivariant-t= ype-parameter-example) from OCaml 5.4.

As part of these changes, we will deprecate ppxlib's copy of Ast_help= er in favor of Ast_builder, aiming to remove Ast_= helper entirely in 1.0.0. We have been maintaining two distinct modu= les for quite a while now. Ast_helper also has a tendency to e= ncourage its users to generate all their code with Location.none as their location which makes the life of their users a bit hard when th= ey have to interpret compiler errors.

This can be seen as a middle ground between the approach proposed here 6 years ag= o (that we gave up on due to its complexity) and the current situati= on.

  • Limitations

    Encoding new features into extension points is not always easy, only specif= ic parts of the AST can be replaced by an extension point. To keep things u= nder control and prevent ppx-es from generating inconsistent nodes, all new= features will always be migrated into an extension point. That means that = if the impacted node cannot directly be encoded that way, we will encode th= e first suitable parent node. In some scenarios, that can climb up the AST = types quite significantly, potentially all the way to the structure_i= tem~/~signature_item. This means that new features won't be equal wh= en it comes to how easy it is to use them in conjunction with some ppx-es. = It's important to keep in mind that this is still a net improvement as it w= as previously not possible to use them together at all.

    Similarly, providing a nice API to allow building and destructing encoded n= ew features will vastly depend on the features themselves and how entangled= they are with new AST types. We will likely not always expose such builder= /destructor pairs and might only add some of them if the demand is high eno= ugh.

    It is also part of the reason why we will probably still bump our AST at so= me points in time even if much less frequently than we have in the past. Wh= en that eventually happens, we will be able to maintain the previous major = versions for quite a while as this will just be a matter of adding our newe= st migrations there as well.

  • Effect syntax example

    OCaml 5.3 introduced the following syntax:

    match f () with
    | v -> Complete v
    | effect (Xchg msg), k ->
      ...
    

    This special effect pattern is represented in the 5.3 AST with the Pp= at_effect variant:

    | Ppat_e=
    ffect of pattern * pattern
    

    We cannot represent this in the 5.2 AST and previously, any attempt at migr= ating such a node down would have failed. With this new approach we instead= migrate it to something along those lines:

    [%ppxlib.migration.ppat_effect? (Xchg msg, k)]
    

    and the upward migration knows to translate this to the right Ppat_ef= fect node. This migration needs to work without context outside the = extension so that any ppx that would unknowingly copy such a node elsewhere= in the AST would not cause an uninterpreted extension error later on durin= g the compilation.

    If this is passed down to an existing ppx as part of its payload and it tri= es to interpret it, it should fail as it won't know what to do with such an= extension.

    Note that ppx authors should never rely on the actual extension point en= coding, we reserve ourselves the right to change that encoding as part of m= inor or patch releases of ppxlib. Such nodes should be left untouched or de= alt with using the stable API described below.

    Now if a ppx author needs to add explicit support for effects they will be = able to use something like:

    val ppat_effect : loc: location -> pattern -> pattern -> pattern
    

    from Ast_builder to generate such a node. Of course if your pp= x generates an effect pattern with an older compiler, this wil= l lead to a compile error as the extension won't be translated unless migra= ted back up. Authors will have to be mindful of this and properly document = when/how they'll generate newer nodes and eventually restrict their ppx to = the right range of compilers.

    These will likely come with a "destruct" version in Ast_pattern. For the effect pattern it should look like:

    val ppat_effect : (pattern * pattern,=
     'a, 'b) t -> (pattern, 'a, 'b) t
    
  • Bivariant type parameter example

    This example is probably a bit of a stretch as it is a very niche syntax ch= ange and is highly unlikely to actually be used in the wild, but it makes a= good example of a feature that is hard to encode.

    In OCaml 5.4, a new variant was added to the Asttypes.variance= type: Bivariant. The variance type is used in th= e AST to describe how a type parameter behaves relative to the type itself.= This can be manually annotated for each parameter when writing a type decl= aration or a class.

    The Bivariant case is a bit of a special one as a parameter ca= n only be Bivariant (i.e. covariant AND contravariant) with th= e type if it does not actually appear in the concrete type definition, that= is in cases such as:

    type 'a t =3D A
    

    For reasons that we won't expand upon here, 5.4 introduced the following sy= ntax to allow one to explicit annotate a parameter as bivariant:

    type +-'a t
    

    The problem is that the variance cannot be replaced directly by an extensio= n point, see the type type_declaration for instance:

    and type_declaration =3D
        {
         ptype_name: string loc;
         ptype_params: (core_type * (variance * injectivity)) list;
                                     ^^^^^^^^
          (** [('a1,...'an) t] *)
         ptype_cstrs: (core_type * core_type * =
    Location.t) list;
          (** [... constraint T1=3DT1'  ... constraint Tn=3DTn'] *)
         ptype_kind: type_kind;
         ptype_private: private_flag;  (** for =
    [=3D private ...] *)
         ptype_manifest: core_type option;  (**=
     represents [=3D T] *)
         ptype_attributes: attributes;  (** [... [\@\@id1] [\@\@id2]<=
    span style=3D"color: #804f60;">] *)<=
    /span>
         ptype_loc: Location.t;
        }
    

    In this example we have to encode the entire parent node of the type declar= ation as an extension point.

    This means that it spreads in quite a few places, type_declaration can be found in structure_items, signature_items and inside some module_type nodes as well.

    Given there's very little to no use for this syntax, we won't be providing = any function to build or destruct such nodes initially.

Miou, a simple scheduler for OCaml 5

Calascibetta Romain announced

I am delighted to announce the release of Miou version 0.5.0. This release = now uses poll(2)~/~ppoll(2) instead of select(3P)= in order to improve I/O management performance.

Since I/O management is decoupled from the scheduler, this does not change = the Miou API or the miou.unix library.

I would particularly like to thank @backtracking for allowing us to integra= te part of his bitv li= brary under a different licence, as well as @haesbaert, the original author= of ocaml-iomux<= /a>, for allowing us to use poll(2)~/~ppoll(2).

This has allowed us to go further, particularly with vif, our web framework for OCaml 5, and our web= site builder-web h= as been completely rewritten to move to OCaml 5 (thanks to @reynir and @yom= imono who participated in this rewrite and provided important feedbacks).

This release comes with a new package, flux (still experimental), offering streaming abstractions t= hat can be used with Miou. I would like to thank @rizo for his sketch streaming in this regard (pre-= OCaml 5). This library takes advantage of the parallelism offered by Miou (= with Miou.call) as well as resource management and finalisers = (with Miou.Ownership). A tutorial is available here to create a ti= ny curl with a loading bar.

3D"fetch.gif"

Finally, we are continuing to lay the groundwork for the development of uni= kernels with mkernel.= We are currently experimenting with three unikernels:

Finally, we would also like to thank everyone who has been involved in the = development of Miou and its related ecosystem, whether directly or indirect= ly.

Happy hacking!

Cmarkit 0.4.0 - CommonMark parser and renderer for OCaml

Daniel B=C3=BCnzli announced

Hello,=20

It's my pleasure to announce a new release of cmarkit, an ISC-licensed CommonMark parser and ren= derer for OCaml.

This release provides support for the latest version of the CommonMark spec= ification, updated data for Unicode 17.0.0, a notable semantic change in th= e task item extension (thanks to @samoht) and a couple of bug fixes and imp= rovements mostly in the CommonMark renderer.

All the details are in the release notes. Thanks to ev= eryone who reported issues.=20

This release is brought to you by essential funding from the OCaml software foundation and my donors.

P.S. I'm surprised by the number of users (or rather, dissatisfied users := =E2=80=93) of the CommonMark renderer. If you are using it don't hesitate t= o tell how/why you are using it in this thread, just curious :=E2=80=93)

OCaml library for Timeplus Proton timeseries streaming databas= e

Michael Freeman announced

A high-performance, feature-rich OCaml driver for Timeplus Proton - the streaming database built on ClickHouse.

Features

  • Streaming Queries - Process large datasets with constant memory = usage
  • Async Inserts - High-throughput data ingestion with automatic ba= tching
  • Compression - LZ4 and ZSTD support for reduced network overhead<= /li>
  • TLS Security - Secure connections with certificate validation
  • Connection Pooling - Efficient resource management for high-conc= urrency applications
  • Rich Data Types - Full support for ClickHouse types including Ar= rays, Maps, Enums, DateTime64
  • Idiomatic OCaml - Functional API leveraging OCaml's strengths

https://gith= ub.com/mfreeman451/proton-ocaml-driver

Book draft: "Control structures in programming languages"

Xavier Leroy announced

I am happy to announce that a draft of my upcoming book "Control structures= in programming languages: from goto to algebraic effects" is now available= at https://xavierle= roy.org/control-structures .

The book compares several programming languages from the standpoint of cont= rol structures. OCaml is used intensively to discuss control in functional= programming, including continuation-passing style, control operators, exce= ptions, user-defined effects and effect handlers, with many examples that I= hope you'll like.

The book also discusses in depth a number of questions that are often raise= d in this forum, such as the theory and practice of algebraic effects and h= andlers, and the static checking of exceptions and effects.

Enjoy!

oplot 0.85 - mathematical plotter

sanette announced

Hello=20

I=E2=80=99m happy to announce a new version of oplot, a library for plotting mathematical functions, = using openGL by default for fast rendering and animations, but also providi= ng high quality vector graphics exports.

This version has a new feature that math lovers will appreciate: impl= icit_curve plotting!

For instance do you want to know what the solutions to the equation (x=C2= =B2+y=C2=B2-1)=C2=B3 - x=C2=B2 y=C2=B3 =3D 0 look like?

Here is the result:

3D"00f=

If you already dug into the problem of plotting implicit curves you know th= at it=E2=80=99s sometimes very difficult to localize in advance the various= singularities of the curve. oplot gives you 3 ways of tuning = the computation: grid size, recursive grid size for subsampling where the c= urvature of the curve seems high, and control over the iterations of the Ne= wton method. There is also a pole detection, where the function changes sig= n but probably still doesn=E2=80=99t have a zero there. You can obtain debu= g information for any curve, for instance here you see the default paramete= rs automatically detected for the above curve: initial grid (green) and sub= sampling (cyan):

3D"1ed=

oplot is available in opam, doc is here.

QCheck 0.27

Jan Midtgaard announced

QCheck 0.27 is now available from the opam repository :partying_face:

https://git= hub.com/c-cube/qcheck/releases/tag/v0.27

The 0.27 release is focused on improving the float shrinking s= upport and also contains a small patch to make the package compile with OxC= aml:

  • Add QCheck.Shrink.float and enable shrinking for QCh= eck.float
  • Add QCheck.Shrink.float_bound and enable shrinking for QCheck.float_bound_inclusive and QCheck.float_bound_exclusi= ve
  • Add QCheck.Shrink.float_range and enable shrinking for QCheck.float_range
  • Enable shrinking for QCheck.{pos_float,neg_float,exponential}
  • Patch QCheck.Print.float and QCheck2.Print.float to print negative nans consistently as "-nan" also on Windows and macOS= , and correct documentation for QCheck.{float,pos_float,neg_float} in that they may produce ~nan~s since #350 from 0.26
  • Eta-expand a couple of partial application to compile under OxCaml

Happy testing! :smiley:

Bytesrw 0.3.0 =E2=80=93 The cryptographic edition

Daniel B=C3=BCnzli announced

Hello,=20

It's my pleasure to announce a new release of the bytesrw set of ISC licensed libraries.

Bytesrw extends the OCaml Bytes module with composable, memory efficient, = byte stream readers and writers compatible with effect-based concurrency.

Optional support for compressed, hashed and encrypted bytes depend, at your= wish, on the C zlib, libzstd, blake3, libmd, xxhash and mbedtls librar= ies.

This release adds optional libraries to support for SHA-3 hash= es, cryptographically secure pseudo-random bytes streams, TLS encrypted byt= e stream and low-level support for cryptographic operations on slices:

  • Bytesrw_sysrandom provides pseudorandom byte s= treams and entropy directly sourced from your operating system primitives.<= /li>
  • Bytesrw_crypto.Psa provides low-level cryptog= raphic operations on byte slices via thin and safe bindings to the TF-PSA-Crypto C library = distributed with Mbed TLS. This library is an implementation of the PSA Crypto API Spec= ification. Its design is particularly suited if you care about key mate= riel not being seen by the OCaml GC (implementations also allow further deg= rees of isolation as can be read in the API's design goals). Bes= ides the API is nicely and thoroughly documented. It is quite bureaucratic = to use but that's what you likely want from a cryptographic library (e.g. k= ey usages have to be declared upfront and are checked at runtime by cryptog= raphic operations).
  • Bytesrw_crypto (will) provides a few higher-level= operations implemented over PSA. The module is rather shallow at the momen= t, more will be added in the future as we abstract over our usage of PSA Cr= ypto. For now it mostly contains an API to access the hashes provided by PS= A Crypto in the way other bytesrw hashing modules expose their= hashing service. This notably provides the SHA-3 family of ha= shes which were not previously available in the set of optional bytes= rw libraries.
  • Bytesrw_tls provides support for TLS encrypted strea= ms and the needed X.509 certificate management (including system lookups fo= r trusted CAs). The backend is provided by the Mbed TLS C library. For now these st= reams are instantied over blocking fds, but this restriction will be lifted= in the future. I also added a little tool called certown whic= h you may find handy for dealing with certificates for localhost when you d= evelop servers.

Note that the binding to PSA cryptography has been used to implement a few = things (e.g. the horrific passkeys specification) but has not run in produc= tion yet. However the binding is pleasantly unsophisticated, the underlying= C API is straightforward to bind to.

See the release notes for details about other changes.

This release was made possible thanks to a grant from the OCaml software foundation and to my donors.

P.S. Libraries that depend on Mbed TLS need the recent 4.0.0 version which = is quite fresh and may take a bit of time to trickle in system package mana= gers. If you trust me you can use my distribution cr= utch opam repository to install it.

Old CWN

If you happen to miss a CWN, you can send me a message and I'll mail it to you, or go take a loo= k at the archive or the <= a href=3D"https://alan.petitepomme.net/cwn/cwn.rss">RSS feed of the archive= s.

If you also wish to receive it every week by mail, you may subscribe to the= caml-list.

--=-=-=--