From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by c5ff346549e7 (Postfix) with ESMTPS id EA5E02E03 for ; Tue, 28 Jun 2022 07:37:33 +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=UgN/YDr9LpLpvC33FFX8P7kXu89IVoCw94jVGLggeoY=; b=f7JZgmbjMDmK16n4AZ1PaVZ98Aqe/tm80gM4TcdLBE0nTqYIe7gevWie cX+BODocSyHdnJZtclSQ9ywbRmMCbWHI3njt87MBZl6G1yBCwi8I+U3Vo ietv8Sg8a7MNWNI+XP8auBIgficJg55dmPbTV9aOGaXSl8jIt4bfdXCbZ w=; Received-SPF: SoftFail (mail2-relais-roc.national.inria.fr: domain of caml-list-owner@inria.fr is inclined to not designate 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 ip4:192.134.164.0/24 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=SoftFail smtp.mailfrom=caml-list-owner@inria.fr; spf=None smtp.helo=postmaster@sympa.inria.fr; dkim=hardfail (signature did not verify [final]) header.i=@polytechnique.org X-IronPort-AV: E=Sophos;i="5.92,227,1650924000"; d="scan'208,217";a="43153110" Received: from prod-listesu18.inria.fr (HELO sympa.inria.fr) ([128.93.162.160]) by mail2-relais-roc.national.inria.fr with ESMTP; 28 Jun 2022 09:37:33 +0200 Received: by sympa.inria.fr (Postfix, from userid 20132) id EB004E7E66; Tue, 28 Jun 2022 09:37:32 +0200 (CEST) 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 05D5AE00BE for ; Tue, 28 Jun 2022 09:37:30 +0200 (CEST) IronPort-SDR: AWT7l/4ULdffDot+DfXOOVbq+xlneOMWFQSBSndsu1P9fJncGU+sStac3ZHVN9jjK6OLXlLQJ4 ejoF+cAY+DzFZ49GeM8ktrQ0Dw2iPHxkF+SdRksVJY0yCRA9/M+8FLFaotA5STPY5T4hPy5bt3 OfIppPHDOL1LeeYNtpF9qDC0pEKZHA0lQ2fBQRbmSfivD1R0fGsj8+iHd3O60tqZL0ie4IaaHe a/LYBBA/xBNrXb89na5ByocjpHpAI3zOQZHVgvW9RwZeZf9eu8RALatufXfsmu2AN1Gdi9tHlF uiCbRz86FyC52wHe2z42W9sW X-IPAS-Result: =?us-ascii?q?A0DdAQAEr7pihyIeaIFaHgEBCxIMgzCBAxkBZ1YuBwhEh?= =?us-ascii?q?E6RDYlWlRYQAQMBDSwBDgQBAgQBAYUDGIU0Ah4GAQUzEwECBAEBAQEDAgMBA?= =?us-ascii?q?QEBAQEDAQEFAQEBAgEBAgQEARMBAQEBDQsJBQgMBRAOBTxkZASBSwSBdAs0D?= =?us-ascii?q?YI1DBmDcAEhBAYTAQEsDBgjAxQBBgMCBA0BFwEeFwESGoJjAYMYAwQBCpEUm?= =?us-ascii?q?xp6fzKBAYIIAQEGgT8BhEqBXAkkgRmGIV9LAYMPhBsCFxAQgVVEhA9ugVB7F?= =?us-ascii?q?wEBAQEBgTsBAU2DKYJljjGDPYEvhjgHOANHLxKBIG4BCAYGBwoFMAYCDBgUB?= =?us-ascii?q?AITEk0GHAISDAoGFQ5CEhcMDwMSAxEBBwIJEggVKwgDAgMIAwIDKwIDFgkHC?= =?us-ascii?q?gMdCAocEhAUAgQRHgsIAxkeLAkCBA4DQggLCgMRBAMTGAkWCBAEBgMILw0nC?= =?us-ascii?q?wMFDw0BBgMGAgUFAQMgAxQDBSQHAyEPJg0NBCIdAwMFJQMCAhsHAgIDAgYVB?= =?us-ascii?q?gICGFYuDQgECAQYHyQPBQIHLwUELwIeBAUGEQgCFgIGBAUCBAQWAhAIAggnF?= =?us-ascii?q?wcTMxkBBVkQCSEWBikQBQYWAyFKJgVFDyg0NjwsHxsKgRosCSIWAwQEAwIGG?= =?us-ascii?q?gMDIgISKQYtBiKWVoRdDkA8PhMBGw8BLykbHQEMFxEVBAoERhYvA5IAIZh4l?= =?us-ascii?q?Tc0B4NRgT4GDIgvgSKNAogkg3WBUJFVkUohlk8giSuBHIJKlFOFPIFOKoFrD?= =?us-ascii?q?AczGjBDgmgJRQEDAg0BAgIDAQIBAgkBAQKOHQkDFoNQhCA5O4VMPzQCAQE3A?= =?us-ascii?q?gYBCgEBAwmFYwEBBRMLAYh4AQE?= IronPort-PHdr: A9a23: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 IronPort-Data: A9a23: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 74= IronPort-HdrOrdr: A9a23:G3/KIq0da0hBnpDb3vbP4wqjBI8kLtp133Aq2lEZdPU1SL36qy nKpp4mPHDP5gr5NEtMpTniAsm9qBHnlKKdiLN5VdyftWLd11dAQrsP0aLShxXeXwf++uRe2a oISdkdNPTASX5gg4Lf6Am8euxQpOVvHZrY4Nvj8w== X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="5.92,227,1650924000"; d="scan'208,217";a="43153083" X-MGA-submission: =?us-ascii?q?MDEsAWQNdcvUB7/R9+6TF+9UbYSgE3fPoQHvy1?= =?us-ascii?q?BLYPtPm71yQ4W2Uj5xUBA23X8xVuMLQd8KIDmEiTRdeIf3Y1A1aVQZFN?= =?us-ascii?q?I/KnH/J9MDfOwv0PaKGEbNkHIS0JcS0Xv/ua7kE8p0WHIFvux/0HhmNv?= =?us-ascii?q?/XcvaQYCs7mMtyIWZ2j8EZEg=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; 28 Jun 2022 09:37:29 +0200 Received: from set (unknown [89.207.171.77]) (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 1C447565B42; Tue, 28 Jun 2022 09:37:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=polytechnique.org; s=svoboda; t=1656401847; bh=aUWy1tKri98D+R9rdjVeBG9RwuvHV/xNhhbroSETOIU=; h=From:To:Subject:Date:Message-ID; b=PQElZNEm4lP01G3rAcpwIneRPNNh5Lg/WJKEfTkez8ElZfZK1cy76q5n40pyoPOZ+ 9McwUGzmhHGuJkWNNryjdcFCQS2007z9kuuaYSo/b8/EcnKV5bAWnBmDMklQJ2Vws9 ywQHqAaBJ08odFe+OiVWZMFFS6YG9erki+JZD2UI= From: Alan Schmitt To: "lwn" , "cwn" , caml-list@inria.fr Date: Tue, 28 Jun 2022 09:37:16 +0200 Message-ID: <87sfnpw85v.fsf@m4x.org> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-=-=" X-AV-Checked: ClamAV using ClamSMTP at svoboda.polytechnique.org (Tue Jun 28 09:37:28 2022 +0200 (CEST)) X-Spam-Flag: Unsure, tests=bogofilter, spamicity=0.459847, queueID=34E0C560785 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: 18809 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: base64 SGVsbG8NCg0KSGVyZSBpcyB0aGUgbGF0ZXN0IE9DYW1sIFdlZWtseSBOZXdzLCBmb3IgdGhlIHdl ZWsgb2YgSnVuZSAyMSB0byAyOCwNCjIwMjIuDQoNClRoZSBtYWlsaW5nIGxpc3QgbW9kZSBvZiBk aXNjdXNzLm9jYW1sLm9yZyBzZWVtcyB0byBoYXZlIGJlZW4gZG93biBmb3IgYQ0KZmV3IGRheXMs IHNvIEkgaGFkIHRvIG1hbnVhbGx5IHNjcmFwZSB0aGUgbWVzc2FnZXMuIE15IGFwb2xvZ2llcyBp ZiBJDQptaXNzZWQgYW55Lg0KDQpUYWJsZSBvZiBDb250ZW50cw0K4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCkFuIGFtdXNpbmcgdXNlIG9mIGZp cnN0LWNsYXNzIG1vZHVsZXM6IHJlYWRpbmcgZnJvbSBwbGFpbnRleHQgYW5kIGNvbXByZXNzZWQg ZmlsZXMNCkx3dC41LjYuMCAoYW5kIG90aGVyIEx3dCBwYWNrYWdlcykNCk9sZCBDV04NCg0KDQpB biBhbXVzaW5nIHVzZSBvZiBmaXJzdC1jbGFzcyBtb2R1bGVzOiByZWFkaW5nIGZyb20gcGxhaW50 ZXh0IGFuZCBjb21wcmVzc2VkIGZpbGVzDQrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZl Og0KICA8aHR0cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90L2FuLWFtdXNpbmctdXNlLW9mLWZpcnN0 LWNsYXNzLW1vZHVsZXMtcmVhZGluZy1mcm9tLXBsYWludGV4dC1hbmQtY29tcHJlc3NlZC1maWxl cy8xMDA3Mz4NCg0KDQpDaGV0X011cnRoeSBleHBsYWluZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIEkgd2FzIHJl Y2VudGx5IHRyeWluZyB0byB3cml0ZSBhIHRoaW5nIGluIFJ1c3QsIGFuZCBoYXZpbmcgcHJvYmxl bXMsDQogIHNvIEkgd3JvdGUgdGhlIHNhbWUgdGhpbmcgaW4gT0NhbWwsIGp1c3QgdG8gbWFrZSBz dXJlIHRoYXQgaXQgd2FzDQogIGRvYWJsZS4gSSB0aG91Z2h0IEnigJlkIHBvc3QgYWJvdXQgaXQs IGIvYyBtYXliZSBpdOKAmXMgYW4gZXhhbXBsZSBvZiB3aGF0DQogIHdl4oCZbGwgZmluZCBtb3Jl IHRyYWN0YWJsZSwgb25jZSB3ZSBoYXZlIG1vZHVsYXIgaW1wbGljaXRzLg0KDQogIFRoZSBwcm9i bGVtOiBJIGhhdmUgYm90aCBjb21wcmVzc2VkIGFuZCBwbGFpbnRleHQgZmlsZXMsIGFuZCBJIHdh bnQgdG8NCiAgcnVuIGEgZnVuY3Rpb24gb3ZlciB0aGUgdW5jb21wcmVzc2VkIGNvbnRlbnRzLiBJ 4oCZZCBsaWtlIGEgY29tYmluYXRvcg0KICB0aGF0IEkgY2FuIGFwcGx5IHRvIHRoZSBmaWxlbmFt ZSBhbmQgdGhlIGZ1bmN0aW9uLCB0aGF0IHdpbGwgZG8gdGhlDQogIHdvcmsgb2Ygb3BlbmluZyB0 aGUgZmlsZSwgY2FsbGluZyB0aGUgZnVuY3Rpb24sIGNsb3NpbmcgdGhlIGZpbGUsIGV0Yy4NCg0K ICBUaGlzIGlzbuKAmXQgc28gaGFyZC4NCg0KICAxLiBkZWZpbmUgYSB0eXBlIG9mIFJFQURFUiAo YW5kIHR3byBpbnN0YW5jZXMgZm9yIHBsYWludGV4dCBhbmQNCiAgICAgZ3ppcHBlZCkuIFRoaXMg aXMgdGhlIGVxdWl2YWxlbnQgb2YgUnVzdOKAmXMg4oCcaW86OkJ1ZlJlYWTigJ0uDQoNCiAgICAg 4pSM4pSA4pSA4pSA4pSADQogICAgIOKUgiBtb2R1bGUgdHlwZSBSRUFERVIgPQ0KICAgICDilIIg ICBzaWcNCiAgICAg4pSCICAgICB0eXBlIGluX2NoYW5uZWwNCiAgICAg4pSCICAgICB2YWwgb3Bl bl9pbiA6IHN0cmluZyAtPiBpbl9jaGFubmVsDQogICAgIOKUgiAgICAgdmFsIGlucHV0X2NoYXIg OiBpbl9jaGFubmVsIC0+IGNoYXINCiAgICAg4pSCICAgICB2YWwgY2xvc2VfaW4gOiBpbl9jaGFu bmVsIC0+IHVuaXQNCiAgICAg4pSCICAgZW5kDQogICAgIOKUgiBsZXQgc3RkcmVhZGVyID0gKG1v ZHVsZSBTdGRsaWIgOiBSRUFERVIpIDs7DQogICAgIOKUgiBsZXQgZ3pyZWFkZXIgPSAobW9kdWxl IEd6aXAgOiBSRUFERVIpIDs7DQogICAgIOKUlOKUgOKUgOKUgOKUgA0KDQogIDIuIHRoZW4gZGVm aW5lIGEgdHlwZSBvZiDigJxpbiBjaGFubmVsIHVzZXLigJ0gKOKAnElDVVNFUuKAnSkgYW5kIHRo ZSBnZW5lcmljDQogICAgIHZlcnNpb24gb2YgaXQNCg0KICAgICDilIzilIDilIDilIDilIANCiAg ICAg4pSCIG1vZHVsZSB0eXBlIElDVVNFUiA9IHNpZw0KICAgICDilIIgICB0eXBlIGluX2NoYW5u ZWwNCiAgICAg4pSCICAgdmFsIHVzZV9pYyA6IGluX2NoYW5uZWwgLT4gdW5pdA0KICAgICDilIIg ZW5kDQogICAgIOKUgiBtb2R1bGUgdHlwZSBHRU5FUklDX0lDVVNFUiA9IGZ1bmN0b3IgKFIgOiBS RUFERVIpIC0+IChJQ1VTRVIgd2l0aCB0eXBlIGluX2NoYW5uZWwgPSBSLmluX2NoYW5uZWwpDQog ICAgIOKUlOKUgOKUgOKUgOKUgA0KDQogIDMuIHRoZW4gZGVmaW5lIG91ciBmdW5jdGlvbiB0aGF0 IHRha2VzIGEgZ2VuZXJpYyBpbl9jaGFubmVsLCBhbmQgdXNlcw0KICAgICBpdCDigJMg4oCcQ2F0 4oCdDQoNCiAgICAg4pSM4pSA4pSA4pSA4pSADQogICAgIOKUgiBtb2R1bGUgQ2F0KFIgOiBSRUFE RVIpIDogSUNVU0VSIHdpdGggdHlwZSBpbl9jaGFubmVsID0gUi5pbl9jaGFubmVsID0gc3RydWN0 DQogICAgIOKUgiAgIHR5cGUgaW5fY2hhbm5lbCA9IFIuaW5fY2hhbm5lbA0KICAgICDilIIgICBs ZXQgdXNlX2ljIGljID0NCiAgICAg4pSCICAgbGV0IHJlYyByZXJlYyAoKSA9DQogICAgIOKUgiAg ICAgbWF0Y2ggUi5pbnB1dF9jaGFyIGljIHdpdGgNCiAgICAg4pSCICAgICAgIGMgLT4gcHJpbnRf Y2hhciBjIDsgcmVyZWMgKCkNCiAgICAg4pSCICAgICB8IGV4Y2VwdGlvbiBFbmRfb2ZfZmlsZSAt PiAoKQ0KICAgICDilIIgICBpbiByZXJlYyAoKQ0KICAgICDilIIgZW5kDQogICAgIOKUlOKUgOKU gOKUgOKUgA0KDQogIDQuIEFuZCB0aGVuIHdyaXRlIG91ciDigJx3aXRoX2lucHV0X2ZpbGXigJ0g ZnVuY3Rpb24sIHRoYXQgdGFrZXMgYQ0KICAgICBmaWxlbmFtZSwgdGhlIGZ1bmN0aW9uIGZyb20g IzMsIGFuZCBhcHBsaWVzIGl0IHRvIGVpdGhlciBhIG5vcm1hbA0KICAgICBpbl9jaGFubmVsLCBv ciBvbmUgcHJvZHVjZWQgZnJvbSBhIGd6aXAtcmVhZGVyLg0KDQogICAgIOKUjOKUgOKUgOKUgOKU gA0KICAgICDilIIgbGV0IHdpdGhfaW5wdXRfZmlsZSBmbmFtZSAobW9kdWxlIFIgOiBHRU5FUklD X0lDVVNFUikgPQ0KICAgICDilIIgICBsZXQgKG1vZHVsZSBNIDogUkVBREVSKSA9DQogICAgIOKU giAgICAgaWYgRnBhdGguKGZuYW1lIHw+IHYgfD4gaGFzX2V4dCAiZ3oiKSB0aGVuDQogICAgIOKU giAgICAgICBnenJlYWRlcg0KICAgICDilIIgICAgIGVsc2Ugc3RkcmVhZGVyIGluDQogICAgIOKU giAgIGxldCBvcGVuIE0gaW4NCiAgICAg4pSCICAgbGV0IGljID0gTS5vcGVuX2luIGZuYW1lIGlu DQogICAgIOKUgiAgIGxldCBtb2R1bGUgQyA9IFIoTSkgaW4NCiAgICAg4pSCICAgdHJ5IGxldCBy diA9IEMudXNlX2ljIGljIGluIGNsb3NlX2luIGljIDsgcnYNCiAgICAg4pSCICAgd2l0aCBlIC0+ IGNsb3NlX2luIGljIDsgcmFpc2UgZQ0KICAgICDilJTilIDilIDilIDilIANCg0KICBBbmQgbm93 IHdlIGNhbiB1c2UgaXQ6DQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiB3aXRoX2lucHV0X2Zp bGUgIi9ldGMvcGFzc3dkIiAobW9kdWxlIENhdCkgOzsNCiAg4pSCIHdpdGhfaW5wdXRfZmlsZSAi Zm9vLmd6IiAobW9kdWxlIENhdCkgOzsNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgRWFzeS1wZWFz eS4gSSBkb27igJl0IHJlbWVtYmVyIGVub3VnaCBhYm91dCB0aGUgbW9kdWxhciBpbXBsaWNpdHMN CiAgcHJvcG9zYWwgdG8gcmVtZW1iZXIgaWYgdGhpcyBjYW4gYmUgY2FzdCBpbiB0aGUgc3VwcG9y dGVkIGxhbmd1YWdlDQogIHRoZXJlLCBzbyBJIHN1cHBvc2UgSSBzaG91bGQgZ2V0IHNvbWUgdmVy c2lvbiBvZiB0aGF0IGNvZGUgKG9yIHRoZQ0KICBuZXdlciB2ZXJzaW9ucyBmcm9tIG90aGVycykg dXAtYW5kLXJ1bm5pbmcsIGFuZCBzZWUgaWYgdGhpcyBjYW4gYmUNCiAgbWFkZSB0byB3b3JrLg0K DQoNCmh5cGhlbnJmIGFza2VkIGFuZCBDaGV0X011cnRoeSByZXBsaWVkDQrilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KICAgICAgICBj YW7igJl0IHdlIGdldCByaWQgb2YgdGhlIGBHRU5FUklDX0lDVVNFUicgcmVxdWlyZW1lbnQgYW5k DQogICAgICAgIGp1c3QgYXNrIGZvciBmdW5jdGlvbnMgdGhhdCB0YWtlIGEgcGFja2VkIG1vZHVs ZSBvZiB0eXBlDQogICAgICAgIGBSRUFERVInDQoNCiAgICAgICAgYnkgdGhhdCBJIG1lYW4gdGhl IHNpZ25hdHVyZSBvZiBgd2l0aF9pbnB1dF9maWxlJyBiZWNvbWVzDQogICAgICAgIGBzdHJpbmcg LT4gKChtb2R1bGUgUkVBREVSKSAtPiAnYSkgLT4gJ2EnDQoNCiAgSXTigJlzIGEgZ29vZCBxdWVz dGlvbiwgYW5kIGFzIGEgbmV3YmllIHVzZXIgb2YgZmlyc3QtY2xhc3MgbW9kdWxlcywgSQ0KICBk b27igJl0IGtub3cgdGhlIHR5cGluZyBydWxlcyB3ZWxsIGVub3VnaCB0byBhbnN3ZXIuIEJ1dCBJ IGRpZCB0cnk6DQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBsZXQgd2l0aF9pbnB1dF9maWxl JyBmbmFtZSBmID0NCiAg4pSCICAgbGV0IChtb2R1bGUgTSA6IFJFQURFUikgPQ0KICDilIIgICAg IGlmIEZwYXRoLihmbmFtZSB8PiB2IHw+IGhhc19leHQgImd6IikgdGhlbg0KICDilIIgICAgICAg Z3pyZWFkZXINCiAg4pSCICAgICBlbHNlIHN0ZHJlYWRlciBpbg0KICDilIIgICBsZXQgb3BlbiBN IGluDQogIOKUgiAgIGxldCBpYyA9IE0ub3Blbl9pbiBmbmFtZSBpbg0KICDilIIgICBmIChtb2R1 bGUgTSA6IFJFQURFUikgaWMNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgYW5kIGdvdA0KDQogIOKU jOKUgOKUgOKUgOKUgA0KICDilIIgRmlsZSAiaW9hYnMubWwiLCBsaW5lIDk2LCBjaGFyYWN0ZXJz IDI0LTI2Og0KICDilIIgOTYgfCAgIGYgKG1vZHVsZSBNIDogUkVBREVSKSBpYw0KICDilIIgCQkJ ICAgICBeXg0KICDilIIgRXJyb3I6IFRoaXMgZXhwcmVzc2lvbiBoYXMgdHlwZSBNLmluX2NoYW5u ZWwNCiAg4pSCICAgICAgICBidXQgYW4gZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWQgb2YgdHlwZSAn YQ0KICDilIIgICAgICAgIFRoZSB0eXBlIGNvbnN0cnVjdG9yIE0uaW5fY2hhbm5lbCB3b3VsZCBl c2NhcGUgaXRzIHNjb3BlDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIEVUQTogSSByZW1lbWJlciBp biB0aGUgbW9kdWxhciBpbXBsaWNpdHMgcGFwZXIsIHRoYXQgdGhlcmUgd2FzIGEgbG90DQogIG9m IHdyYXBwZXJpbmcgY29kZSBpbiBzdHJ1Y3RzICh0aGF0IGRpZG7igJl0IHN0YXJ0IG9mZiBpbiBz dHJ1Y3RzKS4gSQ0KICB3b25kZXIgaWYgdGhhdOKAmXMgZXZpZGVuY2UgdGhhdCB5b3UgcmVhbGx5 IGRvIGhhdmUgdG8g4oCccHVzaCB1cOKAnSBjb2RlIHRvDQogIHRoZSBtb2R1bGUgbGV2ZWwgaW4g b3JkZXIgdG8gbWFrZSBpdCB3b3JrLg0KDQoNCm9jdGFjaHJvbiB0aGVuIHNhaWQNCuKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIFlv dSBkb27igJl0IG5lZWQgbW9kdWxhciBpbXBsaWNpdHMgdG8gc2ltcGxpZnkgeW91ciBjb2RlLiBZ b3VyIHBhY2tlZA0KICBtb2R1bGUgdHlwZSBpcyBlcXVpdmFsZW50IHRvOg0KDQogIOKUjOKUgOKU gOKUgOKUgA0KICDilIIgdHlwZSBjaGFubmVsID0geyBpbnB1dF9jaGFyOiB1bml0IC0+IGNoYXI7 IGNsb3NlX2luOiB1bml0IC0+IHVuaXQgfQ0KICDilIIgdHlwZSBjaGFubmVsX2dlbmVyYXRvciA9 IHN0cmluZyAtPiAgY2hhbm5lbA0KICDilJTilIDilIDilIDilIANCg0KICBXZSBjb3VsZCBnbyBm YW5jeSBhbmQgbWFuaWZlc3QgdGhlIHR5cGUgd2l0aCBhbiBleGlzdGVudGlhbA0KDQogIOKUjOKU gOKUgOKUgOKUgA0KICDilIIgdHlwZSAnYSBjaGFubmVsID0NCiAg4pSCICAgeyBvcGVuX2ZuOiBz dHJpbmcgLT4gJ2E7IGlucHV0X2NoYXI6ICdhIC0+IGNoYXI7IGNsb3NlX2luOiAnYSAtPiB1bml0 IH0NCiAg4pSCIHR5cGUgY2hhbiA9IEFueTogJ2EgY2hhbm5lbCAtPiBjaGFuDQogIOKUlOKUgOKU gOKUgOKUgA0KDQogIGJ1dCB0aGlzIGhhcyBtYWlubHkgdGhlIGFkdmFudGFnZSB0byBpbGx1c3Ry YXRlIHRoZSBmYWN0IHRoYXQgeW91IGFyZQ0KICBuZXZlciB1c2luZyB0aGUgbm9uLWV4aXN0ZW50 aWFsbHkgcXVhbGlmaWVkIGAnYSBjaGFubmVsJyB3aGljaCBtZWFucw0KICB0aGF0IGluIHRoZSBj dXJyZW50IHZlcnNpb24gb2YgeW91ciBjb2RlLCBtb2R1bGFyIChleHBsaWNpdHMgb3IpDQogIGlt cGxpY2l0cyBpcyBub3QgYSBnb29kIGZpdDogd2UgYXJlIG5vdCBzZWxlY3RpbmcgYSBtb2R1bGUg dG8gcHJvdmlkZQ0KICBmdW5jdGlvbnMgZm9yIGEgdHlwZSwgd2UgaGF2ZSBhbiBvYmplY3QgKGFr YSBhbiBleGlzdGVudGlhbGx5DQogIHF1YWxpZmllZCByZWNvcmQpIHdpdGggc29tZSBoaWRkZW4g aW5uZXIgdHlwZSB0aGF0IHdlIG5ldmVyIG5lZWQgdG8NCiAga25vdy4NCg0KDQpjLWN1YmUgbGF0 ZXIgc2FpZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSADQoNCiAgSSB0aGluayBpdOKAmXMga2luZCBvZiBjb3VudGVyLXByb2R1Y3RpdmUgdG8gd2Fu dCBhIGBpbl9jaGFubmVsJyB0eXBlIGF0DQogIGFsbC4gVGhpcyBpcyB3aGF0IEnigJl2ZSBiZWVu IGRvaW5nLCBtb3JlIGFuZCBtb3JlOg0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgbW9kdWxl IHR5cGUgSU5QVVQgPSBzaWcNCiAg4pSCICAgdmFsIHJlYWRfY2hhciA6IHVuaXQgLT4gY2hhcg0K ICDilIIgICB2YWwgcmVhZCA6IGJ5dGVzIC0+IGludCAtPiBpbnQgLT4gaW50DQogIOKUgiAgIHZh bCBjbG9zZSA6IHVuaXQgLT4gdW5pdA0KICDilIIgZW5kDQogIOKUgiANCiAg4pSCIHR5cGUgaW5w dXQgPSAobW9kdWxlIElOUFVUKQ0KICDilIIgDQogIOKUgiBsZXQgb3Blbl9maWxlIChmaWxlbmFt ZTpzdHJpbmcpIDogaW5wdXQgPQ0KICDilIIgICBsZXQgaWMgPSBvcGVuX2luIGZpbGVuYW1lIGlu DQogIOKUgiAgIChtb2R1bGUgc3RydWN0DQogIOKUgiAgICAgbGV0IHJlYWRfY2hhcigpID0gaW5w dXRfY2hhciBpYw0KICDilIIgICAgIGxldCByZWFkID0gaW5wdXQgaWMNCiAg4pSCICAgICBsZXQg Y2xvc2UoKSA9IGNsb3NlX2luIGljDQogIOKUgiAgZW5kKQ0KICDilIIgDQogIOKUgiANCiAg4pSC IGxldCBkb19zdGggKG1vZHVsZSBJTjpJTlBVVCkgPQ0KICDilIIgICBJQy5yZWFkX2NoYXIgKCk7 DQogIOKUgiAgIElDLnJlYWQg4oCmDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIFRoaXMgYmVoYXZl cyBsaWtlIGNsYXNzaWMgb2JqZWN0cyBpbiBvdGhlciBsYW5ndWFnZXMgYW5kIHRoZXJl4oCZcyBu bw0KICBjb21wbGljYXRlZCB0eXBpbmcgZ29pbmcgb24gKHdoYXQgd2l0aCBlYWNoIGltcGxlbWVu dGF0aW9uIGhhdmluZyBpdHMNCiAgb3duIGNoYW5uZWwgdHlwZSkuDQoNCg0KTHd0LjUuNi4wIChh bmQgb3RoZXIgTHd0IHBhY2thZ2VzKQ0K4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2ZToNCiAgPGh0dHBzOi8vZGlzY3Vzcy5vY2FtbC5vcmcv dC9hbm4tbHd0LTUtNi0wLWFuZC1vdGhlci1sd3QtcGFja2FnZXMvMTAwNzc+DQoNCg0KcmFwaGFl bC1wcm91c3QgYW5ub3VuY2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KICBJdCBpcyBhIHJlYWwgcGxl YXN1cmUgdG8gYW5ub3VuY2UgdGhlIHJlbGVhc2Ugb2YgTHd0IHZlcnNpb24gNS42LjAgYXMNCiAg d2VsbCBhcyBMd3QtZG9tYWluLjAuMi4wLCBMd3QtcHB4LjIuMS4wIGFuZCBMd3QtcmVhY3QuMS4y LjAuIFdpdGggdGhpcw0KICByZWxlYXNlIEx3dCBpcyBub3cgY29tcGF0aWJsZSB3aXRoIE9DYW1s IHZlcnNpb24gNS4NCg0KICA8aHR0cHM6Ly9naXRodWIuY29tL29jc2lnZW4vbHd0L3JlbGVhc2Vz L3RhZy81LjYuMD4NCg0KICBUaGFuayB5b3UgdG8gdGhlIG1hbnkgY29udHJpYnV0b3JzIGZvciB0 aGUgZml4ZXMsIHRoZSBpbXByb3ZlbWVudHMsDQogIGFuZCB0aGUgT0NhbWw1IGNvbXBhdGliaWxp dHkhIENoZWNrIG91dCB0aGUgY2hhbmdlbG9nIGZvciBmdWxsIGRldGFpbHMNCiAgb24gZWFjaCBj b250cmlidXRpb24uDQoNCg0KT2xkIENXTg0K4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgSWYg eW91IGhhcHBlbiB0byBtaXNzIGEgQ1dOLCB5b3UgY2FuIFtzZW5kIG1lIGEgbWVzc2FnZV0gYW5k IEknbGwgbWFpbA0KICBpdCB0byB5b3UsIG9yIGdvIHRha2UgYSBsb29rIGF0IFt0aGUgYXJjaGl2 ZV0gb3IgdGhlIFtSU1MgZmVlZCBvZiB0aGUNCiAgYXJjaGl2ZXNdLg0KDQogIElmIHlvdSBhbHNv IHdpc2ggdG8gcmVjZWl2ZSBpdCBldmVyeSB3ZWVrIGJ5IG1haWwsIHlvdSBtYXkgc3Vic2NyaWJl DQogIFtvbmxpbmVdLg0KDQogIFtBbGFuIFNjaG1pdHRdDQoNCg0KW3NlbmQgbWUgYSBtZXNzYWdl XSA8bWFpbHRvOmFsYW4uc2NobWl0dEBwb2x5dGVjaG5pcXVlLm9yZz4NCg0KW3RoZSBhcmNoaXZl XSA8aHR0cHM6Ly9hbGFuLnBldGl0ZXBvbW1lLm5ldC9jd24vPg0KDQpbUlNTIGZlZWQgb2YgdGhl IGFyY2hpdmVzXSA8aHR0cHM6Ly9hbGFuLnBldGl0ZXBvbW1lLm5ldC9jd24vY3duLnJzcz4NCg0K W29ubGluZV0gPGh0dHA6Ly9saXN0cy5pZHlsbC5vcmcvbGlzdGluZm8vY2FtbC1uZXdzLXdlZWts eS8+DQoNCltBbGFuIFNjaG1pdHRdIDxodHRwczovL2FsYW4ucGV0aXRlcG9tbWUubmV0Lz4NCg0K --=-=-= 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 June 21 to 28, 2022.

The mailing list mode of discuss.ocaml.org seems to have been down for a fe= w days, so I had to manually scrape the messages. My apologies if I missed = any.

An amusing use of first-class modules: reading from plaintext = and compressed files

Chet_Murthy explained

I was recently trying to write a thing in Rust, and having problems, so I w= rote the same thing in OCaml, just to make sure that it was doable. I thoug= ht I=E2=80=99d post about it, b/c maybe it=E2=80=99s an example of what we= =E2=80=99ll find more tractable, once we have modular implicits.

The problem: I have both compressed and plaintext files, and I want to run = a function over the uncompressed contents. I=E2=80=99d like a combinator th= at I can apply to the filename and the function, that will do the work of o= pening the file, calling the function, closing the file, etc.

This isn=E2=80=99t so hard.

  1. define a type of READER (and two instances for plaintext and gzipped). This= is the equivalent of Rust=E2=80=99s =E2=80=9Cio::BufRead=E2=80=9D.

    module type READER =3D
      sig
        type in_channel
        val open_in : string -> in_channel
        val input_char : in_channel -> char
        val close_in : in_channel -> unit
      end
    let stdreader =3D (=
    module Stdlib : READER) ;;
    let gzreader =3D (m=
    odule Gzip : READER) ;;
    
  2. then define a type of =E2=80=9Cin channel user=E2=80=9D (=E2=80=9CICUSER=E2= =80=9D) and the generic version of it

    module type ICUSER =3D <=
    span style=3D"color: #000000; font-weight: bold;">sig
      type in_channel
      val use_ic : in_channel -> unit
    end
    module type GENERIC_ICUSER =3D functor (READER) -> (ICUSER with type in_channel =3D R.in_channel)
    
  3. then define our function that takes a generic in_channel, and uses it =E2= =80=93 =E2=80=9CCat=E2=80=9D

    module Cat(R : READER=
    ) : =
    ICUSER with type<=
    /span> in_channel =3D R.in_channel =3D struct
      type in_channel =3D R.in_channel
      let use_ic ic =3D
      let rec rerec () =3D
        match R.input_char ic with
          c -> print_char c ; rerec ()
        | exception End_of_file -> ()
      in rerec ()
    end
    
  4. And then write our =E2=80=9Cwith_input_file=E2=80=9D function, that takes a= filename, the function from #3, and applies it to either a normal in_chann= el, or one produced from a gzip-reader.

    let with_input_file fname (m=
    odule R : GENERIC_ICUSER) =3D
      let (module M : =
    READER) =3D
        if Fpath.(fname |> v |> has_ext "gz") then
          gzreader
        else stdreader in
      let open M in
      let ic =3D M.open_in fname in
      let module C =3D R(M) in
      try let rv =
    =3D C.use_ic ic in close_in ic ; rv
      with e -> close_in ic ; raise e
    

And now we can use it:

with_input_file  (module Cat) ;;
with_input_file "foo.gz" (module Cat) ;;

Easy-peasy. I don=E2=80=99t remember enough about the modular implicits pro= posal to remember if this can be cast in the supported language there, so I= suppose I should get some version of that code (or the newer versions from= others) up-and-running, and see if this can be made to work.

hyphenrf asked and Chet_Murthy replied

can=E2=80=99t we get rid of the GENERIC_ICUSER requirement and= just ask for functions that take a packed module of type READER

by that I mean the signature of with_input_file becomes = string -> ((module READER) -> 'a) -> 'a

It=E2=80=99s a good question, and as a newbie user of first-class modules, = I don=E2=80=99t know the typing rules well enough to answer. But I did try:

let with_input_file' fname f=
 =3D
  let (module M : =
READER) =3D
    if Fpath.(fname |> v |> has_ext "gz") then
      gzreader
    else stdreader in
  let open M in
  let ic =3D M.open_in fname in
  f (module M : READER) ic

and got

File "ioabs.ml",=
 line 96, characters 24-26:
96 |   f (module M : READER) ic
                             ^^
Error: This expres=
sion has type M.in_channel
       but an expression was expected of type 'a
       The type constructor M.=
in_channel would escape its scope

ETA: I remember in the modular implicits paper, that there was a lot of wra= ppering code in structs (that didn=E2=80=99t start off in structs). I wonde= r if that=E2=80=99s evidence that you really do have to =E2=80=9Cpush up=E2= =80=9D code to the module level in order to make it work.

octachron then said

You don=E2=80=99t need modular implicits to simplify your code. Your packed= module type is equivalent to:

type channel =3D { input=
_char: unit -> char; close_in: unit -> unit }
type channel_generator =3D string ->  channel

We could go fancy and manifest the type with an existential

type 'a channel =3D
  { open_fn: string -> 'a; input_char: 'a -> char; close_in: 'a ->=
 unit }
type chan =3D Any: 'a channel -> chan

but this has mainly the advantage to illustrate the fact that you are never= using the non-existentially qualified 'a channel which means = that in the current version of your code, modular (explicits or) implicits = is not a good fit: we are not selecting a module to provide functions for a= type, we have an object (aka an existentially qualified record) with some = hidden inner type that we never need to know.

c-cube later said

I think it=E2=80=99s kind of counter-productive to want a in_channel<= /code> type at all. This is what I=E2=80=99ve been doing, more and more:

module type INPUT =3D sig
  val read_char : unit -> char
  val read : bytes -> int -> int -> int
  val close : unit -> unit
end

type input =3D (modu=
le INPUT)

let open_file (file=
name:string) : input =3D
  let ic =3D open_in filename in
  (module struct
    let read_char() =3D input_char ic
    let read =3D input ic
    let close() =3D close_in ic
 end)


let do_sth (module<=
/span> IN:INPUT) =3D
  IC.read_char ();
  IC.read …

This behaves like classic objects in other languages and there=E2=80=99s no= complicated typing going on (what with each implementation having its own = channel type).

Lwt.5.6.0 (and other Lwt packages)

raphael-proust announced

It is a real pleasure to announce the release of Lwt version 5.6.0 as well = as Lwt-domain.0.2.0, Lwt-ppx.2.1.0 and Lwt-react.1.2.0. With this release L= wt is now compatible with OCaml version 5.

https://githu= b.com/ocsigen/lwt/releases/tag/5.6.0

Thank you to the many contributors for the fixes, the improvements, and the= OCaml5 compatibility! Check out the changelog for full details on each con= tribution.

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 online.

--=-=-=--