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 590465D5 for ; Tue, 14 Jan 2020 14:17:10 +0000 (UTC) X-IronPort-AV: E=Sophos;i="5.69,433,1571695200"; d="scan'208,217";a="431299342" Received: from sympa.inria.fr ([193.51.193.213]) by mail2-relais-roc.national.inria.fr with ESMTP; 14 Jan 2020 15:17:08 +0100 Received: by sympa.inria.fr (Postfix, from userid 20132) id A65CF7F3CE; Tue, 14 Jan 2020 15:17:08 +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 0FA377ED1F for ; Tue, 14 Jan 2020 15:17:06 +0100 (CET) Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=Pass smtp.pra=alan.schmitt@polytechnique.org; spf=Pass smtp.mailfrom=SRS0=r8bB=3D=polytechnique.org=alan.schmitt@bounces.m4x.org; spf=Pass smtp.helo=postmaster@mx1.polytechnique.org IronPort-PHdr: =?us-ascii?q?9a23=3AbGLwuhMU8rdKjQUBw/Ul6mtUPXoX/o7sNwtQ0KIM?= =?us-ascii?q?zox0K/3+osbcNUDSrc9gkEXOFd2Cra4d16yO6+u8ACRAuc/H7ClZNsQUFlcsso?= =?us-ascii?q?Y/p0QYGsmLCEn2frbBThcRO4B8bmJj5GyxKkNPGczzNBX4q3y26iMOSF2kbVIm?= =?us-ascii?q?buv6FZTPgMupyuu854PcYxlShDq6fLh+MAi6oR/eu8ULjoZuMLo9xgfGrnZHZu?= =?us-ascii?q?hd2GdkKU6Okxrm6cq84ZBu/z5Mt/498sJLTLn3cbk/QbFEFjotLno75NfstRnN?= =?us-ascii?q?TAuP4mUTX2ALmRdWAAbL8Q/3UI7pviT1quRy1i+aPdbrTb8vQjSt871rSB7zhy?= =?us-ascii?q?gZMTMy7XzahdZxjKJfpxKhugB/zovJa4ybKPZyYqXQds4aSWRCWMZRSS1BApi9?= =?us-ascii?q?b4QUC+oOI/tTrof6p1sUsBS+HhSnCOfhxzNUg3P727Ax3eY8HgHcxAEuH8wAvm?= =?us-ascii?q?naotv2O6gdTfu4w7PUwTjZdf5axSvx5YrOfxs8of+MR7Vwcc/JxEQzEwPKlFOQ?= =?us-ascii?q?opH4MTyJ1uQNtmmb7/Z8VemyjGMosQVxrSKpxss2kYnGmoIVylXF9SVl3IY4Ps?= =?us-ascii?q?W4SEl/Yd+kDJtfqT2VN4twQsMjWmFopTg1xqcBuZ6hcygH0ZIqzAPRZfyAdoiH?= =?us-ascii?q?+BPjVOCJLDd/mH1qYre/hxKo/Uin0O38WdG40E5UoSpZk9nMqm4C1wTU6siCT/?= =?us-ascii?q?ty4F2t2TCR2ADP8u1EIEY0lbDaK5E72LIwmIATvVzdES/tmET6lrSWdkU89uiv?= =?us-ascii?q?9+voeLDmppuEN49ujQHyKLghmsu6AeggPQgOXnSb+eSh1LL450H2XLJKjvgunq?= =?us-ascii?q?nYrZ/bJcAbpqqjDw9SyIYj5A6zACmi0NsChnkHMFNFdw6dg4f1PFHDJu3zA/Sn?= =?us-ascii?q?g1m0jTtn2fTLMqf8DpnRIXXPirnscapn50NSxwc/1c1T6pxJBr0bPv7+WkD8uM?= =?us-ascii?q?bFAhMlKQC43uTqBMl724gDQ2yAGLWZP7nXsVKQ5uIgPe2MZIgNtTb4JPkp+uTi?= =?us-ascii?q?jWc+mV8ZfaipwYUYZ2y4HvRgIkWZeGfsjckbHWcNpAo+Q/TmiFyEUTFNe3a/R7?= =?us-ascii?q?8w6i8/BY68EIvPWo+gjKaP0SunBJFbaG9LBkiJEXjydoWEX/kMaDiVIs9kijEK?= =?us-ascii?q?SKSvRZI92Ry2rg/3yKFoI/fM9yAWu5zuzMB15+rXlRAy6Tx7EdiS02GLT2F1h2?= =?us-ascii?q?MIWiE50Lp4oUxnxVeOybJ3g/hCGtxV/f9JSRs1NZ7Zz+x7F9DyRhnMccyOSFa7?= =?us-ascii?q?RNWpHS8+Tskrz98LbEt8FM+ujhfZ3yqlG7MVjaCEBIQo8qLA2Hj8P9pyxGzD1K?= =?us-ascii?q?klllUmRspPNXa6hqNk7AjSB4vJk12DmKqwdKQc2jTN9GaZwmaUskFYSl04baKQ?= =?us-ascii?q?F3QAYAGe+dDm4GvGULnoD7k7ZE8Jg8WdLOECIoniklNuQPb4JM+YYm6gn2P2Ag?= =?us-ascii?q?yHkPfEZ4PvfyAZ3T7BIEkCiQEau3icZiYkASL0imbXCnRVHlLqYl/wub13rHq9?= =?us-ascii?q?CFQ/zwSLc1FJz72x6wIYjvyaSuoO0/QDoih3+GY8J0q0w9+DU4nInAFmZqgJOo?= =?us-ascii?q?tkvAV3kFnBvgk4BaSOarh4jwdPIRxwu1Ly2h53DIRZjMVsq2klnlMrdPColWhZ?= =?us-ascii?q?fjbd5qjef73aLm6op0Kqe/eQwlbawcqb8acJ6e0lphPkpg77TxNzoUUi6MFc1j?= =?us-ascii?q?6n3ruPCQMTVZzrVUNuqEpwoKzcaSQmoYaIxTtrK6bm6zI=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0D9EQDMzB1ehyIeaIFcCR4BCxyBfYEjW?= =?us-ascii?q?IEYVTIqhA2JA4VlNIUehRqNAoQngWMNAQMBDBgBDgUBAgEBgUyDDYFmHQYBBTM?= =?us-ascii?q?TAhABAQQBAQECAQIDBAETAQEBCgsJCCmFPgxCFgGBYgwZgwMDARgBCAQGOQIBA?= =?us-ascii?q?QECJSMDFAEGAwIEDQEXARQKFwESFAUBAYMLATiCQwUKj3ibdH8zhDQBAwIBEBg?= =?us-ascii?q?jA0CDU4E9DQITgRQBhRyDCYNNJg+BTD+BEYJlbIF5Ug4LAQEBAQGBLQEICQIBC?= =?us-ascii?q?IMmgl4EjTgZCgMFGAeIQ4IhhS+Be45JZQeCO3cEhVpnhUODX02CPYJggkcwR4c?= =?us-ascii?q?LE5ARIY46gxCDVG4QeoUhgwOKH4E/KoEJcTMaMCIhgjgBAQExCRZJDYgNF4EEA?= =?us-ascii?q?QKCQwaBPoMbO4E9hAECQDMBAQEBBgIHgQ4BAQUTCwGGcIRqAQE?= X-IPAS-Result: =?us-ascii?q?A0D9EQDMzB1ehyIeaIFcCR4BCxyBfYEjWIEYVTIqhA2JA4V?= =?us-ascii?q?lNIUehRqNAoQngWMNAQMBDBgBDgUBAgEBgUyDDYFmHQYBBTMTAhABAQQBAQECA?= =?us-ascii?q?QIDBAETAQEBCgsJCCmFPgxCFgGBYgwZgwMDARgBCAQGOQIBAQECJSMDFAEGAwI?= =?us-ascii?q?EDQEXARQKFwESFAUBAYMLATiCQwUKj3ibdH8zhDQBAwIBEBgjA0CDU4E9DQITg?= =?us-ascii?q?RQBhRyDCYNNJg+BTD+BEYJlbIF5Ug4LAQEBAQGBLQEICQIBCIMmgl4EjTgZCgM?= =?us-ascii?q?FGAeIQ4IhhS+Be45JZQeCO3cEhVpnhUODX02CPYJggkcwR4cLE5ARIY46gxCDV?= =?us-ascii?q?G4QeoUhgwOKH4E/KoEJcTMaMCIhgjgBAQExCRZJDYgNF4EEAQKCQwaBPoMbO4E?= =?us-ascii?q?9hAECQDMBAQEBBgIHgQ4BAQUTCwGGcIRqAQE?= X-IronPort-AV: E=Sophos;i="5.69,433,1571695200"; d="scan'208,217";a="431299318" X-MGA-submission: =?us-ascii?q?MDHMW4Du7XzfJuCk9szIACHkMjdXCvyUrNVxQt?= =?us-ascii?q?XMt0u0HuL6p1FMM8b3bYl+gYY5OVhEV5/PDzyYqGQIizQdZ9puwUwgBe?= =?us-ascii?q?t/i7dzWsBflXynDB47wSyGN7C2cz3s60zJfTVff0ozuslfH6/aKuBllC?= =?us-ascii?q?Q5Pp6ZddAYWcmF+CYIyue5tg=3D=3D?= Received: from mx1.polytechnique.org ([129.104.30.34]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 14 Jan 2020 15:17:03 +0100 Received: from set (set.irisa.fr [131.254.10.170]) (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 C1A3A56467A; Tue, 14 Jan 2020 15:16:59 +0100 (CET) From: Alan Schmitt To: "lwn" , "cwn" , caml-list@inria.fr Date: Tue, 14 Jan 2020 15:16:52 +0100 Message-ID: <87pnfmt963.fsf@polytechnique.org> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-=-=" X-AV-Checked: ClamAV using ClamSMTP at svoboda.polytechnique.org (Tue Jan 14 15:17:00 2020 +0100 (CET)) X-Spam-Flag: No, tests=bogofilter, spamicity=0.007366, queueID=2614156468A 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: 17952 Errors-to: caml-list-owner@inria.fr Precedence: list Precedence: bulk Sender: caml-list-request@inria.fr X-no-archive: yes List-Id: List-Archive: List-Help: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: base64 SGVsbG8NCg0KSGVyZSBpcyB0aGUgbGF0ZXN0IE9DYW1sIFdlZWtseSBOZXdzLCBmb3IgdGhlIHdl ZWsgb2YgSmFudWFyeSAwNyB0byAxNCwNCjIwMjAuDQoNClRhYmxlIG9mIENvbnRlbnRzDQrilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KQ2FsbGlu ZyBhIHNpbmdsZSBmdW5jdGlvbiBvbiBldmVyeSBtZW1iZXIgb2YgYSBHQURUPw0KT0NhbWxQcm8n cyBvcGFtIGNoZWF0IHNoZWV0LCB3aXRoIGEgbmV3IHRoZW1lIQ0KT0NhbWwgNC4xMC4wLCBmaXJz dCBiZXRhDQpEYXRhIGVuZ2luZWVyIHBvc2l0aW9ucyBhdCBFbGFzdGljLCBVUy9DYW5hZGEvV2Vz dGVybiBFdXJvcGUgKHByb3hpbWF0ZSB0byBOQSB0aW1lem9uZXMpDQpSZWxlYXNlIG9mIG5hYm9y aXMgMC4xLjAgYSBzaW1wbGUgaHR0cCBzZXJ2ZXINCmVzeUAwLjYuMCByZWxlYXNlDQpPbGQgQ1dO DQoNCg0KQ2FsbGluZyBhIHNpbmdsZSBmdW5jdGlvbiBvbiBldmVyeSBtZW1iZXIgb2YgYSBHQURU Pw0K4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoNCiAgQXJjaGl2 ZToNCiAgPGh0dHBzOi8vc3ltcGEuaW5yaWEuZnIvc3ltcGEvYXJjL2NhbWwtbGlzdC8yMDIwLTAx L21zZzAwMDA3Lmh0bWw+DQoNCg0KSXZhbiBHb3RvdmNoaXRzIGFza2VkDQrilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KICBJ J20gYmFzaWNhbGx5IHRyeWluZyB0byBkbyB0aGUgZXF1aXZhbGVudCBvZiB0aGlzIHNpbXBsZSBg Zm9sZCcNCiAgZnVuY3Rpb246DQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBtb2R1bGUgU2lt cGxlID0NCiAg4pSCIHN0cnVjdA0KICDilIIgICB0eXBlIHRlcm0gPQ0KICDilIIgICAgICB8IElu dCBvZiBpbnQNCiAg4pSCICAgICAgfCBBZGQNCiAg4pSCICAgICAgfCBBcHAgb2YgdGVybSAqIHRl cm0NCiAg4pSCIA0KICDilIIgICBsZXQgcmVjIGZvbGQgaSBmID0gZnVuY3Rpb24NCiAg4pSCICAg ICB8IEludCBfIGFzIHQgLT4gZiBpIHQNCiAg4pSCICAgICB8IEFkZCAtPiBmIGkgQWRkDQogIOKU giAgICAgfCBBcHAgKHgsIHkpIGFzIHQgLT4gZiAoZm9sZCAoZm9sZCBpIGYgeCkgZiB5KSB0DQog IOKUgiBlbmQNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAg4oCmIGJ1dCB1c2luZyBhIEdBRFQ6DQoN CiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBtb2R1bGUgR2FkdCA9DQogIOKUgiBzdHJ1Y3QNCiAg 4pSCICAgdHlwZSBfIHRlcm0gPQ0KICDilIIgICAgICB8IEludCA6IGludCAtPiBpbnQgdGVybQ0K ICDilIIgICAgICB8IEFkZCA6IChpbnQgLT4gaW50IC0+IGludCkgdGVybQ0KICDilIIgICAgICB8 IEFwcCA6ICgnYiAtPiAnYSkgdGVybSAqICdiIHRlcm0gLT4gJ2EgdGVybQ0KICDilIIgDQogIOKU giAgIGxldCByZWMgZm9sZCA6IHR5cGUgYS4gJ3IgLT4gKCdyIC0+IF8gdGVybSAtPiAncikgLT4g J3IgPSBmdW4gaSBmIC0+IGZ1bmN0aW9uDQogIOKUgiAgICAgfCBJbnQgXyBhcyB0IC0+IGYgaSB0 DQogIOKUgiAgICAgfCBBZGQgLT4gZiBpIEFkZA0KICDilIIgKCoNCiAg4pSCICAgICAgXiBFcnJv cjogVGhpcyBwYXR0ZXJuIG1hdGNoZXMgdmFsdWVzIG9mIHR5cGUgKGludCAtPiBpbnQgLT4gaW50 KSB0ZXJtDQogIOKUgiAJYnV0IGEgcGF0dGVybiB3YXMgZXhwZWN0ZWQgd2hpY2ggbWF0Y2hlcyB2 YWx1ZXMgb2YgdHlwZSBpbnQgdGVybQ0KICDilIIgCVR5cGUgaW50IC0+IGludCAtPiBpbnQgaXMg bm90IGNvbXBhdGlibGUgd2l0aCB0eXBlIGludA0KICDilIIgKikNCiAg4pSCICAgICB8IEFwcCAo eCwgeSkgYXMgdCAtPiBmIChmb2xkIChmb2xkIGkgZiB4KSBmIHkpIHQNCiAg4pSCIGVuZA0KICDi lJTilIDilIDilIDilIANCg0KICBJJ3ZlIHRyaWVkIG90aGVyIHZhcmlhbnRzIG9mIHRoZSBzeW50 YXggYW5kIGdvdCBtYW55IGVuY291cmFnZW1lbnRzDQogIGJ1dCBubyBncmVlbiBmbGFnIGZyb20g dGhlIHR5cGUtY2hlY2tlci4gIFdoeSBpcyB0aGUgY29tcGlsZXINCiAgZXhwZWN0aW5nIGFuIGlu dCB0ZXJtIGluIHRoZXJlPyBJIHRob3VnaCB0aGUgd2hvbGUgcG9pbnQgb2YgdGhlIGB0eXBlDQog IGEuIC4uLicgc3ludGF4IHdhcyB0byBhbGxvdyB0aGUgbWF0Y2hlZCB0eXBlIHRvIHZhcnkgZnJv bSBvbmUgcGF0dGVybg0KICB0byB0aGUgbmV4dD8gIElzIHRoZXJlIGEgd2F5IHRvIGRvIHRoaXM/ DQoNCg0KSXZhbiBHb3RvdmNoaXRzIHJlcGxpZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIEl0IGlzIHRo ZSBsaW1pdGF0aW9uIG9mIHRoZSBsZXQtYm91bmQgcG9seW1vcnBoaXNtLiBBIHBhcmFtZXRlciBv ZiBhDQogIGZ1bmN0aW9uIGlzIG1vbm9tb3JwaGljIGluIGl0cyBib2R5LiBUaGUgY2xhc3NpY2Fs IGV4YW1wbGUgZG9lc24ndA0KICBldmVuIHJlZmVyZW5jZSBhbnkgR0FEVCwNCg0KICDilIzilIDi lIDilIDilIANCiAg4pSCIGxldCBleGFtcGxlIGYgID0gZiAiaGVsbG8iLCBmIDQyDQogIOKUlOKU gOKUgOKUgOKUgA0KDQogIEl0IHdvbid0IGNvbXBpbGUgZXZlbiB0aG91Z2ggd2UgY2FuIHByb3Zp ZGUgYSBwb2x5bW9ycGhpYyBmdW5jdGlvbg0KICB0aGF0IGNhbiBhcHBsaWVkIGJvdGggdG8gaW50 ZWdlcnMgYW5kIHRvIHN0cmluZ3MsIGUuZy4sIGBleGFtcGUgKGZ1biB4DQogIC0+IHgpJyBzaG91 bGQgYmUgcG9zc2libGUsIGJ1dCBub3QsIGJlY2F1c2Ugb2YgdGhlIGxldC1ib3VuZGVkDQogIHBv bHltb3JwaGlzbS4gVGhlcmUgYXJlIGEgZmV3IHNvbHV0aW9ucyBhdmFpbGFibGUgaW4gT0NhbWws IHRoZQ0KICBzaW1wbGVzdCBpcyB0byB1c2UgcmVjb3JkcywgZS5nLiwNCg0KICDilIzilIDilIDi lIDilIANCiAg4pSCIHR5cGUgYXBwID0ge2FwcGx5IDogJ2EuICdhIC0+ICdhfQ0KICDilIIgDQog IOKUgiBsZXQgZXhhbXBsZSB7YXBwbHl9ID0gYXBwbHkgImhlbGxvIiwgYXBwbHkgNDI7Ow0KICDi lIIgDQogIOKUgiB2YWwgZXhhbXBsZSA6IGFwcCAtPiBzdHJpbmcgKiBpbnQgPSA8ZnVuPg0KICDi lJTilIDilIDilIDilIANCg0KICBOb3cgd2UgaGF2ZSBgYXBwJyB0aGF0IGlzIHBvbHltb3JwaGlj LiAgSW4geW91ciBjYXNlLCBJIHdvdWxkIGRlZmluZSBhDQogIHZpc2l0b3IgdHlwZSwgZS5nLiwN Cg0KICDilIzilIDilIDilIDilIANCiAg4pSCIHR5cGUgJ3IgdmlzaXRvciA9IHt2aXNpdCA6ICdh LiAnYSB0ZXJtIC0+ICdyIC0+ICdyfQ0KICDilIIgDQogIOKUgiBsZXQgcmVjIGZvbGQgOiB0eXBl IGEuICdyIC0+ICdyIHZpc2l0b3IgLT4gYSB0ZXJtIC0+ICdyID0NCiAg4pSCICAgZnVuIGkgZiB0 IC0+IG1hdGNoIHQgd2l0aA0KICDilIIgICAgIHwgSW50IF8gYXMgdCAtPiBmLnZpc2l0IGkgdA0K ICDilIIgICAgIHwgQWRkIGFzIHQgLT4gZi52aXNpdCBpIHQNCiAg4pSCICAgICB8IEFwcCAoeCx5 KSBhcyB0IC0+DQogIOKUgiAJbGV0IGkgPSBmb2xkIGkgZiB4IGluDQogIOKUgiAJbGV0IGkgPSBm b2xkIGkgZiB5IGluDQogIOKUgiAJZi52aXNpdCBpIHQNCiAg4pSU4pSA4pSA4pSA4pSADQoNCg0K SmFjcXVlcyBHYXJyaWd1ZSBhbHNvIHJlcGxpZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgA0KDQogIEFjdHVhbGx5LCB0aGlzIGlzIGEgcmFyZSBjYXNlIHdoZXJlIHVzaW5nIGEgcG9s eW1vcnBoaWMgbWV0aG9kIG1heSBiZQ0KICBoYW5keSB0b286DQoNCiAg4pSM4pSA4pSA4pSA4pSA DQogIOKUgiBsZXQgcmVjIGZvbGQgOiB0eXBlIGEgci4gciAtPiA8diA6ICdiLiByIC0+ICdiIHRl cm0gLT4gcj4gLT4gYSB0ZXJtIC0+IHIgPQ0KICDilIIgICAgICBmdW4gaSBmIC0+IGZ1bmN0aW9u DQogIOKUgiAgICAgIHwgSW50IF8gYXMgdCAtPiBmI3YgaSB0DQogIOKUgiAgICAgIHwgQWRkIC0+ IGYjdiBpIEFkZA0KICDilIIgICAgICB8IEFwcCAoeCwgeSkgYXMgdCAtPiBmI3YgKGZvbGQgKGZv bGQgaSBmIHgpIGYgeSkgdA0KICDilIIgDQogIOKUgiBsZXQgdiA9DQogIOKUgiAgICBvYmplY3Qg bWV0aG9kIHYgOiB0eXBlIGEuIF8gLT4gYSBHYWR0LnRlcm0gLT4gXyA9DQogIOKUgiAgICAgIGZ1 biB4IC0+IGZ1bmN0aW9uDQogIOKUgiAgICAgICAgfCBJbnQgbiAtPiB4K24NCiAg4pSCICAgICAg ICB8IEFkZCAtPiB4KzENCiAg4pSCICAgICAgICB8IEFwcCBfIC0+IHgrMg0KICDilIIgICAgZW5k DQogIOKUgiANCiAg4pSCIGxldCByID0gR2FkdC5mb2xkIDAgdiAoQXBwIChBcHAgKEFkZCwgSW50 IDMpLCBJbnQgNSkpDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIFRoZSBwb2ludCBiZWluZyB0aGF0 IHRvIG1hdGNoIG9uIGEgR2FkdCB5b3Ugd2lsbCBhbnl3YXkgbmVlZCB0byB1c2UNCiAgdGhlICh0 eXBlIGEpIGNvbnN0cnVjdCB0byBhbGxvdyByZWZpbmVtZW50Lg0KDQoNCnJpeGVkIGFza2VkIGFu ZCBJdmFuIEdvdG92Y2hpdHMgcmVwbGllZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgICAgICAgU28gdGhlcmUgaXMgbm8g bGlnaHRlciBzeW50YXggdG8gc3BlY2lmeSB0aGF0IGBmJyBzaG91bGQNCiAgICAgICAgYWNjZXB0 IGFueSBtZW1iZXIgb2YgYSBHQURUIHRoYW4gdGhlIHN5bnRheCB0byBzcGVjaWZ5DQogICAgICAg IHRoYXQgYGYnIHNob3VsZCBhY2NlcHQgYW55IHR5cGUgYXQgYWxsPw0KDQogIE9ubHkgdGhyZWUg bWV0aG9kcyBvZiBpbnRyb2R1Y2luZyByYW5rLTIgcG9seW1vcnBoaXNtIGFyZSBrbm93biB0byBt ZToNCiAgMS4gcmVjb3Jkcw0KICAyLiBvYmplY3RzDQogIDMuIGZpcnN0LWNsYXNzIG1vZHVsZXMN Cg0KICBKYWNxdWVzIGhhcyBkZW1vbnN0cmF0ZWQgdGhlIHNvbHV0aW9uIHdpdGggb2JqZWN0cywg d2hpY2ggbWlnaHQgYmUgYQ0KICBsaXR0bGUgYml0IG1vcmUgbGlnaHR3ZWlnaHQsIGF0IGxlYXN0 IGFzIHlvdSBkb24ndCBuZWVkIHRvIGRlZmluZSBhDQogIG5ldyBkYXRhIHR5cGUgYmVmb3JlaGFu ZC4gQnV0IHRoZSBpbnZvY2F0aW9uIGlzIG1vcmUgdmVyYm9zZSBhbmQNCiAgcmVxdWlyZXMgYW4g YW5ub3RhdGlvbiBmcm9tIHRoZSBjYWxsZXIgc2lkZSwgd2hpY2ggY291bGQgYmUNCiAgY29uZnVz aW5nLiBUaGUgdGhpcmQgc29sdXRpb24gcmVsaWVzIG9uIGZpcnN0LWNsYXNzIG1vZHVsZXMgYW5k IGlzDQogIGV2ZW4gbW9yZSB2ZXJib3NlLCBhdCBsZWFzdCBvbiB0aGUgZGVmaW5pdGlvbiBzaWRl LiBKdXN0IGZvciB0aGUgc2FrZQ0KICBvZiBjb21wbGV0ZW5lc3MsDQoNCiAg4pSM4pSA4pSA4pSA 4pSADQogIOKUgiAgIG1vZHVsZSB0eXBlIFZpc2l0b3IgPSBzaWcNCiAg4pSCICAgICB0eXBlIHQN CiAg4pSCICAgICB2YWwgdGVybSA6IHQgLT4gJ2EgdGVybSAtPiB0DQogIOKUgiAgIGVuZA0KICDi lIIgDQogIOKUgiAgIGxldCByZWMgZm9sZCA6IHR5cGUgYSByLiByIC0+IChtb2R1bGUgVmlzaXRv ciB3aXRoIHR5cGUgdCA9IHIpIC0+IGEgdGVybQ0KICDilIIgLT4gciA9DQogIOKUgiAgICAgZnVu IGkgKChtb2R1bGUgVmlzaXQpIGFzIGYpIHQgLT4gbWF0Y2ggdCB3aXRoDQogIOKUgiAgICAgICB8 IEludCBfIGFzIHQgLT4gVmlzaXQudGVybSBpIHQNCiAg4pSCICAgICAgIHwgQWRkIGFzIHQgLT4g VmlzaXQudGVybSBpIHQNCiAg4pSCICAgICAgIHwgQXBwICh4LHkpIGFzIHQgLT4NCiAg4pSCIAkg IGxldCBpID0gZm9sZCBpIGYgeCBpbg0KICDilIIgCSAgbGV0IGkgPSBmb2xkIGkgZiB5IGluDQog IOKUgiAJICBWaXNpdC50ZXJtIGkgdA0KICDilIIgDQogIOKUgiAgIGxldCBzID0gZm9sZCAwICht b2R1bGUgc3RydWN0DQogIOKUgiAgICAgICB0eXBlIHQgPSBpbnQNCiAg4pSCICAgICAgIGxldCB0 ZXJtIHggXyA9IHggKyAxDQogIOKUgiAgICAgZW5kKQ0KICDilJTilIDilIDilIDilIANCg0KICBB bmQgYWdhaW4sIGl0IGlzIG5vdCBhYm91dCBHQURULiBHQURUIGFjdCBhcyBhIHJlZCBoZXJyaW5n IGhlcmUuIEFzDQogIEkndmUgZGVtb25zdHJhdGVkIGVhcmxpZXIsIHVzaW5nIGEgc2ltcGxlIHBh aXIgd2lsbCBzdWZmaWNlIHRvIGRpc3BsYXkNCiAgdGhlIGxpbWl0YXRpb24gb2YgdGhlIHByZW5l eCBwb2x5bW9ycGhpc20uIEV2ZW4gbm8gQURUIGlzIHJlcXVpcmVkLA0KICBqdXN0IGFwcGx5IG9u ZSB0ZXJtIHRvIGFub3RoZXIgdHdvIGFuZCB5b3Ugd2lsbCBnZXQgdGhlbSB1bmlmaWVkLA0KICBl LmcuLA0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgbGV0IGYgZyB4IHkgOiB1bml0ID0gZyB4 OyBnIHkNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgd2lsbCBoYXZlIHR5cGUNCg0KICDilIzilIDi lIDilIDilIANCiAg4pSCIHZhbCBmIDogKCdhIC0+IHVuaXQpIC0+ICdhIC0+ICdhIC0+IHVuaXQN CiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgYmVjYXVzZSAnYSBpcyBxdWFudGlmaWVkIG9uIHRoZSBz Y29wZSBvZiBgZicgbm90IGBnJywgaW4gb3RoZXIgd29yZHMsDQogIGl0IGhhcyB0eXBlIChub3Qg YW4gT0NhbWwgc3ludGF4KQ0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgdmFsIGYgOiBmb3Jh bGwgJ2EuICgnYSAtPiB1bml0KSAtPiAnYSAtPiAnYSAtPiB1bml0DQogIOKUlOKUgOKUgOKUgOKU gA0KDQogIHdoaWxlIHdlIHdvdWxkIGxpa2UgdG8gaGF2ZSBhIHR5cGUNCg0KICDilIzilIDilIDi lIDilIANCiAg4pSCIHZhbCBmIDogZm9yYWxsICdiLCAnYy4gKGZvcmFsbCAnYS4gJ2EgLT4gdW5p dCkgLT4gJ2IgLT4gJ2MgLT4gdW5pdA0KICDilJTilIDilIDilIDilIANCg0KICBPQ2FtbCBkb2Vz bid0IGFsbG93IHVzIHRvIGRlZmluZSB0eXBlcyBsaWtlIGAoJ2EuICdhIC0+ICdhKScgYW5kIHRo ZQ0KICByZWFzb24gaXMgbm90IHRoYXQgaXQgaXMgaGFyZCB0byBleHRlbmQgdGhlIHBhcnNlciBp dCBpc+KApg0KDQogICAgICAgIEkgd29uZGVyLCBpcyB0aGlzIGp1c3QgYSBsaW1pdGF0aW9uIG9m IHRoZSBPQ2FtbCBwYXJzZXIgb3INCiAgICAgICAgaXMgdGhlcmUgc29tZSBkZWVwIHJlYXNvbiBm b3IgdGhlc2Ugd29yay1hcm91bmQgKGxpa2UgaXMNCiAgICAgICAgdGhlIGNhc2UsIGZyb20gbXkg dW5kZXJzdGFuZGluZywgZm9yIHRoZSB2YWx1ZQ0KICAgICAgICByZXN0cmljdGlvbik/DQoNCiAg WWVwLCBnb29kIGNhdGNoISBJdCBpcyBiZWNhdXNlIG9mIHRoZSBpbXB1cml0eS4gSW5kZWVkLCBI YXNrZWxsIGhhcw0KICB0aGUgUmFuazJUeXBlcyBleHRlbnNpb24gdGhhdCBsZXRzIHVzIHdyaXRl IHR5cGVzIGxpa2UgYChmb3JhbGwgYS4gYQ0KICAtPiAoKSkgLT4gYiAtPiBjIC0+ICgpJywgd2l0 aCBubyBleHRyYSBzeW50YWN0aWMgYnVyZGVuIChtb2R1bG8gaGF2aW5nDQogIHRvIHByb3ZpZGUg dGhlIHR5cGUgYW5ub3RhdGlvbikuIEJ1dCBmdW5jdGlvbnMgaW4gSGFza2VsbCBhcmUgcHVyZSwN CiAgdGhlcmVmb3JlIGl0IGlzIHBvc3NpYmxlLiBUbyBtYWtlIHRoZSBzdG9yeSBzaG9ydCBhbmQg b2J2aW91cywgbGV0IG1lDQogIGRvIGEgc2ltcGxlIGRlbW9uc3RyYXRpb24gb2YgaG93IHRoaW5n cyBjYW4gZ28gd3JvbmcgaW4gYSBsYW5ndWFnZQ0KICB3aXRoIHNpZGUtZWZmZWN0cy4gIExldCdz IGdvIGJhY2sgdG8gdGhlIHNpbXBsZSBleGFtcGxlIG9mIHBhaXJzIGFuZA0KICB0aGUgaWRlbnRp dHkgZnVuY3Rpb24uICBDb25zaWRlciB0aGUgZm9sbG93aW5nIG5hc3R5IGlkZW50aXR5DQogIGZ1 bmN0aW9uLA0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgbGV0IGJhZF9pZCAoKSA9DQogIOKU giAgIGxldCBjYWNoZSA9IHJlZiBOb25lIGluDQogIOKUgiAgIGZ1biB4IC0+IG1hdGNoIGNhY2hl LmNvbnRlbnRzIHdpdGgNCiAg4pSCICAgICB8IE5vbmUgLT4gY2FjaGUgOj0gU29tZSB4OyB4DQog IOKUgiAgICAgfCBTb21lIGNhY2hlIC0+IGNhY2hlDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIEl0 IGhhcyB0eXBlIGB1bml0IC0+ICdhIC0+ICdhJyB0aGVyZWZvcmUsIGlmIHdlIHdvdWxkIGhhdmUg dGhlIHJhbmstMQ0KICBwb2x5bW9ycGhpc20gZW5hYmxlZCBmb3IgZnVuY3Rpb25zLCB3ZSBjb3Vs ZCBhcHBseSBpdCB0byB0aGUgZnVuY3Rpb24NCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIGxl dCBtYXAyIDogZnVuICgnYS4gJ2EgLT4gJ2EpIC0+ICdiIC0+ICdjIC0+ICdiICogJ2MgPSBmdW4g ZiAoeCx5KSAtPiBmIHgsIGYgeQ0KICDilJTilIDilIDilIDilIANCg0KICBhcw0KDQogIOKUjOKU gOKUgOKUgOKUgA0KICDilIIgbGV0IHgseSA6IHN0cmluZyAqIGludCA9IG1hcDIgKGJhZF9pZCAo KSkgImhlbGxvIiwgNDINCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgYW5kIHdpbGwgZ2V0IGEgc2Vn bWVudGF0aW9uIGZhdWx0LCBhcyBgeScgd2lsbCBub3cgaGF2ZSB0eXBlIGludCBidXQNCiAgaG9s ZCBhIHN0cmluZy4NCg0KICBBbmQgaGVyZSBjb21lcyB0aGUgc3ludGF4IGFzIGEgc2F2aW9yIGFz IGl0IGxldHMgdXMgc3BlY2lmeSBmdW5jdGlvbnMNCiAgdGhhdCBhcmUgZ3VhcmFudGVlZCB0byBi ZSBzeW50YWN0aWMgdmFsdWVzLiBJbmRlZWQsIGFsbCB0aHJlZQ0KICBzb2x1dGlvbnMgc3ludGFj dGljYWxseSBndWFyYW50ZWUgdGhhdCB0aGUgcHJvdmlkZWQgYXJndW1lbnQgaXMgYQ0KICBmdW5j dGlvbiwgbm90IGEgY2xvc3VyZS4gSW5kZWVkLCBsZXQncyBpbnRyb2R1Y2UgdGhlIHVuaXZlcnNh bA0KICBpZGVudGl0eSB2aWEgYSByZWNvcmQsDQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiB0 eXBlIGlkID0geyBmIDogJ2EuICdhIC0+ICdhfQ0KICDilJTilIDilIDilIDilIANCg0KICBhbmQg d2UgY2FuIHNlZSB0aGF0IG91ciBgYmFkX2lkJyBpcyBub3QgYWNjZXB0ZWQgZHVlIHRvIHRoZSB2 YWx1ZQ0KICByZXN0cmljdGlvbiwgd2hpbGUgZ29vZF9pZCwgZGVmaW5lZCBhcywNCg0KICDilIzi lIDilIDilIDilIANCiAg4pSCIGxldCBnb29kX2lkIHggPSB4DQogIOKUlOKUgOKUgOKUgOKUgA0K DQogIGlzIHBlcmZlY3RseSBmaW5lLCBlLmcuLA0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIg bGV0IGlkMSA9IHtmID0gZ29vZF9pZH0gKCphY2NlcHRlZCAqKQ0KICDilIIgbGV0IGlkMiA9IHtm ID0gYmFkX2lkfSAgICgqIHJlamVjdGVkICopDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIG1vcmVv dmVyLCBldmVuIGEgZmluZSwgYnV0IG5vdCBzeW50YWN0aWMsIGlkZW50aXR5IGlzIGFsc28gcmVq ZWN0ZWQNCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIGxldCBmaW5lX2lkICgpIHggPSB4DQog IOKUgiBsZXQgaWQzID0ge2YgPSBmaW5lX2lkICgpfSAoKiByZWplY3RlZCAqKQ0KICDilJTilIDi lIDilIDilIANCg0KICB3aXRoIHRoZSBtZXNzYWdlDQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKU giBUaGlzIGZpZWxkIHZhbHVlIGhhcyB0eXBlICdiIC0+ICdiIHdoaWNoIGlzIGxlc3MgZ2VuZXJh bCB0aGFuICdhLiAnYSAtPiAnYQ0KICDilJTilIDilIDilIDilIANCg0KICBUaGUgc2FtZSBpcyB0 cnVlIHdpdGggbW9kdWxlcywNCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIG1vZHVsZSB0eXBl IElkID0gc2lnDQogIOKUgiAgIHZhbCBmIDogJ2EgLT4gJ2ENCiAg4pSCIGVuZA0KICDilIIgbW9k dWxlIElkMSA6IElkID0gc3RydWN0IGxldCBmID0gZ29vZF9pZCBlbmQgICAoKiBhY2NlcHRlZCAq KQ0KICDilIIgbW9kdWxlIElkMiA6IElkID0gc3RydWN0IGxldCBmID0gYmFkX2lkICgpIGVuZCAo KiByZWplY3RlZCAqKQ0KICDilIIgbW9kdWxlIElkMyA6IElkID0gc3RydWN0IGxldCBmID0gZmlu ZV9pZCAoKSBlbmQgKCogcmVqZWN0ZWQgKikNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgYW5kIHdp dGggb2JqZWN0cyAobGVmdCBhcyBhbiBleGVyY2lzZSkuDQoNCiAgVG8gc3VtbWFyaXplLCBpbiBv cmRlciB0byBlbmFibGUgcmFuazIgcG9seW1vcnBoaXNtIHdlIG5lZWQgYSBzcGVjaWFsDQogIGtp bmQgb2YgdmFsdWVzIHRvIGJlYXIgdW5pdmVyc2FsIGZ1bmN0aW9ucywgYXMgd2UgY2FuJ3QgcmVs eSBvbg0KICBvcmRpbmFyeSBmdW5jdGlvbnMsIHdoaWNoIGNvdWxkIGJlIGNvbnN0cnVjdGVkIHVz aW5nIHBhcnRpYWwNCiAgYXBwbGljYXRpb24uIE9DYW1sIGFscmVhZHkgaGFkIG9iamVjdHMgYW5k IHJlY29yZHMsIHdoaWNoIHNlcnZlIGFzIGENCiAgZmluZSBtZWRpYSBmb3IgdW5pdmVyc2FsbHkg cXVhbnRpZmllZCBmdW5jdGlvbnMuIExhdGVyIGZpcnN0IGNsYXNzDQogIG1vZHVsZXMgd2VyZSBp bnRyb2R1Y2VkLCB3aGljaCBjb3VsZCBhbHNvIGJlIHVzZWQgZm9yIHRoZSBzYW1lDQogIHB1cnBv c2UuIFByb2JhYmx5LCBvbmUgY291bGQgZGV2aXNlIGEgc3BlY2lhbCBzeW50YXggKG9yIHJlbHkg b24gdGhlDQogIG5ldyBhdHRyaWJ1dGVzIGFuZCBleHRlbnNpb25zIHN5bnRheCwgZS5nLiwgYG1h cDIgWyVyYW5rMiA6IGZ1biB4IC0+DQogIHhdICgiaGVsbG8iLDQyKScgYnV0IHByb2JhYmx5IHRo aXMgd2lsbCBsZWFkIHRvIGFuIHVubmVjZXNzYXJ5DQogIGJsb2F0aW5nIG9mIHRoZSBsYW5ndWFn ZSBhbmQgdGhlIGltcGxlbWVudGF0aW9uLCBlc3BlY2lhbGx5IHNpbmNlIHdlDQogIGFscmVhZHkg aGF2ZSB0aHJlZSBzb2x1dGlvbnMgd2l0aCBhIG1vcmUgb3IgbGVzcyB0b2xlcmFibGUgc3ludGF4 IChhbmQNCiAgYXJlIGluIHRoZSBiYXNlIGxhbmd1YWdlLCBub3QgYW4gZXh0ZW5zaW9uKS4gIEJl c2lkZXMsIGlmIHdlIHdpbGwgdXNlDQogIHRoZSBgW0BAdW5ib3hlZF0nIGFubm90YXRpb24sIG9y IHZpc2l0b3Igd2lsbCBoYXZlIHRoZSBzYW1lDQogIHJlcHJlc2VudGF0aW9uIGFzIGEgZnVuY3Rp b24sIGUuZy4sDQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiB0eXBlICdyIHZpc2l0b3IgPSB7 dmlzaXQgOiAnYS4gJ3IgLT4gJ2EgdGVybSAtPiAncn0gW0BAdW5ib3hlZF0NCiAg4pSCIGxldCBj b3VudCB4IF8gPSB4ICsgMQ0KICDilIIgbGV0IGNvdW50ZXIgPSB7dmlzaXQ9Y291bnR9DQogIOKU lOKUgOKUgOKUgOKUgA0KDQogIGFuZA0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgIyBDb3Jl X2tlcm5lbC5waHlzX3NhbWUgY291bnQgY291bnRlcjs7DQogIOKUgiAtIDogYm9vbCA9IHRydWUN CiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgQ29uY2VybmluZyByYW5rLW4gcG9seW1vcnBoaXNtLCBp biBPQ2FtbCBpcyBpcyBhY2hpZXZlZCB1c2luZw0KICBmdW5jdG9ycy4gIFllcywgdGhleSBhcmUg YSBsaXR0bGUgYml0IHN5bnRhY3RpY2FsbHkgaGVhdnkgYW5kIGZvcmNlIHVzDQogIHRvIHdyaXRl IHNpZ25hdHVyZXMsIGJ1dCB0aGlzIGlzIG5lY2Vzc2FyeSBhbnl3YXkgYXMgcmFuay1uIGlzDQog IHVuZGVjaWRhYmxlIChub24taW5mZXJyYWJsZSkuIEZpbmFsbHksIGFzIGEgcmVhbC13b3JsZCBl eGFtcGxlIFsxXSBvZg0KICByYW5rLTIgcG9seW1vcnBoaXNtIGNvbnNpZGVyIHRoZSB1bml2ZXJz YWwgV0FWTCB0cmVlIHRoYXQgaXMgYSBiaW5hcnkNCiAgdHJlZSB3aXRoIGVhY2ggZWxlbWVudCBo YXZpbmcgYSBkaWZmZXJlbnQgdHlwZSAoYWthIGhldGVyb2dlbmVvdXMNCiAgbWFwKS4gV2UgdXNl IGl0IGluIEJBUCBhcyBhIGJhY2tpbmcgc3RvcmUuIFlvdSBtaWdodCBmaW5kIGEgZmV3IHRyaWNr cw0KICB0aGVyZSwgZXNwZWNpYWxseSB1c2luZyBjb250aW51YXRpb24tcGFzc2luZyBpbiB0aGUg cmVjdXJzaXZlIGNhc2VzLg0KDQogIENoZWVycywgSXZhbg0KDQogIFsxXToNCiAgPGh0dHBzOi8v Z2l0aHViLmNvbS9CaW5hcnlBbmFseXNpc1BsYXRmb3JtL2JhcC9ibG9iL2I0MDY4OWU2MzY2MDdi OTc3NzU4YWYwNDhiNzlkNjU2ODRjZTQ4YzMvbGliL2tub3dsZWRnZS9iYXBfa25vd2xlZGdlLm1s I0w4NDctTDE2OTM+DQoNCg0KTWFsY29sbSBNYXRhbGthIGFza2VkIGFuZCBJdmFuIEdvdG92Y2hp dHMgcmVwbGllZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgICAgICAg V2h5IGlzIHR5cGUgY2hlY2tpbmcgY3JlYXRpbmcgYSByZWNvcmQgZGlmZmVyZW50IHRoYW4gdHlw ZQ0KICAgICAgICBjaGVja2luZyBhIGZ1bmN0aW9uIGFyZ3VtZW50Pw0KDQogICAgICAgIElmIHdl IGhhZCB0aGUgc3ludGF4IChvciBzb21ldGhpbmcgbGlrZSBpdCk6DQoNCiAgICAgICAgbGV0IG1h cDIgOiAoJ2EuICdhIC0+ICdhKSAtPiAoJ2IgKiAnYykgLT4gKCdiICogJ2MpDQoNCiAgICAgICAg V2h5IHdvdWxkIHRoZSB0eXBlIGNoZWNrZXIgbm90IGJlIGFibGUgdG8gc2VlIHRoYXQNCg0KICAg ICAgICBtYXAyIGdvb2RfaWQgKCJoaSIsIDQyKQ0KDQogICAgICAgIGlzIHZhbGlkIGJ1dA0KDQog ICAgICAgIG1hcDIgKGZpbmVfaWQgKCkpICgiaGkiLCAzMikNCg0KICAgICAgICBpcyBub3QsIHVz aW5nIHRoZSBzYW1lIGxvZ2ljIHRoYXQgaXMgdmVyaWZ5aW5nIGNyZWF0aW5nDQogICAgICAgIHRo ZSAiaWQiIHJlY29yZCBpcyBub3QgdmFsaWQ/DQoNCiAgSSBiZWxpZXZlIGl0IGlzIHBvc3NpYmxl LCBhcyBpdCBpcyBwb3NzaWJsZSBpbiBIYXNrZWxsICh3aXRoDQogIFJhbmtOVHlwZXMgYW5kIFNj b3BlZFR5cGVWYXJpYWJsZXMpLiBUaGUgbWFpbiAodGhlb3JldGljYWwpIGRpZmZlcmVuY2UNCiAg aXMgdGhhdCBpbiBPQ2FtbCB3ZSBuZWVkIHRvIGNoZWNrIHdoZXRoZXIgYW4gZXhwcmVzc2lvbiBp cyBleHBhbnNpdmUNCiAgYW5kIHVzZSBhIHNwZWNpYWxpemVkIGdlbmVyYWxpemF0aW9uIGluIGNh c2UgaWYgaXQgaXMgKGZvciB0aGUgcmVsYXhlZA0KICB2YWx1ZSByZXN0cmljdGlvbikuIEl0IHdp bGwsIGhvd2V2ZXIsIGNvbXBsaWNhdGUgdGhlIHR5cGUgaW5mZXJlbmNlDQogIGVuZ2luZSBhIGxv dCwgYnV0IG1vc3QgaW1wb3J0YW50bHksIGNoYW5naW5nIHRoZSB0eXBpbmcgcnVsZSBvZg0KICBm dW5jdGlvbnMgd2lsbCBoYXZlIGEgdHJlbWVuZG91cyBpbXBhY3Qgb24gdGhlIGxhbmd1YWdlLiBT byB0aGlzIHdvdWxkDQogIGJlIGEgdmVyeSBpbXByYWN0aWNhbCBzb2x1dGlvbi4gIEVzcGVjaWFs bHksIHNpbmNlIHdlIGRvbid0IGhhdmUgdGhlDQogIG1lY2hhbmlzbSBvZiBsYW5ndWFnZSBleHRl bnNpb25zLCBlbmFibGluZyBSYW5rTlR5cGVzIHdpbGwgbWFrZSBhIGxvdA0KICBvZiBwcm9ncmFt cyB1bnR5cGVhYmxlLCBhcyB0aGV5IHdpbGwgbm93IHJlcXVpcmUgdHlwZSBhbm5vdGF0aW9ucw0K ICAocmVjYWxsIHRoYXQgUmFua04gaXMgdW5kZWNpZGFibGUgaW4gZ2VuZXJhbCkuICBJdCBjb3Vs ZCBwcm9iYWJseSBiZQ0KICBpbXBsZW1lbnRlZCBhcyBhIGNvbXBpbGVyIGNvbW1hbmQgbGluZSBw YXJhbWV0ZXIsIGxpa2UgYC1yZWN0eXBlcycgYnV0DQogIHRoaXMgd2lsbCBiZSBzdGlsbCBxdWl0 ZSBpbXByYWN0aWNhbCBzaW5jZSBtb3JlIG9mdGVuIGNvZGUgbGlrZSBgZnVuIGYNCiAgLT4gZiAx LCBmIHRydWUnIGlzIGEgcHJvZ3JhbW1lciBlcnJvciwgcmF0aGVyIHRoYW4gYSB0cnVlIHJlcXVl c3QgZm9yDQogIHVuaXZlcnNhbCBwb2x5bW9ycGhpc20gKHRoZSBzYW1lIGFzIHdpdGggcmVjdHlw ZXMsIHJlY3Vyc2l2ZSB0eXBlcyBhDQogIG1vcmUgb2Z0ZW4gYW4gZXJyb3IgcmF0aGVyIHRoYW4g YSBkZWxpYmVyYXRlIGF0dGVtcHQpLiBUaGVyZWZvcmUsDQogIGVuYWJsaW5nIFJhbmtOKF4xKSBw b2x5bW9ycGhpc20gd2lsbCB0eXBlIHRvbyBtYW55IHByb2dyYW1zIChub3QgdGhhdA0KICBpdCBp cyB1bnNvdW5kLCBqdXN0IG1hbnkgcHJvZ3JhbXMgd29uJ3QgaGF2ZSBzZW5zZSkgYXQgdGhlIGNv c3Qgb2YNCiAgZXZlbiBtb3JlIG9ic2N1cmUgdHlwZSBlcnJvcnMuIE9uIHRoZSBvdGhlciBoYW5k LCB3ZSBoYXZlIHRocmVlDQogIHN5bnRhY3RpYyBjb25zdHJ1Y3RzIHRoYXQgbGV0IHVzIGV4cHJl c3Mgbm9uLXByZW5leCBwb2x5bW9ycGhpc20gb2YNCiAgdGhlIG5lY2Vzc2FyeSByYW5rKF4yKSB3 aXRob3V0IGJyZWFraW5nIGFueXRoaW5nIGVsc2UuIFNvIGl0IGxvb2tzDQogIGxpa2UgYSBnb29k IGRlYWwgLSB3ZSBjYW4gaGF2ZSByYW5rTiBwb2x5bW9ycGhpc20gYW5kIGRlY2lkYWJsZSB0eXBl DQogIGNoZWNrZXIgYXQgdGhlIHNhbWUgdGltZS4gSnVzdCB0aGluayBvZiBwb2x5bW9ycGhpYyBy ZWNvcmRzL21ldGhvZHMgYXMNCiAgYW4gZW1iZWRkZWQgRFNMIGZvciByYW5rTiBwb2x5bW9ycGhp c20uDQoNCiAgYD09PT09PT09PT0nIEZvb3Rub3RlczoNCg0KICAxKSBBbiBpbXBvcnRhbnQgcG9p bnQsIHRoYXQgSSBmb3Jnb3QgdG8gbm90aWNlLCBpcyB0aGF0IGVuYWJsaW5nDQogICAgIHNjb3Bl ZA0KICB0eXBlIHZhcmlhYmxlcywgd2lsbCBpbmV2aXRhYmx5IGVuYWJsZSByYW5rTiBwb2x5bW9y cGhpc20sIGUuZy4sIHNpbmNlDQogIG5vdyBhbnkgdHlwZSBjb3VsZCBiZSBhIHBvbHl0eXBlLCB0 aGVuIHN1cHBvc2Ugd2UgaGF2ZSB0eXBlDQogIGAnYS4gKCdiLidiIC0+ICdhKSAtPiAnYScgY291 bGQgYmUgaW5zdGFudGlhdGVkIHRvICdhID0gJ2QuICgnYy4gLT4NCiAgJ2QpIC0+ICdkLCBzbyB0 aGF0IG91ciB0eXBlIGlzIG5vdyBgJ2QuICgnYi4gJ2IgLT4gKCdjLiAnYyAtPiAnZCkgLT4NCiAg J2QpIC0+ICgnYy4gJ2MgLT4gJ2QpIC0+ICdkJyB3aGljaCBpcyBub3cgcmFuazMuIFRoZXJlZm9y ZSwgZW5hYmxpbmcNCiAgYXJiaXRyYXJ5IHF1YW50aWZpY2F0aW9uIGluIHRoZSBhcnJvdyB0eXBl IHdpbGwgbGVhZCB0byByYW5rTiBhbmQNCiAgaW1tZWRpYXRlbHkgbWFrZSB1bmRlY2lkYWJsZSBt b3N0IG9mIHRoZSB0eXBlIGNoZWNrZXIuDQoNCiAgMSkgV2UgY2FuIGNyYWZ0IGFyYml0cmFyeSBy YW5rIHVzaW5nIHJlY29yZHMgd2l0aCB1bml2ZXJzYWxseQ0KICAgICBxdWFudGlmaWVkDQogIHR5 cGUgdmFyaWFibGVzLCBlLmcuLCBoZXJlIGlzIGFuIGV4YW1wbGUgb2YgcmFuazMgcG9seW1vcnBo aXNtOg0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgdHlwZSAnYSByYW5rMSA9IHtmMSA6ICdz LiAncyAtPiAnYX0NCiAg4pSCIHR5cGUgJ2EgcmFuazIgPSB7ZjIgOiAnci4gJ3IgLT4gJ2EgcmFu azF9DQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIEluZGVlZCwgYGYyJyBoYXMgdHlwZSBgJ2EuKCdy LiAnciAtPiAoJ3MuICdzIC0+ICdhKScNCg0KDQpPQ2FtbFBybydzIG9wYW0gY2hlYXQgc2hlZXQs IHdpdGggYSBuZXcgdGhlbWUhDQrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZl Og0KICA8aHR0cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90L3JmYy1vY2FtbHByb3Mtb3BhbS1jaGVh dC1zaGVldC13aXRoLWEtbmV3LXRoZW1lLzQ2ODkvMz4NCg0KDQpUaG9tYXMgQmxhbmMgYW5ub3Vu Y2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIANCg0KICBUaGUgb3BhbSBjaGVhdC1zaGVldCBpcyBub3cgcHVibGlzaGVk IGluIGl0cyBmaW5hbCBmb3JtLg0KDQogIFlvdSBjYW4gZ2V0IHRoZSBbY29sb3JlZF0gYW5kIFti bGFjay1hbmQtd2hpdGVdIHZlcnNpb25zIGZyb20gb3VyDQogIHdlYnNpdGUuDQoNCiAgSGFwcHkg aGFja2luZyENCg0KDQpbY29sb3JlZF0NCjxodHRwOi8vd3d3Lm9jYW1scHJvLmNvbS93cC1jb250 ZW50L3VwbG9hZHMvMjAxOS8xMS9vY2FtbC1vcGFtLnBkZj4NCg0KW2JsYWNrLWFuZC13aGl0ZV0N CjxodHRwOi8vd3d3Lm9jYW1scHJvLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAyMC8wMS9vY2Ft bC1vcGFtLWJ3LnBkZj4NCg0KDQpPQ2FtbCA0LjEwLjAsIGZpcnN0IGJldGENCuKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkA0KDQogIEFyY2hpdmU6IDxodHRwczovL2Rpc2N1c3Mub2NhbWwub3JnL3Qvb2NhbWwtNC0x MC0wLWZpcnN0LWJldGEvNDk4OS8xPg0KDQoNCm9jdGFjaHJvbiBhbm5vdW5jZWQNCuKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIFRo ZSByZWxlYXNlIG9mIE9DYW1sIDQuMTAuMCBpcyBhcHByb2FjaGluZy4gV2UgaGF2ZSBwdWJsaXNo ZWQgYSBmaXJzdA0KICBiZXRhIHZlcnNpb24gdG8gaGVscCB5b3UgYWRhcHQgeW91ciBzb2Z0d2Fy ZSB0byB0aGUgbmV3IGZlYXR1cmVzIGFoZWFkDQogIG9mIHRoZSByZWxlYXNlLg0KDQogIER1cmlu ZyBvdXIgcHJlbGltaW5hcnkgdGVzdHMgZm9yIHRoaXMgbmV3IGJldGEsIHdlIGRpc2NvdmVyZWQg dGhhdCB0aGUNCiAgcmVjZW50IHdvcmsgdG93YXJkcyBhIG11bHRpY29yZS1yZWFkeSBPQ2FtbCBy dW50aW1lIGludHJvZHVjZWQNCiAgY29tcGF0aWJpbGl0eSBpc3N1ZXMgd2l0aGluIHNvbWUgb3Bh bSBwYWNrYWdlcywgdGhhdCB3ZXJlIHR3ZWFraW5nIHRoZQ0KICBydW50aW1lIGludGVybmFscy4g IE1vc3Qgb2YgdGhvc2Ugb3BhbSBwYWNrYWdlcyBoYXZlIGJlZW4gZml4ZWQsIG9yDQogIHdpbGwg YmUgc29vbi4gIE5ldmVydGhlbGVzcywgaWYgeW91IGFyZSBhZmZlY3RlZCBieSBzdWNoIGNvbXBh dGliaWxpdHkNCiAgaXNzdWUsIHBsZWFzZSBzcGVhayB1cC4NCg0KICBUaGUgc291cmNlIGNvZGUg aXMgYXZhaWxhYmxlIGF0IHRoZXNlIGFkZHJlc3NlczoNCg0KICA8aHR0cHM6Ly9naXRodWIuY29t L29jYW1sL29jYW1sL2FyY2hpdmUvNC4xMC4wK2JldGExLnRhci5nej4NCiAgPGh0dHBzOi8vY2Ft bC5pbnJpYS5mci9wdWIvZGlzdHJpYi9vY2FtbC00LjEwL29jYW1sLTQuMTAuMCtiZXRhMS50YXIu Z3o+DQoNCiAgVGhlIGNvbXBpbGVyIGNhbiBhbHNvIGJlIGluc3RhbGxlZCBhcyBhbiBPUEFNIHN3 aXRjaCB3aXRoIG9uZSBvZiB0aGUNCiAgZm9sbG93aW5nIGNvbW1hbmRzLg0KICDilIzilIDilIDi lIDilIANCiAg4pSCIG9wYW0gc3dpdGNoIGNyZWF0ZSBvY2FtbC12YXJpYW50cy40LjEwLjArYmV0 YTEgLS1yZXBvc2l0b3JpZXM9ZGVmYXVsdCxiZXRhPWdpdCtodHRwczovL2dpdGh1Yi5jb20vb2Nh bWwvb2NhbWwtYmV0YS1yZXBvc2l0b3J5LmdpdA0KICDilJTilIDilIDilIDilIANCiAgb3INCiAg 4pSM4pSA4pSA4pSA4pSADQogIOKUgiBvcGFtIHN3aXRjaCBjcmVhdGUgb2NhbWwtdmFyaWFudHMu NC4xMC4wK2JldGExKzxWQVJJQU5UPiAtLXJlcG9zaXRvcmllcz1kZWZhdWx0LGJldGE9Z2l0K2h0 dHBzOi8vZ2l0aHViLmNvbS9vY2FtbC9vY2FtbC1iZXRhLXJlcG9zaXRvcnkuZ2l0DQogIOKUlOKU gOKUgOKUgOKUgA0KICB3aGVyZSB5b3UgcmVwbGFjZSA8VkFSSUFOVD4gd2l0aCBvbmUgb2YgdGhl c2U6DQogIOKAoiBhZmwNCiAg4oCiIGZsYW1iZGENCiAg4oCiIGZwDQogIOKAoiBmcCtmbGFtYmRh DQoNCiAgV2Ugd2FudCB0byBrbm93IGFib3V0IGFsbCBidWdzLiBQbGVhc2UgcmVwb3J0IHRoZW0g aGVyZToNCg0KICA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL29jYW1sL2lzc3Vlcz4NCg0KICBI YXBweSBoYWNraW5nLg0KDQoNCkthdGUgYWRkZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgA0KDQogIEZvciB0aGUgcGVvcGxlIHdhbnRpbmcgdG8gZ2l2ZSBPQ2FtbCA0LjEwLjBiZXRh MSBhIHNob3QsIGhlcmUgaXMgYW4NCiAgb3BhbSBvdmVybGF5IHdoaWNoIGFkZHMgZml4ZXMgdG8g bWFqb3IgcGFja2FnZXMgZm9yIHRoZW0gdG8gd29yayB3aXRoDQogIHRoaXMgYmV0YTogPGh0dHBz Oi8vZ2l0aHViLmNvbS9raXQtdHkta2F0ZS9vcGFtLWFscGhhLXJlcG9zaXRvcnk+DQoNCiAgVG8g dXNlIGl0LCBzaW1wbGUgY2FsbDoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiAkIG9wYW0gc3dp dGNoIDQuMTANCiAg4pSCICQgb3BhbSByZXBvc2l0b3J5IGFkZCBhbHBoYSBnaXQ6Ly9naXRodWIu Y29tL2tpdC10eS1rYXRlL29wYW0tYWxwaGEtcmVwb3NpdG9yeS5naXQNCiAg4pSU4pSA4pSA4pSA 4pSADQoNCiAgT2J2aW91c2x5LCB0aGlzIHJlcG9zaXRvcnkgc2hvdWxkIG5vdCBiZSB1c2VkIGlu IHByb2R1Y3Rpb24gYW5kDQogIHByb2JhYmx5IGNvbnRhaW5zIGEgZmV3IGJ1Z3MsIGJ1dCBhdCBs ZWFzdCBpdCBhbGxvd3MgZXZlcnlvbmUgdG8gaGF2ZQ0KICBhbG1vc3QgYXMgbWFueSBwYWNrYWdl cyBhdmFpbGFibGUgYXMgd2l0aCBPQ2FtbCA0LjA5LiBPbmx5IDYwaXNoDQogIHBhY2thZ2VzIGFy ZSBzdGlsbCBub3QgYXZhaWxhYmxlLCBidXQgYXBhcnQgZnJvbSB0aGUgbm90YWJsZSBleGNlcHRp b24NCiAgb2YgYG1lcmxpbicgYWxsIHRoZSBlc3NlbnRpYWwgcGFja2FnZXMgYW5kIGRlcGVuZGVu Y2llcyBhcmUgdGhlcmUuDQoNCiAgVGhpcyB3b3JrIGhhcyBiZWVuIHBhcnQgb2YgdGhlIHJlbGVh c2UtcmVhZHluZXNzIGVmZm9ydCBmb3VuZGVkIGJ5IHRoZQ0KICBPQ2FtbCBTb2Z0d2FyZSBGb3Vu ZGF0aW9uIGFzIGFubm91bmNlZCBoZXJlOg0KICA8aHR0cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90 L2Fubi10aGUtb2NhbWwtc29mdHdhcmUtZm91bmRhdGlvbi80NDc2LzEzPg0KDQogIFRoZSByZXN0 IG9mIHRoZSBlZmZvcnQgaXMgZ29pbmcgdG8gYmUgcHV0IHRvd2FyZHMgaGF2aW5nIGBtZXJsaW4n DQogIGF2YWlsYWJsZSBmb3IgT0NhbWwgNC4xMCBhbmQgdXBzdHJlYW1pbmcgYWxsIHRoZSBmaXhl cyBmcm9tDQogIG9wYW0tYWxwaGEtcmVwb3NpdG9yeSAobW9zdCBvZiB0aGVtIGhhdmUgUFJzIGFz c29jaWF0ZWQgYWxyZWFkeSkuIEknbQ0KICBob3BlZnVsIGZvciB0aGVtIGJlIGFsbCB1cHN0cmVh bWVkIGFuZCBhdmFpbGFibGUgYmVmb3JlIHRoZSBzdGFibGUNCiAgcmVsZWFzZSBvZiBPQ2FtbCA0 LjEwLg0KDQoNCkRhdGEgZW5naW5lZXIgcG9zaXRpb25zIGF0IEVsYXN0aWMsIFVTL0NhbmFkYS9X ZXN0ZXJuIEV1cm9wZSAocHJveGltYXRlIHRvIE5BIHRpbWV6b25lcykNCuKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkA0KDQogIEFyY2hpdmU6DQogIDxodHRwczovL2Rpc2N1c3Mu b2NhbWwub3JnL3Qvam9iLWRhdGEtZW5naW5lZXItcG9zaXRpb25zLWF0LWVsYXN0aWMtdXMtY2Fu YWRhLXdlc3Rlcm4tZXVyb3BlLXByb3hpbWF0ZS10by1uYS10aW1lem9uZXMvNDk5MS8xPg0KDQoN CkhlemVraWFoIENhcnR5IGFubm91bmNlZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgT3VyIHRlYW0g aGVyZSBhdCBbRWxhc3RpY10gaGFzIHBvc2l0aW9ucyBvcGVuIGZvciBhIGZldyBzZWN1cml0eSBk YXRhDQogIGVuZ2luZWVycyAoYWthIHdyYW5nbGVycyBvZiBkYXRhIGFuZCBhbGwgdGhlIHN5c3Rl bXMgaW52b2x2ZWQpLiAgV2UNCiAgYXJlIGEgZGlzdHJpYnV0ZWQgY29tcGFueSBzbyB5b3UgZG9u J3QgaGF2ZSB0byBiZSBjbG9zZSB0byBhbiBvZmZpY2UNCiAgdG8gYmUgY29uc2lkZXJlZC4gIElu Zm9zZWMgaW5kdXN0cnkgZXhwZXJpZW5jZSBpcyBfbm90XyByZXF1aXJlZCwNCiAgdGhvdWdoIG9m IGNvdXJzZSB3ZWxjb21lLiAgV2UncmUgc3Vycm91bmRlZCBieSBleHBlcnRzIGluIHRoZSBmaWVs ZCBzbw0KICB5b3UnbGwgaGF2ZSBsb3RzIG9mIG9wcG9ydHVuaXRpZXMgdG8gbGVhcm4gYXMgeW91 IGdvIQ0KDQogIFRoZSBvZmZpY2lhbCBwb3N0aW5ncyBhcmUgYXZhaWxhYmxlIGhlcmUgKGJvdGgg aGF2ZSB0aGUgc2FtZSB0ZXh0IGFuZA0KICBvbmx5IGRpZmZlciBpbiB0aXRsZS9zZW5pb3JpdHkp Og0KICDigKIgU2VjdXJpdHkgZGF0YSBlbmdpbmVlciAtDQogICAgPGh0dHBzOi8vam9icy5lbGFz dGljLmNvL2pvYnMvc2VjdXJpdHktc29sdXRpb25zL2FtZXItZGlzdHJpYnV0ZWQtL3NlY3VyaXR5 LWRhdGEtZW5naW5lZXIvMjAwNTE0MCMvPg0KICDigKIgU2VuaW9yIHNlY3VyaXR5IGRhdGEgZW5n aW5lZXIgLQ0KICAgIDxodHRwczovL2pvYnMuZWxhc3RpYy5jby9qb2JzL3NlY3VyaXR5LXNvbHV0 aW9ucy9hbWVyLWRpc3RyaWJ1dGVkLS9zZWN1cml0eS1zZW5pb3ItZGF0YS1lbmdpbmVlci8yMDA1 MTUyIy8+DQoNCiAgTGFuZ3VhZ2Utd2lzZSwgT0NhbWwvUmVhc29uIG1ha2VzIHVwIG1vc3Qgb2Yg dGhlIGNvZGUgeW914oCZbGwgYmUNCiAgd29ya2luZyBvbi4gUHl0aG9uIG1ha2VzIHVwIG1vc3Qg b2YgdGhlIHJlc3QsIGluIHBhcnRpY3VsYXIgdGFraW5nDQogIGFkdmFudGFnZSBvZiB0aGUgbWFj aGluZSBsZWFybmluZyBhbmQgbmF0dXJhbCBsYW5ndWFnZSBwcm9jZXNzaW5nDQogIGdvb2RpZXMg dGhhdCBlY29zeXN0ZW0gcHJvdmlkZXMuIE1vc3Qgb2YgdGhlIHRvb2xzIGFuZCBzZXJ2aWNlIHdl DQogIGRldmVsb3AgYXJlIGludGVybmFsbHkgZm9jdXNlZCwgc3VwcG9ydGluZyBzZWN1cml0eSBy ZXNlYXJjaCBhbmQNCiAgaW1wcm92ZW1lbnRzIHRvIHNlY3VyaXR5IHByb3RlY3Rpb25zIGZvciBv dXIgdXNlcnMuIEZvciB0aG9zZQ0KICBzby1pbmNsaW5lZCwgdGhlcmUgYXJlIGxvdHMgb2Ygb3Bw b3J0dW5pdGllcyB0byBwcmVzZW50IGF0IGFuZCBhdHRlbmQNCiAgY29uZmVyZW5jZXMsIHByZXNl bnQgd29yayBpbiBibG9nIHBvc3RzLCBjb250cmlidXRlIHRvIG9wZW4gc291cmNlDQogIHNvZnR3 YXJlIHByb2plY3RzIGFuZCBvdGhlcndpc2UgZW5nYWdlIHRoZSBjb21tdW5pdHkuDQoNCiAgVGhl IHBvc2l0aW9ucyBhcmUgdmVyeSBzaW1pbGFyIHRvIG91ciBbbGFzdCBoaXJpbmcgYW5ub3VuY2Vt ZW50XSwNCiAgdGhvdWdoIHdlIGhhZCBhIGRpZmZlcmVudCBuYW1lIGF0IHRoYXQgcG9pbnQhDQoN CiAgUGxlYXNlIHJlYWNoIG91dCB0byBtZSBpZiB5b3UgaGF2ZSBhbnkgcXVlc3Rpb25zLiBJ4oCZ bSBhdmFpbGFibGUgb24gdGhlDQogIE9DYW1sIG9yIFJlYXNvbiBEaXNjb3JkIHNlcnZlcnMgb3Ig YnkgZW1haWwgYXQNCiAgaGV6ZWtpYWguY2FydHlAZWxhc3RpYy5jby4NCg0KDQpbRWxhc3RpY10g PGh0dHBzOi8vd3d3LmVsYXN0aWMuY28vPg0KDQpbbGFzdCBoaXJpbmcgYW5ub3VuY2VtZW50XQ0K PGh0dHBzOi8vZGlzY3Vzcy5vY2FtbC5vcmcvdC9maWxsZWQtcG9zdGluZy1pcy1uby1sb25nZXIt b3Blbi10aHJlYXQtcmVzZWFyY2gtZW5naW5lZXItam9iLWVuZGdhbWUtdXMvMTkzNz4NCg0KDQpS ZWxlYXNlIG9mIG5hYm9yaXMgMC4xLjAgYSBzaW1wbGUgaHR0cCBzZXJ2ZXINCuKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkA0KDQogIEFyY2hpdmU6DQogIDxodHRwczovL2Rpc2N1c3Mub2NhbWwub3JnL3Qv cmVsZWFzZS1vZi1uYWJvcmlzLTAtMS0wLWEtc2ltcGxlLWh0dHAtc2VydmVyLzQ5OTQvMT4NCg0K DQpTaGF3biBNY0dpbnR5IGFubm91bmNlZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgPGh0dHBzOi8vZ2l0 aHViLmNvbS9zaGF3bi1tY2dpbnR5L25hYm9yaXM+DQoNCiAgSSBjb3VsZCB1c2UgaW5wdXQgb24g dGhlIEFQSSBhbmQgdGhlIGRvY3VtZW50YXRpb24uICBXb3JraW5nIG9uIHRyeWluZw0KICB0byBp bXByb3ZlIGJvdGggYXQgdGhlIG1vbWVudC4NCg0KICBUaGUgZ29hbCB3YXMgdG8gY3JlYXRlIGEg dmVyeSBzaW1wbGUgbGlicmFyeSBmb3IgYnVpbGRpbmcgUkVTVGZ1bCB0eXBlDQogIG9mIHdlYiBz ZXJ2ZXJzLiAgTWFrZSBpdCBfdmVyeV8gZWFzeSB0byBtYW5hZ2UgaGFuZGxlIHJlcXVlc3QvcmVz cG9uc2UNCiAgbGlmZWN5Y2xlIGFuZCBzZXNzaW9ucy4NCg0KICBJbiBteSBvcGluaW9uIHRoaXMg dHlwZSBvZiB3ZWIgc2VydmVyIGlzIGEgZ3JlYXQgZW50cnkgcG9pbnQgZm9yIG5ldw0KICBkZXZl bG9wZXJzIGxvb2tpbmcgdG8gZXhwbG9yZSB0aGUgT0NhbWwvUmVhc29uIHdvcmxkLg0KDQogIFJl Y2VudGx5IEkgaGF2ZSBmYWxsZW4gaW4gbG92ZSB3aXRoIE9DYW1sIGFuZCBSZWFzb24sIGFuZCBh cyBhIG1vc3RseQ0KICB3ZWIgY2VudGVyZWQgZGV2ZWxvcGVyIEkndmUgZm91bmQgdGhpcyBhcmVh IHF1aXRlIGxhY2tpbmcuICBJJ20gc3RpbGwNCiAgbmV3IHRvIHRoZSBsYW5ndWFnZSBhbmQgZWNv IHN5c3RlbSBzbyBhbnkgZ3VpZGFuY2Ugd291bGQgYmUgaGlnaGx5DQogIGFwcHJlY2lhdGVkIQ0K DQoNCllhd2FyIEFtaW4gcmVwbGllZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgV293ISBJdCBzZWVtcyB3ZSBoYWQgbXVjaCB0aGUg c2FtZSBpZGVh4oCTT0NhbWwvUmVhc29uIG1vcmUgYWNjZXNzaWJsZQ0KICB0byB3ZWIgZGV2ZWxv cGVycyBuZXcgdG8gdGhlIGVjb3N5c3RlbSA6LUQgSSd2ZSBiZWVuIHdvcmtpbmcgb24NCiAgc29t ZXRoaW5nIHZlcnkgc2ltaWxhcjogPGh0dHBzOi8vZ2l0aHViLmNvbS95YXdhcmFtaW4vcmUtd2Vi Lz4NCg0KDQpVbHJpayBTdHJpZCBzYWlkDQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIANCg0KICBUaGVyZSBpcyBhbHNvIG9waXVtIDxodHRwczovL2dpdGh1 Yi5jb20vcmdyaW5iZXJnL29waXVtPg0KDQogIEFuZCBtb3JwaCA8aHR0cHM6Ly9naXRodWIuY29t L3JlYXNvbi1uYXRpdmUtd2ViL21vcnBoPiB0aGF0IGhhcw0KICBzaW1pbGFyIGdvYWxzLg0KDQog IEl0IHdvdWxkIGJlIG5pY2UgaWYgd2UgY291bGQgZWl0aGVyIGNyZWF0ZSBhIHNoYXJlZCBjb3Jl IHRoYXQgYWxsDQogIGNvdWxkIGJ1aWxkIGZyb20gb3IgY29sbGFib3JhdGUgb24gb25lLg0KDQoN CmVzeUAwLjYuMCByZWxlYXNlDQrilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZANCg0KICBBcmNoaXZlOiA8aHR0cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90 L2Fubi1lc3ktMC02LTAtcmVsZWFzZS81MDEwLzE+DQoNCg0KQW5kcmV5IFBvcHAgYW5ub3VuY2Vk DQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIANCg0KICBXZSd2ZSBqdXN0IHJlbGVhc2VkIGEgbmV3IHZlcnNpb24gb2YgZXN5LiBZ b3UgY2FuIGluc3RhbGwgaXQgd2l0aCBucG06DQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgJCBu cG0gaW5zdGFsbCAtZyBlc3lAMC42LjANCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgW2VzeV0gaXMg YSBwYWNrYWdlLmpzb24gZHJpdmVuIHdvcmtmbG93IGZvciBuYXRpdmUgZGV2ZWxvcG1lbnQgd2l0 aA0KICBSZWFzb24vT0NhbWwgKGFuZCBldmVuIEMvQysrKS4gSXQgcHJvdmlkZXMgcGVyLXByb2pl Y3QgYnVpbGQNCiAgZW52aXJvbm1lbnRzIHdoaWNoIGFyZSBpc29sYXRlZCBmcm9tIGVhY2ggb3Ro ZXIgYnV0IHNoYXJlIHVuZGVybHlpbmcNCiAgYnVpbGQgY2FjaGVzIHNvIGNyZWF0aW5nIG5ldyBl bnZpcm9ubWVudHMgaXMgY2hlYXAuDQoNCiAgV2hpbGUgMC42LjAgaXMgbWFpbmx5IGFib3V0ICJx dWFsaXR5LW9mLWxpZmUiIGltcHJvdmVtZW50cyBpdCBhbHNvIGdvdA0KICBmZXcgbmV3IGZlYXR1 cmVzIGluY2x1ZGluZyBhIGJhc2ljIHN1cHBvcnQgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbiBvZg0K ICB1bnVzZWQgYnVpbGQgYXJ0aWZhY3RzLg0KDQogIEZvciBtb3JlIGluZm8gc2VlIGEgW2Jsb2cg cG9zdF0gYnkgQHByb21ldGhlYW5zYWNyaWZpY2Ugd2hpY2gNCiAgaGlnaGxpZ2h0cyBpbXBvcnRh bnQgdXBkYXRlcyBpbiAwLjYuMC4NCg0KDQpbZXN5XSA8aHR0cHM6Ly9lc3kuc2g+DQoNCltibG9n IHBvc3RdIDxodHRwczovL2VzeS5zaC9ibG9nLzIwMjAvMDEvMTIvMC42LjAuaHRtbD4NCg0KDQpP bGQgQ1dODQrilZDilZDilZDilZDilZDilZDilZANCg0KICBJZiB5b3UgaGFwcGVuIHRvIG1pc3Mg YSBDV04sIHlvdSBjYW4gW3NlbmQgbWUgYSBtZXNzYWdlXSBhbmQgSSdsbCBtYWlsDQogIGl0IHRv IHlvdSwgb3IgZ28gdGFrZSBhIGxvb2sgYXQgW3RoZSBhcmNoaXZlXSBvciB0aGUgW1JTUyBmZWVk IG9mIHRoZQ0KICBhcmNoaXZlc10uDQoNCiAgSWYgeW91IGFsc28gd2lzaCB0byByZWNlaXZlIGl0 IGV2ZXJ5IHdlZWsgYnkgbWFpbCwgeW91IG1heSBzdWJzY3JpYmUNCiAgW29ubGluZV0uDQoNCiAg W0FsYW4gU2NobWl0dF0NCg0KDQpbc2VuZCBtZSBhIG1lc3NhZ2VdIDxtYWlsdG86YWxhbi5zY2ht aXR0QHBvbHl0ZWNobmlxdWUub3JnPg0KDQpbdGhlIGFyY2hpdmVdIDxodHRwOi8vYWxhbi5wZXRp dGVwb21tZS5uZXQvY3duLz4NCg0KW1JTUyBmZWVkIG9mIHRoZSBhcmNoaXZlc10gPGh0dHA6Ly9h bGFuLnBldGl0ZXBvbW1lLm5ldC9jd24vY3duLnJzcz4NCg0KW29ubGluZV0gPGh0dHA6Ly9saXN0 cy5pZHlsbC5vcmcvbGlzdGluZm8vY2FtbC1uZXdzLXdlZWtseS8+DQoNCltBbGFuIFNjaG1pdHRd IDxodHRwOi8vYWxhbi5wZXRpdGVwb21tZS5uZXQvPg0KDQo= --=-=-= Content-Type: text/html; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable OCaml Weekly News

OCaml Weekly News

Previous Week Up Next Week

Hello

Here is the latest OCaml Weekly News, for the week of January 07 to 14, 202= 0.

Calling a single function on every member of a GADT?

Ivan Gotovchits asked

I'm basically trying to do the equivalent of this simple fold = function:

module Simple =3D
struct
  type term =3D
     | Int of int
     | Add
     | App of term * term

  let rec fold i f =3D function
    | Int=
 _ as t -> f i t
    | Add=
 -> f i Add
    | App=
 (x, y) as t -> f (fold (fold i f=
 x) f y) t
end

… but using a GADT:

module Gadt =3D
struct
  type _ term =3D
     | Int : int -> int term
     | Add : (int -> int -> int) term
     | App : ('b -> 'a) term * 'b term -> 'a term

  let rec fold : type a. 'r -> (=
'r -> _ term -> 'r) -> 'r =3D fun i f -> function
    | Int=
 _ as t -> f i t
    | Add=
 -> f i Add
(*
     ^ Error: This pattern matches values o=
f type (int -> int -> int) term
        but a pattern was expected which ma=
tches values of type int term
        Type int -> int -> int is not=
 compatible with type int
*)
    | App=
 (x, y) as t -> f (fold (fold i f=
 x) f y) t
end

I've tried other variants of the syntax and got many encouragements but no = green flag from the type-checker. Why is the compiler expecting an int term in there? I though the whole poin= t of the type a. ... syntax was to allow the matched type to v= ary from one pattern to the next? Is there a way to do this?

Ivan Gotovchits replied

It is the limitation of the let-bound polymorphism. A parameter of a function is monomorphic in its body. The classical example doesn't even reference any GADT,

let example f  =3D f "hello=
", f 42

It won't compile even though we can provide a polymorphic function that can applied both to integers and to strings, e.g., exampe (fun x -> x)= should be possible, but not, because of the let-bounded polymorphism. There are a few solutions available in OCaml, the simplest is to use records, e.g.,

type app =3D {apply : 'a=
. 'a -> 'a}

let example {apply<=
/span>} =3D apply "hello", apply 42<=
span style=3D"color: #ff4500;">;;

val example : app -> string * int =3D <fun>

Now we have app that is polymorphic. In your case, I would define a visitor type, e.g.,

type 'r visitor =3D {vis=
it : 'a. 'a term -> 'r -> 'r}

let rec fold : type a. 'r -> '=
r visitor -> a term -> 'r =3D
  fun f t -> match t with
    | Int=
 _ as t -> f.visit i t
    | Add=
 as t -> f.visit i t
    | App=
 (x,y) as t ->
        let i =3D fold i f x in
        let i =3D fold i f y in
        f.visit i t

Jacques Garrigue also replied

Actually, this is a rare case where using a polymorphic method may be handy too:

let rec fold : type a r. r -> &l=
t;v : 'b. r -> 'b term -> r> -> a term -> r =3D
     fun i f -> function
     | Int _ as t -> f#v i t
     | Add -> f#v i Ad=
d
     | App (x, y) as t -> f#v (fold (fold =
i f x) f y) t

let v =3D
   object method v : type a. _ ->=
; a Gadt.term -> _ =3D
     fun x -> function
       | Int n -> x+n
       | Add -> x+1
       | App _ -> x+2
   end

let r =3D Gadt.fold 0 v (App=
 (App (Add,=
 Int 3), =
Int 5))

The point being that to match on a Gadt you will anyway need to use the (type a) construct to allow refinement.

rixed asked and Ivan Gotovchits replied

So there is no lighter syntax to specify that f should accept = any member of a GADT than the syntax to specify that f should accept any = type at all?

Only three methods of introducing rank-2 polymorphism are known to me:

  1. records
  2. objects
  3. first-class modules

Jacques has demonstrated the solution with objects, which might be a little bit more lightweight, at least as you don't need to define a new data type beforehand. But the invocation is more verbose and requires an annotation from the caller side, which could be confusing. The third solution relies on first-class modules and is even more verbose, at least on the definition side. Just for the sake of completeness,

  module type Visitor =
=3D sig
    type t
    val term : t -> 'a term -> t
  end

  let rec fold : type a r. r -> =
(module Visito=
r with type t =
=3D r) -> a term
-> r =3D
    fun i ((module Visit) as <=
span style=3D"color: #a0522d;">f) t<=
/span> -> match t with
      | Int _ as t -> Visit.term i t
      | Add as t -> Visit.term i t
      | App (x,y) as t ->
          let i =3D fold i f x in
          let i =3D fold i f y in
          Visit.term i t

  let s =3D fold 0 (module struct
      type t =3D int
      let term x _ =3D x + 1
    end)

And again, it is not about GADT. GADT act as a red herring here. As I've demonstrated earlier, using a simple pair will suffice to display the limitation of the prenex polymorphism. Even no ADT is required, just apply one term to another two and you will get them unified, e.g.,

let f g x y : unit =3D g x; g y

will have type

val f : ('a -> unit) =
-> 'a -> 'a -> unit

because 'a is quantified on the scope of f not g,= in other words, it has type (not an OCaml syntax)

val f : forall 'a. ('a -=
> unit) -> 'a -> 'a -> unit

while we would like to have a type

val f : forall 'b, 'c. (=
forall 'a. 'a -> unit) -> 'b -> 'c -> unit

OCaml doesn't allow us to define types like ('a. 'a -> 'a) = and the reason is not that it is hard to extend the parser it is…

I wonder, is this just a limitation of the OCaml parser or is there some deep reason for these work-around (like is the case, from my understanding, for the value restriction)?

Yep, good catch! It is because of the impurity. Indeed, Haskell has the Rank2Types extension that lets us write types like (forall a. a ->= ()) -> b -> c -> (), with no extra syntactic burden (modulo having to= provide the type annotation). But functions in Haskell are pure, therefore it is possible. To make the story short and obvious, let me do a simple demonstration of how things can go wrong in a language with side-effects. Let's go back to the simple example of pairs and the identity function. Consider the following nasty identity function,

let bad_id () =3D
  let cache =3D ref None in
  fun match cache.content=
s with
    | None -> cache :=3D Some x; x
    | Some cache -> cache

It has type unit -> 'a -> 'a therefore, if we would have= the rank-1 polymorphism enabled for functions, we could apply it to the function

let map2 : fun ('a. 'a -> 'a) -> 'b -> 'c -> 'b * 'c=
 =3D fun f (x,y) -> f x, f y

as

let x,y : string * int =3D map2 (bad_id ()) "hello", 42

and will get a segmentation fault, as y will now have type int= but hold a string.

And here comes the syntax as a savior as it lets us specify functions that are guaranteed to be syntactic values. Indeed, all three solutions syntactically guarantee that the provided argument is a function, not a closure. Indeed, let's introduce the universal identity via a record,

type id =3D { f : 'a. 'a=
 -> 'a}

and we can see that our bad_id is not accepted due to the value restriction, while good_id, defined as,

let good_id x =3D x

is perfectly fine, e.g.,

let id1 =3D {f =3D good_=
id} (**)
let id2 =3D {f =3D bad_id}   (* rejected *)

moreover, even a fine, but not syntactic, identity is also rejected

let fine_id () x =3D x
let id3 =3D {f =3D fine_id ()} (* rejected *)

with the message

This field value has type 'b -> 'b which is less general than 'a. 'a -&g=
t; 'a

The same is true with modules,

module type Id =3D sig
  val f : 'a -> 'a
end
module Id1 : Id =3D struct let f =3D good_id end   (* accepted *)<=
/span>
module Id2 : Id =3D struct let f =3D bad_id () end (* rejected *)<=
/span>
module Id3 : Id =3D struct let f =3D fine_id () end (* rejected *)=

and with objects (left as an exercise).

To summarize, in order to enable rank2 polymorphism we need a special kind of values to bear universal functions, as we can't rely on ordinary functions, which could be constructed using partial application. OCaml already had objects and records, which serve as a fine media for universally quantified functions. Later first class modules were introduced, which could also be used for the same purpose. Probably, one could devise a special syntax (or rely on the new attributes and extensions syntax, e.g., map2 [%rank2 : fun x -> x] ("hello",42) but p= robably this will lead to an unnecessary bloating of the language and the implementation, especially since we already have three solutions with a more or less tolerable syntax (and are in the base language, not an extension). Besides, if we will use the [@@unboxed] annotatio= n, or visitor will have the same representation as a function, e.g.,

type 'r visitor =3D {vis=
it : 'a. 'r -> 'a term -> 'r} [@@unbo=
xed]
let count x =
_ =3D x + 1
let counter =3D {visit=3Dcount}

and

# Core_kernel.=
phys_same count counter;;
- : bool =3D true

Concerning rank-n polymorphism, in OCaml is is achieved using functors. Yes, they are a little bit syntactically heavy and force us to write signatures, but this is necessary anyway as rank-n is undecidable (non-inferrable). Finally, as a real-world example [1] of rank-2 polymorphism consider the universal WAVL tree that is a binary tree with each element having a different type (aka heterogeneous map). We use it in BAP as a backing store. You might find a few tricks there, especially using continuation-passing in the recursive cases.

Cheers, Ivan

[1]: https://github.com/BinaryAnalysisPlatform/bap/blob/b40689e636607b977758af0= 48b79d65684ce48c3/lib/knowledge/bap_knowledge.ml#L847-L1693

Malcolm Matalka asked and Ivan Gotovchits replied

Why is type checking creating a record different than type checking a function argument?

If we had the syntax (or something like it):

let map2 : ('a. 'a -> 'a) -> ('b * 'c) -> ('b * 'c)

Why would the type checker not be able to see that

map2 good_id ("hi", 42)

is valid but

map2 (fine_id ()) ("hi", 32)

is not, using the same logic that is verifying creating the "id" record is not valid?

I believe it is possible, as it is possible in Haskell (with RankNTypes and ScopedTypeVariables). The main (theoretical) difference is that in OCaml we need to check whether an expression is expansive and use a specialized generalization in case if it is (for the relaxed value restriction). It will, however, complicate the type inference engine a lot, but most importantly, changing the typing rule of functions will have a tremendous impact on the language. So this would be a very impractical solution. Especially, since we don't have the mechanism of language extensions, enabling RankNTypes will make a lot of programs untypeable, as they will now require type annotations (recall that RankN is undecidable in general). It could probably be implemented as a compiler command line parameter, like -rectypes but this will be still quite impractical since more = often code like fun f -> f 1, f true is a programmer error, rather tha= n a true request for universal polymorphism (the same as with rectypes, recursive types a more often an error rather than a deliberate attempt). Therefore, enabling RankN(^1) polymorphism will type too many programs (not that it is unsound, just many programs won't have sense) at the cost of even more obscure type errors. On the other hand, we have three syntactic constructs that let us express non-prenex polymorphism of the necessary rank(^2) without breaking anything else. So it looks like a good deal - we can have rankN polymorphism and decidable type checker at the same time. Just think of polymorphic records/methods as an embedded DSL for rankN polymorphism.

=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D Footnotes:

  1. An important point, that I forgot to notice, is that enabling scoped

type variables, will inevitably enable rankN polymorphism, e.g., since now any type could be a polytype, then suppose we have type 'a. ('b.'b -&= gt; 'a) -> 'a could be instantiated to 'a =3D 'd. ('c. -> 'd) -> '= d, so that our type is now 'd. ('b. 'b -> ('c. 'c -> 'd) -> 'd) -> ('c. = 'c -> 'd) -> 'd which is now rank3. Therefore, enabling arbitrary quantification in the arrow type will lead to rankN and immediately make undecidable most of the type checker.

  1. We can craft arbitrary rank using records with universally quantified

type variables, e.g., here is an example of rank3 polymorphism:

type 'a rank1 =3D {f1 : =
's. 's -> 'a}
type 'a rank2 =3D {f2 : 'r. 'r -> 'a rank1}

Indeed, f2 has type 'a.('r. 'r -> ('s. 's -> 'a)

OCamlPro's opam cheat sheet, with a new theme!

Thomas Blanc announced

The opam cheat-sheet is now published in its final form.

You can get the colored and black-and-white versions from = our website.

Happy hacking!

OCaml 4.10.0, first beta

octachron announced

The release of OCaml 4.10.0 is approaching. We have published a first beta version to help you adapt your software to the new features ahead of the release.

During our preliminary tests for this new beta, we discovered that the rece= nt work towards a multicore-ready OCaml runtime introduced compatibility issues within some opam packages, that were tweaking the runtime internals. Most of those opam packages have been fixed, or will be soon. Nevertheless, if you are affected by such compatibility issue, please speak= up.

The source code is available at these addresses:

http= s://github.com/ocaml/ocaml/archive/4.10.0+beta1.tar.gz
https://caml.inria.fr/pub/distrib/ocaml-4.10/ocaml-4.10.0+beta1.tar= .gz

The compiler can also be installed as an OPAM switch with one of the following commands.

opam switch create ocaml-variants.4.10.0+beta1=
 --repositories=3Ddefault,beta=3Dgit=
+https://github.com/ocaml/ocaml-beta-repository.git

or

opam switch create ocaml-variants.4.10.0+beta1=
+<VARIANT> --repositories=3Ddefault,b=
eta=3Dgit+https://github.com/ocaml/ocaml-beta-repository.git

where you replace <VARIANT> with one of these:

  • afl
  • flambda
  • fp
  • fp+flambda

We want to know about all bugs. Please report them here:

https://github.com/ocaml/= ocaml/issues

Happy hacking.

Kate added

For the people wanting to give OCaml 4.10.0beta1 a shot, here is an opam ov= erlay which adds fixes to major packages for them to work with this beta: <= a href=3D"https://github.com/kit-ty-kate/opam-alpha-repository">https://git= hub.com/kit-ty-kate/opam-alpha-repository

To use it, simple call:

$ opam switch 4.10
$ opam repository add alpha git://github.com/kit-ty-kate/opam-alpha-reposit=
ory.git

Obviously, this repository should not be used in production and probably co= ntains a few bugs, but at least it allows everyone to have almost as many p= ackages available as with OCaml 4.09. Only 60ish packages are still not ava= ilable, but apart from the notable exception of merlin all the= essential packages and dependencies are there.

This work has been part of the release-readyness effort founded by the OCam= l Software Foundation as announced here: https://discuss.ocaml.org/t= /ann-the-ocaml-software-foundation/4476/13

The rest of the effort is going to be put towards having merlin available for OCaml 4.10 and upstreaming all the fixes from opam-alpha-re= pository (most of them have PRs associated already). I'm hopeful for them b= e all upstreamed and available before the stable release of OCaml 4.10.

Data engineer positions at Elastic, US/Canada/Western Europe (= proximate to NA timezones)

Hezekiah Carty announced

Our team here at Elastic has positi= ons open for a few security data engineers (aka wranglers of data and all t= he systems involved). We are a distributed company so you don't have to be= close to an office to be considered. Infosec industry experience is not required, though of course welcome. We're = surrounded by experts in the field so you'll have lots of opportunities to = learn as you go!

The official postings are available here (both have the same text and only = differ in title/seniority):

Language-wise, OCaml/Reason makes up most of the code you=E2=80=99ll be wor= king on. Python makes up most of the rest, in particular taking advantage o= f the machine learning and natural language processing goodies that ecosyst= em provides. Most of the tools and service we develop are internally focuse= d, supporting security research and improvements to security protections fo= r our users. For those so-inclined, there are lots of opportunities to pres= ent at and attend conferences, present work in blog posts, contribute to op= en source software projects and otherwise engage the community.

The positions are very similar to our last hiring announcement, though we had a different name at that = point!

Please reach out to me if you have any questions. I=E2=80=99m available on = the OCaml or Reason Discord servers or by email at hezekiah.carty@elastic.c= o.

Release of naboris 0.1.0 a simple http server

Shawn McGinty announced

https://github.com/sha= wn-mcginty/naboris

I could use input on the API and the documentation. Working on trying to i= mprove both at the moment.

The goal was to create a very simple library for building RESTful type of w= eb servers. Make it very easy to manage h= andle request/response lifecycle and sessions.

In my opinion this type of web server is a great entry point for new develo= pers looking to explore the OCaml/Reason world.

Recently I have fallen in love with OCaml and Reason, and as a mostly web c= entered developer I've found this area quite lacking. I'm still new to the= language and eco system so any guidance would be highly appreciated!

Yawar Amin replied

Wow! It seems we had much the same idea=E2=80=93OCaml/Reason more accessibl= e to web developers new to the ecosystem :-D I've been working on something= very similar: https://git= hub.com/yawaramin/re-web/

Ulrik Strid said

There is also opium https://= github.com/rgrinberg/opium

And morph https://gi= thub.com/reason-native-web/morph that has similar goals.

It would be nice if we could either create a shared core that all could bui= ld from or collaborate on one.

esy@0.6.0 release

Andrey Popp announced

We've just released a new version of esy. You can install it with npm:

$ npm install -g esy@0.6.0

esy is a package.json driven workflow for na= tive development with Reason/OCaml (and even C/C++). It provides per-projec= t build environments which are isolated from each other but share underlyin= g build caches so creating new environments is cheap.

While 0.6.0 is mainly about "quality-of-life" improvements it also got few = new features including a basic support for garbage collection of unused bui= ld artifacts.

For more info see a b= log post by @prometheansacrifice which highlights important updates in = 0.6.0.

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 RSS feed of the archives<= /a>.

If you also wish to receive it every week by mail, you may subscribe online.

--=-=-=--