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 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 Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of alan.schmitt@polytechnique.org designates 129.104.30.34 as permitted sender) identity=pra; client-ip=129.104.30.34; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="SRS0=r8bB=3D=polytechnique.org=alan.schmitt@bounces.m4x.org"; x-sender="alan.schmitt@polytechnique.org"; x-conformance=sidf_compatible; x-record-type="spf2.0" Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of SRS0=r8bB=3D=polytechnique.org=alan.schmitt@bounces.m4x.org designates 129.104.30.34 as permitted sender) identity=mailfrom; client-ip=129.104.30.34; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="SRS0=r8bB=3D=polytechnique.org=alan.schmitt@bounces.m4x.org"; x-sender="SRS0=r8bB=3D=polytechnique.org=alan.schmitt@bounces.m4x.org"; x-conformance=sidf_compatible; x-record-type="spf2.0" Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of postmaster@mx1.polytechnique.org designates 129.104.30.34 as permitted sender) identity=helo; client-ip=129.104.30.34; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="SRS0=r8bB=3D=polytechnique.org=alan.schmitt@bounces.m4x.org"; x-sender="postmaster@mx1.polytechnique.org"; x-conformance=sidf_compatible; x-record-type="v=spf1" 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 --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: base64 SGVsbG8NCg0KSGVyZSBpcyB0aGUgbGF0ZXN0IE9DYW1sIFdlZWtseSBOZXdz LCBmb3IgdGhlIHdlZWsgb2YgSmFudWFyeSAwNyB0byAxNCwNCjIwMjAuDQoN ClRhYmxlIG9mIENvbnRlbnRzDQrilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KQ2FsbGluZyBhIHNpbmds ZSBmdW5jdGlvbiBvbiBldmVyeSBtZW1iZXIgb2YgYSBHQURUPw0KT0NhbWxQ cm8ncyBvcGFtIGNoZWF0IHNoZWV0LCB3aXRoIGEgbmV3IHRoZW1lIQ0KT0Nh bWwgNC4xMC4wLCBmaXJzdCBiZXRhDQpEYXRhIGVuZ2luZWVyIHBvc2l0aW9u cyBhdCBFbGFzdGljLCBVUy9DYW5hZGEvV2VzdGVybiBFdXJvcGUgKHByb3hp bWF0ZSB0byBOQSB0aW1lem9uZXMpDQpSZWxlYXNlIG9mIG5hYm9yaXMgMC4x LjAgYSBzaW1wbGUgaHR0cCBzZXJ2ZXINCmVzeUAwLjYuMCByZWxlYXNlDQpP bGQgQ1dODQoNCg0KQ2FsbGluZyBhIHNpbmdsZSBmdW5jdGlvbiBvbiBldmVy eSBtZW1iZXIgb2YgYSBHQURUPw0K4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ 4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQ4pWQDQoN CiAgQXJjaGl2ZToNCiAgPGh0dHBzOi8vc3ltcGEuaW5yaWEuZnIvc3ltcGEv YXJjL2NhbWwtbGlzdC8yMDIwLTAxL21zZzAwMDA3Lmh0bWw+DQoNCg0KSXZh biBHb3RvdmNoaXRzIGFza2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0KICBJ J20gYmFzaWNhbGx5IHRyeWluZyB0byBkbyB0aGUgZXF1aXZhbGVudCBvZiB0 aGlzIHNpbXBsZSBgZm9sZCcNCiAgZnVuY3Rpb246DQoNCiAg4pSM4pSA4pSA 4pSA4pSADQogIOKUgiBtb2R1bGUgU2ltcGxlID0NCiAg4pSCIHN0cnVjdA0K ICDilIIgICB0eXBlIHRlcm0gPQ0KICDilIIgICAgICB8IEludCBvZiBpbnQN CiAg4pSCICAgICAgfCBBZGQNCiAg4pSCICAgICAgfCBBcHAgb2YgdGVybSAq IHRlcm0NCiAg4pSCIA0KICDilIIgICBsZXQgcmVjIGZvbGQgaSBmID0gZnVu Y3Rpb24NCiAg4pSCICAgICB8IEludCBfIGFzIHQgLT4gZiBpIHQNCiAg4pSC ICAgICB8IEFkZCAtPiBmIGkgQWRkDQogIOKUgiAgICAgfCBBcHAgKHgsIHkp IGFzIHQgLT4gZiAoZm9sZCAoZm9sZCBpIGYgeCkgZiB5KSB0DQogIOKUgiBl bmQNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAg4oCmIGJ1dCB1c2luZyBhIEdB RFQ6DQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBtb2R1bGUgR2FkdCA9 DQogIOKUgiBzdHJ1Y3QNCiAg4pSCICAgdHlwZSBfIHRlcm0gPQ0KICDilIIg ICAgICB8IEludCA6IGludCAtPiBpbnQgdGVybQ0KICDilIIgICAgICB8IEFk ZCA6IChpbnQgLT4gaW50IC0+IGludCkgdGVybQ0KICDilIIgICAgICB8IEFw cCA6ICgnYiAtPiAnYSkgdGVybSAqICdiIHRlcm0gLT4gJ2EgdGVybQ0KICDi lIIgDQogIOKUgiAgIGxldCByZWMgZm9sZCA6IHR5cGUgYS4gJ3IgLT4gKCdy IC0+IF8gdGVybSAtPiAncikgLT4gJ3IgPSBmdW4gaSBmIC0+IGZ1bmN0aW9u DQogIOKUgiAgICAgfCBJbnQgXyBhcyB0IC0+IGYgaSB0DQogIOKUgiAgICAg fCBBZGQgLT4gZiBpIEFkZA0KICDilIIgKCoNCiAg4pSCICAgICAgXiBFcnJv cjogVGhpcyBwYXR0ZXJuIG1hdGNoZXMgdmFsdWVzIG9mIHR5cGUgKGludCAt PiBpbnQgLT4gaW50KSB0ZXJtDQogIOKUgiAJYnV0IGEgcGF0dGVybiB3YXMg ZXhwZWN0ZWQgd2hpY2ggbWF0Y2hlcyB2YWx1ZXMgb2YgdHlwZSBpbnQgdGVy bQ0KICDilIIgCVR5cGUgaW50IC0+IGludCAtPiBpbnQgaXMgbm90IGNvbXBh dGlibGUgd2l0aCB0eXBlIGludA0KICDilIIgKikNCiAg4pSCICAgICB8IEFw cCAoeCwgeSkgYXMgdCAtPiBmIChmb2xkIChmb2xkIGkgZiB4KSBmIHkpIHQN CiAg4pSCIGVuZA0KICDilJTilIDilIDilIDilIANCg0KICBJJ3ZlIHRyaWVk IG90aGVyIHZhcmlhbnRzIG9mIHRoZSBzeW50YXggYW5kIGdvdCBtYW55IGVu Y291cmFnZW1lbnRzDQogIGJ1dCBubyBncmVlbiBmbGFnIGZyb20gdGhlIHR5 cGUtY2hlY2tlci4gIFdoeSBpcyB0aGUgY29tcGlsZXINCiAgZXhwZWN0aW5n IGFuIGludCB0ZXJtIGluIHRoZXJlPyBJIHRob3VnaCB0aGUgd2hvbGUgcG9p bnQgb2YgdGhlIGB0eXBlDQogIGEuIC4uLicgc3ludGF4IHdhcyB0byBhbGxv dyB0aGUgbWF0Y2hlZCB0eXBlIHRvIHZhcnkgZnJvbSBvbmUgcGF0dGVybg0K ICB0byB0aGUgbmV4dD8gIElzIHRoZXJlIGEgd2F5IHRvIGRvIHRoaXM/DQoN Cg0KSXZhbiBHb3RvdmNoaXRzIHJlcGxpZWQNCuKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgA0KDQogIEl0IGlzIHRoZSBsaW1pdGF0aW9uIG9mIHRoZSBsZXQt Ym91bmQgcG9seW1vcnBoaXNtLiBBIHBhcmFtZXRlciBvZiBhDQogIGZ1bmN0 aW9uIGlzIG1vbm9tb3JwaGljIGluIGl0cyBib2R5LiBUaGUgY2xhc3NpY2Fs IGV4YW1wbGUgZG9lc24ndA0KICBldmVuIHJlZmVyZW5jZSBhbnkgR0FEVCwN Cg0KICDilIzilIDilIDilIDilIANCiAg4pSCIGxldCBleGFtcGxlIGYgID0g ZiAiaGVsbG8iLCBmIDQyDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIEl0IHdv bid0IGNvbXBpbGUgZXZlbiB0aG91Z2ggd2UgY2FuIHByb3ZpZGUgYSBwb2x5 bW9ycGhpYyBmdW5jdGlvbg0KICB0aGF0IGNhbiBhcHBsaWVkIGJvdGggdG8g aW50ZWdlcnMgYW5kIHRvIHN0cmluZ3MsIGUuZy4sIGBleGFtcGUgKGZ1biB4 DQogIC0+IHgpJyBzaG91bGQgYmUgcG9zc2libGUsIGJ1dCBub3QsIGJlY2F1 c2Ugb2YgdGhlIGxldC1ib3VuZGVkDQogIHBvbHltb3JwaGlzbS4gVGhlcmUg YXJlIGEgZmV3IHNvbHV0aW9ucyBhdmFpbGFibGUgaW4gT0NhbWwsIHRoZQ0K ICBzaW1wbGVzdCBpcyB0byB1c2UgcmVjb3JkcywgZS5nLiwNCg0KICDilIzi lIDilIDilIDilIANCiAg4pSCIHR5cGUgYXBwID0ge2FwcGx5IDogJ2EuICdh IC0+ICdhfQ0KICDilIIgDQogIOKUgiBsZXQgZXhhbXBsZSB7YXBwbHl9ID0g YXBwbHkgImhlbGxvIiwgYXBwbHkgNDI7Ow0KICDilIIgDQogIOKUgiB2YWwg ZXhhbXBsZSA6IGFwcCAtPiBzdHJpbmcgKiBpbnQgPSA8ZnVuPg0KICDilJTi lIDilIDilIDilIANCg0KICBOb3cgd2UgaGF2ZSBgYXBwJyB0aGF0IGlzIHBv bHltb3JwaGljLiAgSW4geW91ciBjYXNlLCBJIHdvdWxkIGRlZmluZSBhDQog IHZpc2l0b3IgdHlwZSwgZS5nLiwNCg0KICDilIzilIDilIDilIDilIANCiAg 4pSCIHR5cGUgJ3IgdmlzaXRvciA9IHt2aXNpdCA6ICdhLiAnYSB0ZXJtIC0+ ICdyIC0+ICdyfQ0KICDilIIgDQogIOKUgiBsZXQgcmVjIGZvbGQgOiB0eXBl IGEuICdyIC0+ICdyIHZpc2l0b3IgLT4gYSB0ZXJtIC0+ICdyID0NCiAg4pSC ICAgZnVuIGkgZiB0IC0+IG1hdGNoIHQgd2l0aA0KICDilIIgICAgIHwgSW50 IF8gYXMgdCAtPiBmLnZpc2l0IGkgdA0KICDilIIgICAgIHwgQWRkIGFzIHQg LT4gZi52aXNpdCBpIHQNCiAg4pSCICAgICB8IEFwcCAoeCx5KSBhcyB0IC0+ DQogIOKUgiAJbGV0IGkgPSBmb2xkIGkgZiB4IGluDQogIOKUgiAJbGV0IGkg PSBmb2xkIGkgZiB5IGluDQogIOKUgiAJZi52aXNpdCBpIHQNCiAg4pSU4pSA 4pSA4pSA4pSADQoNCg0KSmFjcXVlcyBHYXJyaWd1ZSBhbHNvIHJlcGxpZWQN CuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0K DQogIEFjdHVhbGx5LCB0aGlzIGlzIGEgcmFyZSBjYXNlIHdoZXJlIHVzaW5n IGEgcG9seW1vcnBoaWMgbWV0aG9kIG1heSBiZQ0KICBoYW5keSB0b286DQoN CiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBsZXQgcmVjIGZvbGQgOiB0eXBl IGEgci4gciAtPiA8diA6ICdiLiByIC0+ICdiIHRlcm0gLT4gcj4gLT4gYSB0 ZXJtIC0+IHIgPQ0KICDilIIgICAgICBmdW4gaSBmIC0+IGZ1bmN0aW9uDQog IOKUgiAgICAgIHwgSW50IF8gYXMgdCAtPiBmI3YgaSB0DQogIOKUgiAgICAg IHwgQWRkIC0+IGYjdiBpIEFkZA0KICDilIIgICAgICB8IEFwcCAoeCwgeSkg YXMgdCAtPiBmI3YgKGZvbGQgKGZvbGQgaSBmIHgpIGYgeSkgdA0KICDilIIg DQogIOKUgiBsZXQgdiA9DQogIOKUgiAgICBvYmplY3QgbWV0aG9kIHYgOiB0 eXBlIGEuIF8gLT4gYSBHYWR0LnRlcm0gLT4gXyA9DQogIOKUgiAgICAgIGZ1 biB4IC0+IGZ1bmN0aW9uDQogIOKUgiAgICAgICAgfCBJbnQgbiAtPiB4K24N CiAg4pSCICAgICAgICB8IEFkZCAtPiB4KzENCiAg4pSCICAgICAgICB8IEFw cCBfIC0+IHgrMg0KICDilIIgICAgZW5kDQogIOKUgiANCiAg4pSCIGxldCBy ID0gR2FkdC5mb2xkIDAgdiAoQXBwIChBcHAgKEFkZCwgSW50IDMpLCBJbnQg NSkpDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIFRoZSBwb2ludCBiZWluZyB0 aGF0IHRvIG1hdGNoIG9uIGEgR2FkdCB5b3Ugd2lsbCBhbnl3YXkgbmVlZCB0 byB1c2UNCiAgdGhlICh0eXBlIGEpIGNvbnN0cnVjdCB0byBhbGxvdyByZWZp bmVtZW50Lg0KDQoNCnJpeGVkIGFza2VkIGFuZCBJdmFuIEdvdG92Y2hpdHMg cmVwbGllZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgICAg ICAgU28gdGhlcmUgaXMgbm8gbGlnaHRlciBzeW50YXggdG8gc3BlY2lmeSB0 aGF0IGBmJyBzaG91bGQNCiAgICAgICAgYWNjZXB0IGFueSBtZW1iZXIgb2Yg YSBHQURUIHRoYW4gdGhlIHN5bnRheCB0byBzcGVjaWZ5DQogICAgICAgIHRo YXQgYGYnIHNob3VsZCBhY2NlcHQgYW55IHR5cGUgYXQgYWxsPw0KDQogIE9u bHkgdGhyZWUgbWV0aG9kcyBvZiBpbnRyb2R1Y2luZyByYW5rLTIgcG9seW1v cnBoaXNtIGFyZSBrbm93biB0byBtZToNCiAgMS4gcmVjb3Jkcw0KICAyLiBv YmplY3RzDQogIDMuIGZpcnN0LWNsYXNzIG1vZHVsZXMNCg0KICBKYWNxdWVz IGhhcyBkZW1vbnN0cmF0ZWQgdGhlIHNvbHV0aW9uIHdpdGggb2JqZWN0cywg d2hpY2ggbWlnaHQgYmUgYQ0KICBsaXR0bGUgYml0IG1vcmUgbGlnaHR3ZWln aHQsIGF0IGxlYXN0IGFzIHlvdSBkb24ndCBuZWVkIHRvIGRlZmluZSBhDQog IG5ldyBkYXRhIHR5cGUgYmVmb3JlaGFuZC4gQnV0IHRoZSBpbnZvY2F0aW9u IGlzIG1vcmUgdmVyYm9zZSBhbmQNCiAgcmVxdWlyZXMgYW4gYW5ub3RhdGlv biBmcm9tIHRoZSBjYWxsZXIgc2lkZSwgd2hpY2ggY291bGQgYmUNCiAgY29u ZnVzaW5nLiBUaGUgdGhpcmQgc29sdXRpb24gcmVsaWVzIG9uIGZpcnN0LWNs YXNzIG1vZHVsZXMgYW5kIGlzDQogIGV2ZW4gbW9yZSB2ZXJib3NlLCBhdCBs ZWFzdCBvbiB0aGUgZGVmaW5pdGlvbiBzaWRlLiBKdXN0IGZvciB0aGUgc2Fr ZQ0KICBvZiBjb21wbGV0ZW5lc3MsDQoNCiAg4pSM4pSA4pSA4pSA4pSADQog IOKUgiAgIG1vZHVsZSB0eXBlIFZpc2l0b3IgPSBzaWcNCiAg4pSCICAgICB0 eXBlIHQNCiAg4pSCICAgICB2YWwgdGVybSA6IHQgLT4gJ2EgdGVybSAtPiB0 DQogIOKUgiAgIGVuZA0KICDilIIgDQogIOKUgiAgIGxldCByZWMgZm9sZCA6 IHR5cGUgYSByLiByIC0+IChtb2R1bGUgVmlzaXRvciB3aXRoIHR5cGUgdCA9 IHIpIC0+IGEgdGVybQ0KICDilIIgLT4gciA9DQogIOKUgiAgICAgZnVuIGkg KChtb2R1bGUgVmlzaXQpIGFzIGYpIHQgLT4gbWF0Y2ggdCB3aXRoDQogIOKU giAgICAgICB8IEludCBfIGFzIHQgLT4gVmlzaXQudGVybSBpIHQNCiAg4pSC ICAgICAgIHwgQWRkIGFzIHQgLT4gVmlzaXQudGVybSBpIHQNCiAg4pSCICAg ICAgIHwgQXBwICh4LHkpIGFzIHQgLT4NCiAg4pSCIAkgIGxldCBpID0gZm9s ZCBpIGYgeCBpbg0KICDilIIgCSAgbGV0IGkgPSBmb2xkIGkgZiB5IGluDQog IOKUgiAJICBWaXNpdC50ZXJtIGkgdA0KICDilIIgDQogIOKUgiAgIGxldCBz ID0gZm9sZCAwIChtb2R1bGUgc3RydWN0DQogIOKUgiAgICAgICB0eXBlIHQg PSBpbnQNCiAg4pSCICAgICAgIGxldCB0ZXJtIHggXyA9IHggKyAxDQogIOKU giAgICAgZW5kKQ0KICDilJTilIDilIDilIDilIANCg0KICBBbmQgYWdhaW4s IGl0IGlzIG5vdCBhYm91dCBHQURULiBHQURUIGFjdCBhcyBhIHJlZCBoZXJy aW5nIGhlcmUuIEFzDQogIEkndmUgZGVtb25zdHJhdGVkIGVhcmxpZXIsIHVz aW5nIGEgc2ltcGxlIHBhaXIgd2lsbCBzdWZmaWNlIHRvIGRpc3BsYXkNCiAg dGhlIGxpbWl0YXRpb24gb2YgdGhlIHByZW5leCBwb2x5bW9ycGhpc20uIEV2 ZW4gbm8gQURUIGlzIHJlcXVpcmVkLA0KICBqdXN0IGFwcGx5IG9uZSB0ZXJt IHRvIGFub3RoZXIgdHdvIGFuZCB5b3Ugd2lsbCBnZXQgdGhlbSB1bmlmaWVk LA0KICBlLmcuLA0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgbGV0IGYg ZyB4IHkgOiB1bml0ID0gZyB4OyBnIHkNCiAg4pSU4pSA4pSA4pSA4pSADQoN CiAgd2lsbCBoYXZlIHR5cGUNCg0KICDilIzilIDilIDilIDilIANCiAg4pSC IHZhbCBmIDogKCdhIC0+IHVuaXQpIC0+ICdhIC0+ICdhIC0+IHVuaXQNCiAg 4pSU4pSA4pSA4pSA4pSADQoNCiAgYmVjYXVzZSAnYSBpcyBxdWFudGlmaWVk IG9uIHRoZSBzY29wZSBvZiBgZicgbm90IGBnJywgaW4gb3RoZXIgd29yZHMs DQogIGl0IGhhcyB0eXBlIChub3QgYW4gT0NhbWwgc3ludGF4KQ0KDQogIOKU jOKUgOKUgOKUgOKUgA0KICDilIIgdmFsIGYgOiBmb3JhbGwgJ2EuICgnYSAt PiB1bml0KSAtPiAnYSAtPiAnYSAtPiB1bml0DQogIOKUlOKUgOKUgOKUgOKU gA0KDQogIHdoaWxlIHdlIHdvdWxkIGxpa2UgdG8gaGF2ZSBhIHR5cGUNCg0K ICDilIzilIDilIDilIDilIANCiAg4pSCIHZhbCBmIDogZm9yYWxsICdiLCAn Yy4gKGZvcmFsbCAnYS4gJ2EgLT4gdW5pdCkgLT4gJ2IgLT4gJ2MgLT4gdW5p dA0KICDilJTilIDilIDilIDilIANCg0KICBPQ2FtbCBkb2Vzbid0IGFsbG93 IHVzIHRvIGRlZmluZSB0eXBlcyBsaWtlIGAoJ2EuICdhIC0+ICdhKScgYW5k IHRoZQ0KICByZWFzb24gaXMgbm90IHRoYXQgaXQgaXMgaGFyZCB0byBleHRl bmQgdGhlIHBhcnNlciBpdCBpc+KApg0KDQogICAgICAgIEkgd29uZGVyLCBp cyB0aGlzIGp1c3QgYSBsaW1pdGF0aW9uIG9mIHRoZSBPQ2FtbCBwYXJzZXIg b3INCiAgICAgICAgaXMgdGhlcmUgc29tZSBkZWVwIHJlYXNvbiBmb3IgdGhl c2Ugd29yay1hcm91bmQgKGxpa2UgaXMNCiAgICAgICAgdGhlIGNhc2UsIGZy b20gbXkgdW5kZXJzdGFuZGluZywgZm9yIHRoZSB2YWx1ZQ0KICAgICAgICBy ZXN0cmljdGlvbik/DQoNCiAgWWVwLCBnb29kIGNhdGNoISBJdCBpcyBiZWNh dXNlIG9mIHRoZSBpbXB1cml0eS4gSW5kZWVkLCBIYXNrZWxsIGhhcw0KICB0 aGUgUmFuazJUeXBlcyBleHRlbnNpb24gdGhhdCBsZXRzIHVzIHdyaXRlIHR5 cGVzIGxpa2UgYChmb3JhbGwgYS4gYQ0KICAtPiAoKSkgLT4gYiAtPiBjIC0+ ICgpJywgd2l0aCBubyBleHRyYSBzeW50YWN0aWMgYnVyZGVuIChtb2R1bG8g aGF2aW5nDQogIHRvIHByb3ZpZGUgdGhlIHR5cGUgYW5ub3RhdGlvbikuIEJ1 dCBmdW5jdGlvbnMgaW4gSGFza2VsbCBhcmUgcHVyZSwNCiAgdGhlcmVmb3Jl IGl0IGlzIHBvc3NpYmxlLiBUbyBtYWtlIHRoZSBzdG9yeSBzaG9ydCBhbmQg b2J2aW91cywgbGV0IG1lDQogIGRvIGEgc2ltcGxlIGRlbW9uc3RyYXRpb24g b2YgaG93IHRoaW5ncyBjYW4gZ28gd3JvbmcgaW4gYSBsYW5ndWFnZQ0KICB3 aXRoIHNpZGUtZWZmZWN0cy4gIExldCdzIGdvIGJhY2sgdG8gdGhlIHNpbXBs ZSBleGFtcGxlIG9mIHBhaXJzIGFuZA0KICB0aGUgaWRlbnRpdHkgZnVuY3Rp b24uICBDb25zaWRlciB0aGUgZm9sbG93aW5nIG5hc3R5IGlkZW50aXR5DQog IGZ1bmN0aW9uLA0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgbGV0IGJh ZF9pZCAoKSA9DQogIOKUgiAgIGxldCBjYWNoZSA9IHJlZiBOb25lIGluDQog IOKUgiAgIGZ1biB4IC0+IG1hdGNoIGNhY2hlLmNvbnRlbnRzIHdpdGgNCiAg 4pSCICAgICB8IE5vbmUgLT4gY2FjaGUgOj0gU29tZSB4OyB4DQogIOKUgiAg ICAgfCBTb21lIGNhY2hlIC0+IGNhY2hlDQogIOKUlOKUgOKUgOKUgOKUgA0K DQogIEl0IGhhcyB0eXBlIGB1bml0IC0+ICdhIC0+ICdhJyB0aGVyZWZvcmUs IGlmIHdlIHdvdWxkIGhhdmUgdGhlIHJhbmstMQ0KICBwb2x5bW9ycGhpc20g ZW5hYmxlZCBmb3IgZnVuY3Rpb25zLCB3ZSBjb3VsZCBhcHBseSBpdCB0byB0 aGUgZnVuY3Rpb24NCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIGxldCBt YXAyIDogZnVuICgnYS4gJ2EgLT4gJ2EpIC0+ICdiIC0+ICdjIC0+ICdiICog J2MgPSBmdW4gZiAoeCx5KSAtPiBmIHgsIGYgeQ0KICDilJTilIDilIDilIDi lIANCg0KICBhcw0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgbGV0IHgs eSA6IHN0cmluZyAqIGludCA9IG1hcDIgKGJhZF9pZCAoKSkgImhlbGxvIiwg NDINCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgYW5kIHdpbGwgZ2V0IGEgc2Vn bWVudGF0aW9uIGZhdWx0LCBhcyBgeScgd2lsbCBub3cgaGF2ZSB0eXBlIGlu dCBidXQNCiAgaG9sZCBhIHN0cmluZy4NCg0KICBBbmQgaGVyZSBjb21lcyB0 aGUgc3ludGF4IGFzIGEgc2F2aW9yIGFzIGl0IGxldHMgdXMgc3BlY2lmeSBm dW5jdGlvbnMNCiAgdGhhdCBhcmUgZ3VhcmFudGVlZCB0byBiZSBzeW50YWN0 aWMgdmFsdWVzLiBJbmRlZWQsIGFsbCB0aHJlZQ0KICBzb2x1dGlvbnMgc3lu dGFjdGljYWxseSBndWFyYW50ZWUgdGhhdCB0aGUgcHJvdmlkZWQgYXJndW1l bnQgaXMgYQ0KICBmdW5jdGlvbiwgbm90IGEgY2xvc3VyZS4gSW5kZWVkLCBs ZXQncyBpbnRyb2R1Y2UgdGhlIHVuaXZlcnNhbA0KICBpZGVudGl0eSB2aWEg YSByZWNvcmQsDQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiB0eXBlIGlk ID0geyBmIDogJ2EuICdhIC0+ICdhfQ0KICDilJTilIDilIDilIDilIANCg0K ICBhbmQgd2UgY2FuIHNlZSB0aGF0IG91ciBgYmFkX2lkJyBpcyBub3QgYWNj ZXB0ZWQgZHVlIHRvIHRoZSB2YWx1ZQ0KICByZXN0cmljdGlvbiwgd2hpbGUg Z29vZF9pZCwgZGVmaW5lZCBhcywNCg0KICDilIzilIDilIDilIDilIANCiAg 4pSCIGxldCBnb29kX2lkIHggPSB4DQogIOKUlOKUgOKUgOKUgOKUgA0KDQog IGlzIHBlcmZlY3RseSBmaW5lLCBlLmcuLA0KDQogIOKUjOKUgOKUgOKUgOKU gA0KICDilIIgbGV0IGlkMSA9IHtmID0gZ29vZF9pZH0gKCphY2NlcHRlZCAq KQ0KICDilIIgbGV0IGlkMiA9IHtmID0gYmFkX2lkfSAgICgqIHJlamVjdGVk ICopDQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIG1vcmVvdmVyLCBldmVuIGEg ZmluZSwgYnV0IG5vdCBzeW50YWN0aWMsIGlkZW50aXR5IGlzIGFsc28gcmVq ZWN0ZWQNCg0KICDilIzilIDilIDilIDilIANCiAg4pSCIGxldCBmaW5lX2lk ICgpIHggPSB4DQogIOKUgiBsZXQgaWQzID0ge2YgPSBmaW5lX2lkICgpfSAo KiByZWplY3RlZCAqKQ0KICDilJTilIDilIDilIDilIANCg0KICB3aXRoIHRo ZSBtZXNzYWdlDQoNCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBUaGlzIGZp ZWxkIHZhbHVlIGhhcyB0eXBlICdiIC0+ICdiIHdoaWNoIGlzIGxlc3MgZ2Vu ZXJhbCB0aGFuICdhLiAnYSAtPiAnYQ0KICDilJTilIDilIDilIDilIANCg0K ICBUaGUgc2FtZSBpcyB0cnVlIHdpdGggbW9kdWxlcywNCg0KICDilIzilIDi lIDilIDilIANCiAg4pSCIG1vZHVsZSB0eXBlIElkID0gc2lnDQogIOKUgiAg IHZhbCBmIDogJ2EgLT4gJ2ENCiAg4pSCIGVuZA0KICDilIIgbW9kdWxlIElk MSA6IElkID0gc3RydWN0IGxldCBmID0gZ29vZF9pZCBlbmQgICAoKiBhY2Nl cHRlZCAqKQ0KICDilIIgbW9kdWxlIElkMiA6IElkID0gc3RydWN0IGxldCBm ID0gYmFkX2lkICgpIGVuZCAoKiByZWplY3RlZCAqKQ0KICDilIIgbW9kdWxl IElkMyA6IElkID0gc3RydWN0IGxldCBmID0gZmluZV9pZCAoKSBlbmQgKCog cmVqZWN0ZWQgKikNCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgYW5kIHdpdGgg b2JqZWN0cyAobGVmdCBhcyBhbiBleGVyY2lzZSkuDQoNCiAgVG8gc3VtbWFy aXplLCBpbiBvcmRlciB0byBlbmFibGUgcmFuazIgcG9seW1vcnBoaXNtIHdl IG5lZWQgYSBzcGVjaWFsDQogIGtpbmQgb2YgdmFsdWVzIHRvIGJlYXIgdW5p dmVyc2FsIGZ1bmN0aW9ucywgYXMgd2UgY2FuJ3QgcmVseSBvbg0KICBvcmRp bmFyeSBmdW5jdGlvbnMsIHdoaWNoIGNvdWxkIGJlIGNvbnN0cnVjdGVkIHVz aW5nIHBhcnRpYWwNCiAgYXBwbGljYXRpb24uIE9DYW1sIGFscmVhZHkgaGFk IG9iamVjdHMgYW5kIHJlY29yZHMsIHdoaWNoIHNlcnZlIGFzIGENCiAgZmlu ZSBtZWRpYSBmb3IgdW5pdmVyc2FsbHkgcXVhbnRpZmllZCBmdW5jdGlvbnMu IExhdGVyIGZpcnN0IGNsYXNzDQogIG1vZHVsZXMgd2VyZSBpbnRyb2R1Y2Vk LCB3aGljaCBjb3VsZCBhbHNvIGJlIHVzZWQgZm9yIHRoZSBzYW1lDQogIHB1 cnBvc2UuIFByb2JhYmx5LCBvbmUgY291bGQgZGV2aXNlIGEgc3BlY2lhbCBz eW50YXggKG9yIHJlbHkgb24gdGhlDQogIG5ldyBhdHRyaWJ1dGVzIGFuZCBl eHRlbnNpb25zIHN5bnRheCwgZS5nLiwgYG1hcDIgWyVyYW5rMiA6IGZ1biB4 IC0+DQogIHhdICgiaGVsbG8iLDQyKScgYnV0IHByb2JhYmx5IHRoaXMgd2ls bCBsZWFkIHRvIGFuIHVubmVjZXNzYXJ5DQogIGJsb2F0aW5nIG9mIHRoZSBs YW5ndWFnZSBhbmQgdGhlIGltcGxlbWVudGF0aW9uLCBlc3BlY2lhbGx5IHNp bmNlIHdlDQogIGFscmVhZHkgaGF2ZSB0aHJlZSBzb2x1dGlvbnMgd2l0aCBh IG1vcmUgb3IgbGVzcyB0b2xlcmFibGUgc3ludGF4IChhbmQNCiAgYXJlIGlu IHRoZSBiYXNlIGxhbmd1YWdlLCBub3QgYW4gZXh0ZW5zaW9uKS4gIEJlc2lk ZXMsIGlmIHdlIHdpbGwgdXNlDQogIHRoZSBgW0BAdW5ib3hlZF0nIGFubm90 YXRpb24sIG9yIHZpc2l0b3Igd2lsbCBoYXZlIHRoZSBzYW1lDQogIHJlcHJl c2VudGF0aW9uIGFzIGEgZnVuY3Rpb24sIGUuZy4sDQoNCiAg4pSM4pSA4pSA 4pSA4pSADQogIOKUgiB0eXBlICdyIHZpc2l0b3IgPSB7dmlzaXQgOiAnYS4g J3IgLT4gJ2EgdGVybSAtPiAncn0gW0BAdW5ib3hlZF0NCiAg4pSCIGxldCBj b3VudCB4IF8gPSB4ICsgMQ0KICDilIIgbGV0IGNvdW50ZXIgPSB7dmlzaXQ9 Y291bnR9DQogIOKUlOKUgOKUgOKUgOKUgA0KDQogIGFuZA0KDQogIOKUjOKU gOKUgOKUgOKUgA0KICDilIIgIyBDb3JlX2tlcm5lbC5waHlzX3NhbWUgY291 bnQgY291bnRlcjs7DQogIOKUgiAtIDogYm9vbCA9IHRydWUNCiAg4pSU4pSA 4pSA4pSA4pSADQoNCiAgQ29uY2VybmluZyByYW5rLW4gcG9seW1vcnBoaXNt LCBpbiBPQ2FtbCBpcyBpcyBhY2hpZXZlZCB1c2luZw0KICBmdW5jdG9ycy4g IFllcywgdGhleSBhcmUgYSBsaXR0bGUgYml0IHN5bnRhY3RpY2FsbHkgaGVh dnkgYW5kIGZvcmNlIHVzDQogIHRvIHdyaXRlIHNpZ25hdHVyZXMsIGJ1dCB0 aGlzIGlzIG5lY2Vzc2FyeSBhbnl3YXkgYXMgcmFuay1uIGlzDQogIHVuZGVj aWRhYmxlIChub24taW5mZXJyYWJsZSkuIEZpbmFsbHksIGFzIGEgcmVhbC13 b3JsZCBleGFtcGxlIFsxXSBvZg0KICByYW5rLTIgcG9seW1vcnBoaXNtIGNv bnNpZGVyIHRoZSB1bml2ZXJzYWwgV0FWTCB0cmVlIHRoYXQgaXMgYSBiaW5h cnkNCiAgdHJlZSB3aXRoIGVhY2ggZWxlbWVudCBoYXZpbmcgYSBkaWZmZXJl bnQgdHlwZSAoYWthIGhldGVyb2dlbmVvdXMNCiAgbWFwKS4gV2UgdXNlIGl0 IGluIEJBUCBhcyBhIGJhY2tpbmcgc3RvcmUuIFlvdSBtaWdodCBmaW5kIGEg ZmV3IHRyaWNrcw0KICB0aGVyZSwgZXNwZWNpYWxseSB1c2luZyBjb250aW51 YXRpb24tcGFzc2luZyBpbiB0aGUgcmVjdXJzaXZlIGNhc2VzLg0KDQogIENo ZWVycywgSXZhbg0KDQogIFsxXToNCiAgPGh0dHBzOi8vZ2l0aHViLmNvbS9C aW5hcnlBbmFseXNpc1BsYXRmb3JtL2JhcC9ibG9iL2I0MDY4OWU2MzY2MDdi OTc3NzU4YWYwNDhiNzlkNjU2ODRjZTQ4YzMvbGliL2tub3dsZWRnZS9iYXBf a25vd2xlZGdlLm1sI0w4NDctTDE2OTM+DQoNCg0KTWFsY29sbSBNYXRhbGth IGFza2VkIGFuZCBJdmFuIEdvdG92Y2hpdHMgcmVwbGllZA0K4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSADQoNCiAgICAgICAgV2h5IGlzIHR5cGUgY2hlY2tpbmcgY3JlYXRpbmcg YSByZWNvcmQgZGlmZmVyZW50IHRoYW4gdHlwZQ0KICAgICAgICBjaGVja2lu ZyBhIGZ1bmN0aW9uIGFyZ3VtZW50Pw0KDQogICAgICAgIElmIHdlIGhhZCB0 aGUgc3ludGF4IChvciBzb21ldGhpbmcgbGlrZSBpdCk6DQoNCiAgICAgICAg bGV0IG1hcDIgOiAoJ2EuICdhIC0+ICdhKSAtPiAoJ2IgKiAnYykgLT4gKCdi ICogJ2MpDQoNCiAgICAgICAgV2h5IHdvdWxkIHRoZSB0eXBlIGNoZWNrZXIg bm90IGJlIGFibGUgdG8gc2VlIHRoYXQNCg0KICAgICAgICBtYXAyIGdvb2Rf aWQgKCJoaSIsIDQyKQ0KDQogICAgICAgIGlzIHZhbGlkIGJ1dA0KDQogICAg ICAgIG1hcDIgKGZpbmVfaWQgKCkpICgiaGkiLCAzMikNCg0KICAgICAgICBp cyBub3QsIHVzaW5nIHRoZSBzYW1lIGxvZ2ljIHRoYXQgaXMgdmVyaWZ5aW5n IGNyZWF0aW5nDQogICAgICAgIHRoZSAiaWQiIHJlY29yZCBpcyBub3QgdmFs aWQ/DQoNCiAgSSBiZWxpZXZlIGl0IGlzIHBvc3NpYmxlLCBhcyBpdCBpcyBw b3NzaWJsZSBpbiBIYXNrZWxsICh3aXRoDQogIFJhbmtOVHlwZXMgYW5kIFNj b3BlZFR5cGVWYXJpYWJsZXMpLiBUaGUgbWFpbiAodGhlb3JldGljYWwpIGRp ZmZlcmVuY2UNCiAgaXMgdGhhdCBpbiBPQ2FtbCB3ZSBuZWVkIHRvIGNoZWNr IHdoZXRoZXIgYW4gZXhwcmVzc2lvbiBpcyBleHBhbnNpdmUNCiAgYW5kIHVz ZSBhIHNwZWNpYWxpemVkIGdlbmVyYWxpemF0aW9uIGluIGNhc2UgaWYgaXQg aXMgKGZvciB0aGUgcmVsYXhlZA0KICB2YWx1ZSByZXN0cmljdGlvbikuIEl0 IHdpbGwsIGhvd2V2ZXIsIGNvbXBsaWNhdGUgdGhlIHR5cGUgaW5mZXJlbmNl DQogIGVuZ2luZSBhIGxvdCwgYnV0IG1vc3QgaW1wb3J0YW50bHksIGNoYW5n aW5nIHRoZSB0eXBpbmcgcnVsZSBvZg0KICBmdW5jdGlvbnMgd2lsbCBoYXZl IGEgdHJlbWVuZG91cyBpbXBhY3Qgb24gdGhlIGxhbmd1YWdlLiBTbyB0aGlz IHdvdWxkDQogIGJlIGEgdmVyeSBpbXByYWN0aWNhbCBzb2x1dGlvbi4gIEVz cGVjaWFsbHksIHNpbmNlIHdlIGRvbid0IGhhdmUgdGhlDQogIG1lY2hhbmlz bSBvZiBsYW5ndWFnZSBleHRlbnNpb25zLCBlbmFibGluZyBSYW5rTlR5cGVz IHdpbGwgbWFrZSBhIGxvdA0KICBvZiBwcm9ncmFtcyB1bnR5cGVhYmxlLCBh cyB0aGV5IHdpbGwgbm93IHJlcXVpcmUgdHlwZSBhbm5vdGF0aW9ucw0KICAo cmVjYWxsIHRoYXQgUmFua04gaXMgdW5kZWNpZGFibGUgaW4gZ2VuZXJhbCku ICBJdCBjb3VsZCBwcm9iYWJseSBiZQ0KICBpbXBsZW1lbnRlZCBhcyBhIGNv bXBpbGVyIGNvbW1hbmQgbGluZSBwYXJhbWV0ZXIsIGxpa2UgYC1yZWN0eXBl cycgYnV0DQogIHRoaXMgd2lsbCBiZSBzdGlsbCBxdWl0ZSBpbXByYWN0aWNh bCBzaW5jZSBtb3JlIG9mdGVuIGNvZGUgbGlrZSBgZnVuIGYNCiAgLT4gZiAx LCBmIHRydWUnIGlzIGEgcHJvZ3JhbW1lciBlcnJvciwgcmF0aGVyIHRoYW4g YSB0cnVlIHJlcXVlc3QgZm9yDQogIHVuaXZlcnNhbCBwb2x5bW9ycGhpc20g KHRoZSBzYW1lIGFzIHdpdGggcmVjdHlwZXMsIHJlY3Vyc2l2ZSB0eXBlcyBh DQogIG1vcmUgb2Z0ZW4gYW4gZXJyb3IgcmF0aGVyIHRoYW4gYSBkZWxpYmVy YXRlIGF0dGVtcHQpLiBUaGVyZWZvcmUsDQogIGVuYWJsaW5nIFJhbmtOKF4x KSBwb2x5bW9ycGhpc20gd2lsbCB0eXBlIHRvbyBtYW55IHByb2dyYW1zIChu b3QgdGhhdA0KICBpdCBpcyB1bnNvdW5kLCBqdXN0IG1hbnkgcHJvZ3JhbXMg d29uJ3QgaGF2ZSBzZW5zZSkgYXQgdGhlIGNvc3Qgb2YNCiAgZXZlbiBtb3Jl IG9ic2N1cmUgdHlwZSBlcnJvcnMuIE9uIHRoZSBvdGhlciBoYW5kLCB3ZSBo YXZlIHRocmVlDQogIHN5bnRhY3RpYyBjb25zdHJ1Y3RzIHRoYXQgbGV0IHVz IGV4cHJlc3Mgbm9uLXByZW5leCBwb2x5bW9ycGhpc20gb2YNCiAgdGhlIG5l Y2Vzc2FyeSByYW5rKF4yKSB3aXRob3V0IGJyZWFraW5nIGFueXRoaW5nIGVs c2UuIFNvIGl0IGxvb2tzDQogIGxpa2UgYSBnb29kIGRlYWwgLSB3ZSBjYW4g aGF2ZSByYW5rTiBwb2x5bW9ycGhpc20gYW5kIGRlY2lkYWJsZSB0eXBlDQog IGNoZWNrZXIgYXQgdGhlIHNhbWUgdGltZS4gSnVzdCB0aGluayBvZiBwb2x5 bW9ycGhpYyByZWNvcmRzL21ldGhvZHMgYXMNCiAgYW4gZW1iZWRkZWQgRFNM IGZvciByYW5rTiBwb2x5bW9ycGhpc20uDQoNCiAgYD09PT09PT09PT0nIEZv b3Rub3RlczoNCg0KICAxKSBBbiBpbXBvcnRhbnQgcG9pbnQsIHRoYXQgSSBm b3Jnb3QgdG8gbm90aWNlLCBpcyB0aGF0IGVuYWJsaW5nDQogICAgIHNjb3Bl ZA0KICB0eXBlIHZhcmlhYmxlcywgd2lsbCBpbmV2aXRhYmx5IGVuYWJsZSBy YW5rTiBwb2x5bW9ycGhpc20sIGUuZy4sIHNpbmNlDQogIG5vdyBhbnkgdHlw ZSBjb3VsZCBiZSBhIHBvbHl0eXBlLCB0aGVuIHN1cHBvc2Ugd2UgaGF2ZSB0 eXBlDQogIGAnYS4gKCdiLidiIC0+ICdhKSAtPiAnYScgY291bGQgYmUgaW5z dGFudGlhdGVkIHRvICdhID0gJ2QuICgnYy4gLT4NCiAgJ2QpIC0+ICdkLCBz byB0aGF0IG91ciB0eXBlIGlzIG5vdyBgJ2QuICgnYi4gJ2IgLT4gKCdjLiAn YyAtPiAnZCkgLT4NCiAgJ2QpIC0+ICgnYy4gJ2MgLT4gJ2QpIC0+ICdkJyB3 aGljaCBpcyBub3cgcmFuazMuIFRoZXJlZm9yZSwgZW5hYmxpbmcNCiAgYXJi aXRyYXJ5IHF1YW50aWZpY2F0aW9uIGluIHRoZSBhcnJvdyB0eXBlIHdpbGwg bGVhZCB0byByYW5rTiBhbmQNCiAgaW1tZWRpYXRlbHkgbWFrZSB1bmRlY2lk YWJsZSBtb3N0IG9mIHRoZSB0eXBlIGNoZWNrZXIuDQoNCiAgMSkgV2UgY2Fu IGNyYWZ0IGFyYml0cmFyeSByYW5rIHVzaW5nIHJlY29yZHMgd2l0aCB1bml2 ZXJzYWxseQ0KICAgICBxdWFudGlmaWVkDQogIHR5cGUgdmFyaWFibGVzLCBl LmcuLCBoZXJlIGlzIGFuIGV4YW1wbGUgb2YgcmFuazMgcG9seW1vcnBoaXNt Og0KDQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgdHlwZSAnYSByYW5rMSA9 IHtmMSA6ICdzLiAncyAtPiAnYX0NCiAg4pSCIHR5cGUgJ2EgcmFuazIgPSB7 ZjIgOiAnci4gJ3IgLT4gJ2EgcmFuazF9DQogIOKUlOKUgOKUgOKUgOKUgA0K DQogIEluZGVlZCwgYGYyJyBoYXMgdHlwZSBgJ2EuKCdyLiAnciAtPiAoJ3Mu ICdzIC0+ICdhKScNCg0KDQpPQ2FtbFBybydzIG9wYW0gY2hlYXQgc2hlZXQs IHdpdGggYSBuZXcgdGhlbWUhDQrilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZlOg0KICA8aHR0 cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90L3JmYy1vY2FtbHByb3Mtb3BhbS1j aGVhdC1zaGVldC13aXRoLWEtbmV3LXRoZW1lLzQ2ODkvMz4NCg0KDQpUaG9t YXMgQmxhbmMgYW5ub3VuY2VkDQrilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIANCg0K ICBUaGUgb3BhbSBjaGVhdC1zaGVldCBpcyBub3cgcHVibGlzaGVkIGluIGl0 cyBmaW5hbCBmb3JtLg0KDQogIFlvdSBjYW4gZ2V0IHRoZSBbY29sb3JlZF0g YW5kIFtibGFjay1hbmQtd2hpdGVdIHZlcnNpb25zIGZyb20gb3VyDQogIHdl YnNpdGUuDQoNCiAgSGFwcHkgaGFja2luZyENCg0KDQpbY29sb3JlZF0NCjxo dHRwOi8vd3d3Lm9jYW1scHJvLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAx OS8xMS9vY2FtbC1vcGFtLnBkZj4NCg0KW2JsYWNrLWFuZC13aGl0ZV0NCjxo dHRwOi8vd3d3Lm9jYW1scHJvLmNvbS93cC1jb250ZW50L3VwbG9hZHMvMjAy MC8wMS9vY2FtbC1vcGFtLWJ3LnBkZj4NCg0KDQpPQ2FtbCA0LjEwLjAsIGZp cnN0IGJldGENCuKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkA0KDQogIEFy Y2hpdmU6IDxodHRwczovL2Rpc2N1c3Mub2NhbWwub3JnL3Qvb2NhbWwtNC0x MC0wLWZpcnN0LWJldGEvNDk4OS8xPg0KDQoNCm9jdGFjaHJvbiBhbm5vdW5j ZWQNCuKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKU gOKUgOKUgOKUgOKUgOKUgA0KDQogIFRoZSByZWxlYXNlIG9mIE9DYW1sIDQu MTAuMCBpcyBhcHByb2FjaGluZy4gV2UgaGF2ZSBwdWJsaXNoZWQgYSBmaXJz dA0KICBiZXRhIHZlcnNpb24gdG8gaGVscCB5b3UgYWRhcHQgeW91ciBzb2Z0 d2FyZSB0byB0aGUgbmV3IGZlYXR1cmVzIGFoZWFkDQogIG9mIHRoZSByZWxl YXNlLg0KDQogIER1cmluZyBvdXIgcHJlbGltaW5hcnkgdGVzdHMgZm9yIHRo aXMgbmV3IGJldGEsIHdlIGRpc2NvdmVyZWQgdGhhdCB0aGUNCiAgcmVjZW50 IHdvcmsgdG93YXJkcyBhIG11bHRpY29yZS1yZWFkeSBPQ2FtbCBydW50aW1l IGludHJvZHVjZWQNCiAgY29tcGF0aWJpbGl0eSBpc3N1ZXMgd2l0aGluIHNv bWUgb3BhbSBwYWNrYWdlcywgdGhhdCB3ZXJlIHR3ZWFraW5nIHRoZQ0KICBy dW50aW1lIGludGVybmFscy4gIE1vc3Qgb2YgdGhvc2Ugb3BhbSBwYWNrYWdl cyBoYXZlIGJlZW4gZml4ZWQsIG9yDQogIHdpbGwgYmUgc29vbi4gIE5ldmVy dGhlbGVzcywgaWYgeW91IGFyZSBhZmZlY3RlZCBieSBzdWNoIGNvbXBhdGli aWxpdHkNCiAgaXNzdWUsIHBsZWFzZSBzcGVhayB1cC4NCg0KICBUaGUgc291 cmNlIGNvZGUgaXMgYXZhaWxhYmxlIGF0IHRoZXNlIGFkZHJlc3NlczoNCg0K ICA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL29jYW1sL2FyY2hpdmUvNC4x MC4wK2JldGExLnRhci5nej4NCiAgPGh0dHBzOi8vY2FtbC5pbnJpYS5mci9w dWIvZGlzdHJpYi9vY2FtbC00LjEwL29jYW1sLTQuMTAuMCtiZXRhMS50YXIu Z3o+DQoNCiAgVGhlIGNvbXBpbGVyIGNhbiBhbHNvIGJlIGluc3RhbGxlZCBh cyBhbiBPUEFNIHN3aXRjaCB3aXRoIG9uZSBvZiB0aGUNCiAgZm9sbG93aW5n IGNvbW1hbmRzLg0KICDilIzilIDilIDilIDilIANCiAg4pSCIG9wYW0gc3dp dGNoIGNyZWF0ZSBvY2FtbC12YXJpYW50cy40LjEwLjArYmV0YTEgLS1yZXBv c2l0b3JpZXM9ZGVmYXVsdCxiZXRhPWdpdCtodHRwczovL2dpdGh1Yi5jb20v b2NhbWwvb2NhbWwtYmV0YS1yZXBvc2l0b3J5LmdpdA0KICDilJTilIDilIDi lIDilIANCiAgb3INCiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiBvcGFtIHN3 aXRjaCBjcmVhdGUgb2NhbWwtdmFyaWFudHMuNC4xMC4wK2JldGExKzxWQVJJ QU5UPiAtLXJlcG9zaXRvcmllcz1kZWZhdWx0LGJldGE9Z2l0K2h0dHBzOi8v Z2l0aHViLmNvbS9vY2FtbC9vY2FtbC1iZXRhLXJlcG9zaXRvcnkuZ2l0DQog IOKUlOKUgOKUgOKUgOKUgA0KICB3aGVyZSB5b3UgcmVwbGFjZSA8VkFSSUFO VD4gd2l0aCBvbmUgb2YgdGhlc2U6DQogIOKAoiBhZmwNCiAg4oCiIGZsYW1i ZGENCiAg4oCiIGZwDQogIOKAoiBmcCtmbGFtYmRhDQoNCiAgV2Ugd2FudCB0 byBrbm93IGFib3V0IGFsbCBidWdzLiBQbGVhc2UgcmVwb3J0IHRoZW0gaGVy ZToNCg0KICA8aHR0cHM6Ly9naXRodWIuY29tL29jYW1sL29jYW1sL2lzc3Vl cz4NCg0KICBIYXBweSBoYWNraW5nLg0KDQoNCkthdGUgYWRkZWQNCuKUgOKU gOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgA0KDQogIEZvciB0aGUgcGVvcGxl IHdhbnRpbmcgdG8gZ2l2ZSBPQ2FtbCA0LjEwLjBiZXRhMSBhIHNob3QsIGhl cmUgaXMgYW4NCiAgb3BhbSBvdmVybGF5IHdoaWNoIGFkZHMgZml4ZXMgdG8g bWFqb3IgcGFja2FnZXMgZm9yIHRoZW0gdG8gd29yayB3aXRoDQogIHRoaXMg YmV0YTogPGh0dHBzOi8vZ2l0aHViLmNvbS9raXQtdHkta2F0ZS9vcGFtLWFs cGhhLXJlcG9zaXRvcnk+DQoNCiAgVG8gdXNlIGl0LCBzaW1wbGUgY2FsbDoN CiAg4pSM4pSA4pSA4pSA4pSADQogIOKUgiAkIG9wYW0gc3dpdGNoIDQuMTAN CiAg4pSCICQgb3BhbSByZXBvc2l0b3J5IGFkZCBhbHBoYSBnaXQ6Ly9naXRo dWIuY29tL2tpdC10eS1rYXRlL29wYW0tYWxwaGEtcmVwb3NpdG9yeS5naXQN CiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgT2J2aW91c2x5LCB0aGlzIHJlcG9z aXRvcnkgc2hvdWxkIG5vdCBiZSB1c2VkIGluIHByb2R1Y3Rpb24gYW5kDQog IHByb2JhYmx5IGNvbnRhaW5zIGEgZmV3IGJ1Z3MsIGJ1dCBhdCBsZWFzdCBp dCBhbGxvd3MgZXZlcnlvbmUgdG8gaGF2ZQ0KICBhbG1vc3QgYXMgbWFueSBw YWNrYWdlcyBhdmFpbGFibGUgYXMgd2l0aCBPQ2FtbCA0LjA5LiBPbmx5IDYw aXNoDQogIHBhY2thZ2VzIGFyZSBzdGlsbCBub3QgYXZhaWxhYmxlLCBidXQg YXBhcnQgZnJvbSB0aGUgbm90YWJsZSBleGNlcHRpb24NCiAgb2YgYG1lcmxp bicgYWxsIHRoZSBlc3NlbnRpYWwgcGFja2FnZXMgYW5kIGRlcGVuZGVuY2ll cyBhcmUgdGhlcmUuDQoNCiAgVGhpcyB3b3JrIGhhcyBiZWVuIHBhcnQgb2Yg dGhlIHJlbGVhc2UtcmVhZHluZXNzIGVmZm9ydCBmb3VuZGVkIGJ5IHRoZQ0K ICBPQ2FtbCBTb2Z0d2FyZSBGb3VuZGF0aW9uIGFzIGFubm91bmNlZCBoZXJl Og0KICA8aHR0cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90L2Fubi10aGUtb2Nh bWwtc29mdHdhcmUtZm91bmRhdGlvbi80NDc2LzEzPg0KDQogIFRoZSByZXN0 IG9mIHRoZSBlZmZvcnQgaXMgZ29pbmcgdG8gYmUgcHV0IHRvd2FyZHMgaGF2 aW5nIGBtZXJsaW4nDQogIGF2YWlsYWJsZSBmb3IgT0NhbWwgNC4xMCBhbmQg dXBzdHJlYW1pbmcgYWxsIHRoZSBmaXhlcyBmcm9tDQogIG9wYW0tYWxwaGEt cmVwb3NpdG9yeSAobW9zdCBvZiB0aGVtIGhhdmUgUFJzIGFzc29jaWF0ZWQg YWxyZWFkeSkuIEknbQ0KICBob3BlZnVsIGZvciB0aGVtIGJlIGFsbCB1cHN0 cmVhbWVkIGFuZCBhdmFpbGFibGUgYmVmb3JlIHRoZSBzdGFibGUNCiAgcmVs ZWFzZSBvZiBPQ2FtbCA0LjEwLg0KDQoNCkRhdGEgZW5naW5lZXIgcG9zaXRp b25zIGF0IEVsYXN0aWMsIFVTL0NhbmFkYS9XZXN0ZXJuIEV1cm9wZSAocHJv eGltYXRlIHRvIE5BIHRpbWV6b25lcykNCuKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkA0KDQogIEFyY2hpdmU6DQogIDxodHRwczov L2Rpc2N1c3Mub2NhbWwub3JnL3Qvam9iLWRhdGEtZW5naW5lZXItcG9zaXRp b25zLWF0LWVsYXN0aWMtdXMtY2FuYWRhLXdlc3Rlcm4tZXVyb3BlLXByb3hp bWF0ZS10by1uYS10aW1lem9uZXMvNDk5MS8xPg0KDQoNCkhlemVraWFoIENh cnR5IGFubm91bmNlZA0K4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoN CiAgT3VyIHRlYW0gaGVyZSBhdCBbRWxhc3RpY10gaGFzIHBvc2l0aW9ucyBv cGVuIGZvciBhIGZldyBzZWN1cml0eSBkYXRhDQogIGVuZ2luZWVycyAoYWth IHdyYW5nbGVycyBvZiBkYXRhIGFuZCBhbGwgdGhlIHN5c3RlbXMgaW52b2x2 ZWQpLiAgV2UNCiAgYXJlIGEgZGlzdHJpYnV0ZWQgY29tcGFueSBzbyB5b3Ug ZG9uJ3QgaGF2ZSB0byBiZSBjbG9zZSB0byBhbiBvZmZpY2UNCiAgdG8gYmUg Y29uc2lkZXJlZC4gIEluZm9zZWMgaW5kdXN0cnkgZXhwZXJpZW5jZSBpcyBf bm90XyByZXF1aXJlZCwNCiAgdGhvdWdoIG9mIGNvdXJzZSB3ZWxjb21lLiAg V2UncmUgc3Vycm91bmRlZCBieSBleHBlcnRzIGluIHRoZSBmaWVsZCBzbw0K ICB5b3UnbGwgaGF2ZSBsb3RzIG9mIG9wcG9ydHVuaXRpZXMgdG8gbGVhcm4g YXMgeW91IGdvIQ0KDQogIFRoZSBvZmZpY2lhbCBwb3N0aW5ncyBhcmUgYXZh aWxhYmxlIGhlcmUgKGJvdGggaGF2ZSB0aGUgc2FtZSB0ZXh0IGFuZA0KICBv bmx5IGRpZmZlciBpbiB0aXRsZS9zZW5pb3JpdHkpOg0KICDigKIgU2VjdXJp dHkgZGF0YSBlbmdpbmVlciAtDQogICAgPGh0dHBzOi8vam9icy5lbGFzdGlj LmNvL2pvYnMvc2VjdXJpdHktc29sdXRpb25zL2FtZXItZGlzdHJpYnV0ZWQt L3NlY3VyaXR5LWRhdGEtZW5naW5lZXIvMjAwNTE0MCMvPg0KICDigKIgU2Vu aW9yIHNlY3VyaXR5IGRhdGEgZW5naW5lZXIgLQ0KICAgIDxodHRwczovL2pv YnMuZWxhc3RpYy5jby9qb2JzL3NlY3VyaXR5LXNvbHV0aW9ucy9hbWVyLWRp c3RyaWJ1dGVkLS9zZWN1cml0eS1zZW5pb3ItZGF0YS1lbmdpbmVlci8yMDA1 MTUyIy8+DQoNCiAgTGFuZ3VhZ2Utd2lzZSwgT0NhbWwvUmVhc29uIG1ha2Vz IHVwIG1vc3Qgb2YgdGhlIGNvZGUgeW914oCZbGwgYmUNCiAgd29ya2luZyBv bi4gUHl0aG9uIG1ha2VzIHVwIG1vc3Qgb2YgdGhlIHJlc3QsIGluIHBhcnRp Y3VsYXIgdGFraW5nDQogIGFkdmFudGFnZSBvZiB0aGUgbWFjaGluZSBsZWFy bmluZyBhbmQgbmF0dXJhbCBsYW5ndWFnZSBwcm9jZXNzaW5nDQogIGdvb2Rp ZXMgdGhhdCBlY29zeXN0ZW0gcHJvdmlkZXMuIE1vc3Qgb2YgdGhlIHRvb2xz IGFuZCBzZXJ2aWNlIHdlDQogIGRldmVsb3AgYXJlIGludGVybmFsbHkgZm9j dXNlZCwgc3VwcG9ydGluZyBzZWN1cml0eSByZXNlYXJjaCBhbmQNCiAgaW1w cm92ZW1lbnRzIHRvIHNlY3VyaXR5IHByb3RlY3Rpb25zIGZvciBvdXIgdXNl cnMuIEZvciB0aG9zZQ0KICBzby1pbmNsaW5lZCwgdGhlcmUgYXJlIGxvdHMg b2Ygb3Bwb3J0dW5pdGllcyB0byBwcmVzZW50IGF0IGFuZCBhdHRlbmQNCiAg Y29uZmVyZW5jZXMsIHByZXNlbnQgd29yayBpbiBibG9nIHBvc3RzLCBjb250 cmlidXRlIHRvIG9wZW4gc291cmNlDQogIHNvZnR3YXJlIHByb2plY3RzIGFu ZCBvdGhlcndpc2UgZW5nYWdlIHRoZSBjb21tdW5pdHkuDQoNCiAgVGhlIHBv c2l0aW9ucyBhcmUgdmVyeSBzaW1pbGFyIHRvIG91ciBbbGFzdCBoaXJpbmcg YW5ub3VuY2VtZW50XSwNCiAgdGhvdWdoIHdlIGhhZCBhIGRpZmZlcmVudCBu YW1lIGF0IHRoYXQgcG9pbnQhDQoNCiAgUGxlYXNlIHJlYWNoIG91dCB0byBt ZSBpZiB5b3UgaGF2ZSBhbnkgcXVlc3Rpb25zLiBJ4oCZbSBhdmFpbGFibGUg b24gdGhlDQogIE9DYW1sIG9yIFJlYXNvbiBEaXNjb3JkIHNlcnZlcnMgb3Ig YnkgZW1haWwgYXQNCiAgaGV6ZWtpYWguY2FydHlAZWxhc3RpYy5jby4NCg0K DQpbRWxhc3RpY10gPGh0dHBzOi8vd3d3LmVsYXN0aWMuY28vPg0KDQpbbGFz dCBoaXJpbmcgYW5ub3VuY2VtZW50XQ0KPGh0dHBzOi8vZGlzY3Vzcy5vY2Ft bC5vcmcvdC9maWxsZWQtcG9zdGluZy1pcy1uby1sb25nZXItb3Blbi10aHJl YXQtcmVzZWFyY2gtZW5naW5lZXItam9iLWVuZGdhbWUtdXMvMTkzNz4NCg0K DQpSZWxlYXNlIG9mIG5hYm9yaXMgMC4xLjAgYSBzaW1wbGUgaHR0cCBzZXJ2 ZXINCuKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKVkOKV kOKVkA0KDQogIEFyY2hpdmU6DQogIDxodHRwczovL2Rpc2N1c3Mub2NhbWwu b3JnL3QvcmVsZWFzZS1vZi1uYWJvcmlzLTAtMS0wLWEtc2ltcGxlLWh0dHAt c2VydmVyLzQ5OTQvMT4NCg0KDQpTaGF3biBNY0dpbnR5IGFubm91bmNlZA0K 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAgPGh0dHBzOi8vZ2l0aHVi LmNvbS9zaGF3bi1tY2dpbnR5L25hYm9yaXM+DQoNCiAgSSBjb3VsZCB1c2Ug aW5wdXQgb24gdGhlIEFQSSBhbmQgdGhlIGRvY3VtZW50YXRpb24uICBXb3Jr aW5nIG9uIHRyeWluZw0KICB0byBpbXByb3ZlIGJvdGggYXQgdGhlIG1vbWVu dC4NCg0KICBUaGUgZ29hbCB3YXMgdG8gY3JlYXRlIGEgdmVyeSBzaW1wbGUg bGlicmFyeSBmb3IgYnVpbGRpbmcgUkVTVGZ1bCB0eXBlDQogIG9mIHdlYiBz ZXJ2ZXJzLiAgTWFrZSBpdCBfdmVyeV8gZWFzeSB0byBtYW5hZ2UgaGFuZGxl IHJlcXVlc3QvcmVzcG9uc2UNCiAgbGlmZWN5Y2xlIGFuZCBzZXNzaW9ucy4N Cg0KICBJbiBteSBvcGluaW9uIHRoaXMgdHlwZSBvZiB3ZWIgc2VydmVyIGlz IGEgZ3JlYXQgZW50cnkgcG9pbnQgZm9yIG5ldw0KICBkZXZlbG9wZXJzIGxv b2tpbmcgdG8gZXhwbG9yZSB0aGUgT0NhbWwvUmVhc29uIHdvcmxkLg0KDQog IFJlY2VudGx5IEkgaGF2ZSBmYWxsZW4gaW4gbG92ZSB3aXRoIE9DYW1sIGFu ZCBSZWFzb24sIGFuZCBhcyBhIG1vc3RseQ0KICB3ZWIgY2VudGVyZWQgZGV2 ZWxvcGVyIEkndmUgZm91bmQgdGhpcyBhcmVhIHF1aXRlIGxhY2tpbmcuICBJ J20gc3RpbGwNCiAgbmV3IHRvIHRoZSBsYW5ndWFnZSBhbmQgZWNvIHN5c3Rl bSBzbyBhbnkgZ3VpZGFuY2Ugd291bGQgYmUgaGlnaGx5DQogIGFwcHJlY2lh dGVkIQ0KDQoNCllhd2FyIEFtaW4gcmVwbGllZA0K4pSA4pSA4pSA4pSA4pSA 4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSADQoNCiAg V293ISBJdCBzZWVtcyB3ZSBoYWQgbXVjaCB0aGUgc2FtZSBpZGVh4oCTT0Nh bWwvUmVhc29uIG1vcmUgYWNjZXNzaWJsZQ0KICB0byB3ZWIgZGV2ZWxvcGVy cyBuZXcgdG8gdGhlIGVjb3N5c3RlbSA6LUQgSSd2ZSBiZWVuIHdvcmtpbmcg b24NCiAgc29tZXRoaW5nIHZlcnkgc2ltaWxhcjogPGh0dHBzOi8vZ2l0aHVi LmNvbS95YXdhcmFtaW4vcmUtd2ViLz4NCg0KDQpVbHJpayBTdHJpZCBzYWlk DQrilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIANCg0KICBUaGVyZSBpcyBhbHNvIG9waXVtIDxodHRwczovL2dpdGh1 Yi5jb20vcmdyaW5iZXJnL29waXVtPg0KDQogIEFuZCBtb3JwaCA8aHR0cHM6 Ly9naXRodWIuY29tL3JlYXNvbi1uYXRpdmUtd2ViL21vcnBoPiB0aGF0IGhh cw0KICBzaW1pbGFyIGdvYWxzLg0KDQogIEl0IHdvdWxkIGJlIG5pY2UgaWYg d2UgY291bGQgZWl0aGVyIGNyZWF0ZSBhIHNoYXJlZCBjb3JlIHRoYXQgYWxs DQogIGNvdWxkIGJ1aWxkIGZyb20gb3IgY29sbGFib3JhdGUgb24gb25lLg0K DQoNCmVzeUAwLjYuMCByZWxlYXNlDQrilZDilZDilZDilZDilZDilZDilZDi lZDilZDilZDilZDilZDilZDilZDilZDilZDilZANCg0KICBBcmNoaXZlOiA8 aHR0cHM6Ly9kaXNjdXNzLm9jYW1sLm9yZy90L2Fubi1lc3ktMC02LTAtcmVs ZWFzZS81MDEwLzE+DQoNCg0KQW5kcmV5IFBvcHAgYW5ub3VuY2VkDQrilIDi lIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDi lIDilIDilIDilIDilIANCg0KICBXZSd2ZSBqdXN0IHJlbGVhc2VkIGEgbmV3 IHZlcnNpb24gb2YgZXN5LiBZb3UgY2FuIGluc3RhbGwgaXQgd2l0aCBucG06 DQogIOKUjOKUgOKUgOKUgOKUgA0KICDilIIgJCBucG0gaW5zdGFsbCAtZyBl c3lAMC42LjANCiAg4pSU4pSA4pSA4pSA4pSADQoNCiAgW2VzeV0gaXMgYSBw YWNrYWdlLmpzb24gZHJpdmVuIHdvcmtmbG93IGZvciBuYXRpdmUgZGV2ZWxv cG1lbnQgd2l0aA0KICBSZWFzb24vT0NhbWwgKGFuZCBldmVuIEMvQysrKS4g SXQgcHJvdmlkZXMgcGVyLXByb2plY3QgYnVpbGQNCiAgZW52aXJvbm1lbnRz IHdoaWNoIGFyZSBpc29sYXRlZCBmcm9tIGVhY2ggb3RoZXIgYnV0IHNoYXJl IHVuZGVybHlpbmcNCiAgYnVpbGQgY2FjaGVzIHNvIGNyZWF0aW5nIG5ldyBl bnZpcm9ubWVudHMgaXMgY2hlYXAuDQoNCiAgV2hpbGUgMC42LjAgaXMgbWFp bmx5IGFib3V0ICJxdWFsaXR5LW9mLWxpZmUiIGltcHJvdmVtZW50cyBpdCBh bHNvIGdvdA0KICBmZXcgbmV3IGZlYXR1cmVzIGluY2x1ZGluZyBhIGJhc2lj IHN1cHBvcnQgZm9yIGdhcmJhZ2UgY29sbGVjdGlvbiBvZg0KICB1bnVzZWQg YnVpbGQgYXJ0aWZhY3RzLg0KDQogIEZvciBtb3JlIGluZm8gc2VlIGEgW2Js b2cgcG9zdF0gYnkgQHByb21ldGhlYW5zYWNyaWZpY2Ugd2hpY2gNCiAgaGln aGxpZ2h0cyBpbXBvcnRhbnQgdXBkYXRlcyBpbiAwLjYuMC4NCg0KDQpbZXN5 XSA8aHR0cHM6Ly9lc3kuc2g+DQoNCltibG9nIHBvc3RdIDxodHRwczovL2Vz eS5zaC9ibG9nLzIwMjAvMDEvMTIvMC42LjAuaHRtbD4NCg0KDQpPbGQgQ1dO DQrilZDilZDilZDilZDilZDilZDilZANCg0KICBJZiB5b3UgaGFwcGVuIHRv IG1pc3MgYSBDV04sIHlvdSBjYW4gW3NlbmQgbWUgYSBtZXNzYWdlXSBhbmQg SSdsbCBtYWlsDQogIGl0IHRvIHlvdSwgb3IgZ28gdGFrZSBhIGxvb2sgYXQg W3RoZSBhcmNoaXZlXSBvciB0aGUgW1JTUyBmZWVkIG9mIHRoZQ0KICBhcmNo aXZlc10uDQoNCiAgSWYgeW91IGFsc28gd2lzaCB0byByZWNlaXZlIGl0IGV2 ZXJ5IHdlZWsgYnkgbWFpbCwgeW91IG1heSBzdWJzY3JpYmUNCiAgW29ubGlu ZV0uDQoNCiAgW0FsYW4gU2NobWl0dF0NCg0KDQpbc2VuZCBtZSBhIG1lc3Nh Z2VdIDxtYWlsdG86YWxhbi5zY2htaXR0QHBvbHl0ZWNobmlxdWUub3JnPg0K DQpbdGhlIGFyY2hpdmVdIDxodHRwOi8vYWxhbi5wZXRpdGVwb21tZS5uZXQv Y3duLz4NCg0KW1JTUyBmZWVkIG9mIHRoZSBhcmNoaXZlc10gPGh0dHA6Ly9h bGFuLnBldGl0ZXBvbW1lLm5ldC9jd24vY3duLnJzcz4NCg0KW29ubGluZV0g PGh0dHA6Ly9saXN0cy5pZHlsbC5vcmcvbGlzdGluZm8vY2FtbC1uZXdzLXdl ZWtseS8+DQoNCltBbGFuIFNjaG1pdHRdIDxodHRwOi8vYWxhbi5wZXRpdGVw b21tZS5uZXQvPg0KDQo= --=-=-= 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.

--=-=-=--