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 E489A5D5 for ; Tue, 7 Jun 2022 10:16:09 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=inria.fr; s=dc; h=from:to:date:message-id:mime-version:subject:reply-to: sender:list-id:list-help:list-subscribe:list-unsubscribe: list-post:list-owner:list-archive; bh=yepF9vSPNsG+uTghrWP/X2I7Kd0UIvHn44AF8b5BWIs=; b=TVqR9g/AFhfZW4emhpYT34cvtKOhR3j1mUHWpJI8ZzgOMVSxjvd9w27u SoKL1TB+Tj6gCulItekOJzSll8Mn2AUrcUCED2VP8camYqVg+uq/n6szx ap56I0idq3WJ0/tcntgqLWKLiTkpv4Na4phBINdXqRab2czJcHXA7iRsB I=; Authentication-Results: mail2-relais-roc.national.inria.fr; dkim=none (message not signed) header.i=none; spf=SoftFail smtp.mailfrom=caml-list-owner@inria.fr; spf=None smtp.helo=postmaster@sympa.inria.fr Received-SPF: SoftFail (mail2-relais-roc.national.inria.fr: domain of caml-list-owner@inria.fr is inclined to not designate 128.93.162.160 as permitted sender) identity=mailfrom; client-ip=128.93.162.160; receiver=mail2-relais-roc.national.inria.fr; envelope-from="caml-list-owner@inria.fr"; x-sender="caml-list-owner@inria.fr"; x-conformance=spf_only; x-record-type="v=spf1"; x-record-text="v=spf1 ip4:192.134.164.0/24 mx ~all" Received-SPF: None (mail2-relais-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@sympa.inria.fr) identity=helo; client-ip=128.93.162.160; receiver=mail2-relais-roc.national.inria.fr; envelope-from="caml-list-owner@inria.fr"; x-sender="postmaster@sympa.inria.fr"; x-conformance=spf_only X-IronPort-AV: E=Sophos;i="5.91,283,1647298800"; d="scan'208,217";a="39792960" Received: from prod-listesu18.inria.fr (HELO sympa.inria.fr) ([128.93.162.160]) by mail2-relais-roc.national.inria.fr with ESMTP; 07 Jun 2022 12:16:08 +0200 Received: by sympa.inria.fr (Postfix, from userid 20132) id 9EC4DE0384; Tue, 7 Jun 2022 12:16:08 +0200 (CEST) Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 42A9AE007E for ; Tue, 7 Jun 2022 12:16:06 +0200 (CEST) IronPort-SDR: JwQbyN/6KN6MsonnB6aroGW8nVLXxaVhSRHUFv/Zr2RV3GrleXpdX17L27K4V5pxdOdCMKD/Dw wiTaZua6PZ92VOoy0qOQIEvCG9POwQdwObyq52QxsIanfXDHL7vvCb7VI/E9unZMToZAF4qsPu Amwe9NJvijy9yxMpbDd/l5Kq4poecenHxWpA0cm46YMOy+HGXTx0yB9gC+Vao63Cf23ysHCQB2 0xU2j04zLQzWKAUhxzQZizdWbcbJ+2xW4tHh4UEiwbeFsy0z5W9T67WRqLOruVrHRFXipZwcfn vVaZyEvEyUmpdW8Ruv4OF+ho X-IPAS-Result: =?us-ascii?q?A0B1AwBXJJ9ieyIeaIFaFoNjWygZAWZWFhcHCESETokAi?= =?us-ascii?q?A0zY4g7hnyNQQNPEAEDAQ0sAQ4EAQIEAQGCDoJ0AoVGAh4GAQUzEwECBAEBA?= =?us-ascii?q?QEDAgMBAQEBAQEDAQEFAQEBAgEBAgQEARMBAQ8LCQYHDAUQDgU8ZGQEgUsEg?= =?us-ascii?q?XQLBwEsDYI1DAwDA4N3AQwMAQIGBAY4CCUjAxQBBgMCEQEXAR4DARMBEhQGA?= =?us-ascii?q?YJjgxgEAQqPUppJGjV6fzKBAYNPAQMCAQIJAgIDDy4Bg3OBZSSBGYYZWkoBg?= =?us-ascii?q?woJhBACJxCBVUSBFYIpSgdugksMCwEBAQEBgRUmAQECVIMggmUEiyiMDwc6A?= =?us-ascii?q?0c0EoEhcQEIBgYHCgUyBgIMGBQEAhMSTQYdAhIMCgYWDkISGQwPAxIDEQEHA?= =?us-ascii?q?gsSCBUsCAMCAwgDAgMuAgMXCQcKAx0IChwSEBQCBBMeCwgDGR8sCQIEDgNFC?= =?us-ascii?q?AsKAxEEAxMYCxYIEAQGAwkvDSgLAwUPDwEGAwYCBQUBAyADFAMFJwcDIQcLJ?= =?us-ascii?q?g0NBCMdAwMFJgMCAhsHAgIDAgYXBgICGVgKJg0IBAgEGAQdJRAFAgcxBQQvA?= =?us-ascii?q?h4EBQYRCQIWAgYEBQIEBBYCAhIIAggnGwcWNhkBBV0GCwkhFgYpEQUGFgMjS?= =?us-ascii?q?icFSA8pNTY6FwwGIpQShDQkAg44BgdGFQYUEwgDEQ4BAQkXAi4EBBgLEQQBC?= =?us-ascii?q?icDGgkCNgQOAQoLAi2SAh0EBZVkgwiUM3w0B4NRgT0GDIdwPIEijQGII4N1g?= =?us-ascii?q?U+KcIUxknYhlkgggiuGfAKBEgmCSYg0i2wlAwMghRuBTiprgQAMBzMaMEOCa?= =?us-ascii?q?AlFAQMCDQECAgMBAgECCQEBAlSKMYIKZgEwAxaBBAEIghsoalSBDBqBdTuBP?= =?us-ascii?q?YQMAz80AgEBNwIGAQoBAQMJhWMBAQUTCwGHNIFdWgEB?= IronPort-PHdr: A9a23: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 N4BV0wmYXU= IronPort-Data: A9a23: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 lvtSg+/ IronPort-HdrOrdr: A9a23:CPTCLaAhCT2VtyvlHemr55DYdb4zR+YMi2TDtnoQdfU7SKOlfq yV9sjztiWUtN9yYh8dcLm7UcHqfZq2z/JICOcqUIuKbU3Phy+DLY1p74fuqgeQeBHWx6p6zq klV6B/DbTLfD1HZCvBkWuFL+o= X-IronPort-Anti-Spam-Filtered: true X-IronPort-AV: E=Sophos;i="5.91,283,1647298800"; d="scan'208,217";a="16085349" X-MGA-submission: =?us-ascii?q?MDGznH5848RCsyPavh7inHx4UvCSRi7Q/pDWYq?= =?us-ascii?q?V+Y5PJGWknT8UItZFtz8gpeKu0MMTXSkOj0m9Muu2Ly2TfifzZjTiG8y?= =?us-ascii?q?pmKMDBjTJL2KKEFnebjIfjdTFGTmsp86KtturNGn9eiGWW9UlC8zlOix?= =?us-ascii?q?udzUNAlGnDxDScshkDgRUXBg=3D=3D?= Received: from mx1.polytechnique.org ([129.104.30.34]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 07 Jun 2022 12:16:05 +0200 Received: from set (ip-185-104-137-32.ptr.icomera.net [185.104.137.32]) (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 942F056065A; Tue, 7 Jun 2022 12:15:38 +0200 (CEST) From: Alan Schmitt To: "lwn" , "cwn" , caml-list@inria.fr Date: Tue, 07 Jun 2022 12:15:24 +0200 Message-ID: <87k09s4w5f.fsf@m4x.org> MIME-Version: 1.0 Content-Type: multipart/alternative; boundary="=-=-=" X-AV-Checked: ClamAV using ClamSMTP at svoboda.polytechnique.org (Tue Jun 7 12:16:03 2022 +0200 (CEST)) X-Spam-Flag: Unsure, tests=bogofilter, spamicity=0.471112, queueID=8F0025606B4 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: 18782 Errors-To: caml-list-owner@inria.fr Precedence: list Precedence: bulk Sender: caml-list-request@inria.fr X-no-archive: yes List-Id: List-Help: List-Subscribe: List-Unsubscribe: List-Post: List-Owner: List-Archive: Archived-At: --=-=-= Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable Hello Here is the latest OCaml Weekly News, for the week of May 31 to June 07, 2022. Table of Contents =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80 carray.0.0.1 ML Family Workshop 2022: Final Call for Presentations OCaml Users and Developers Workshop 2022 dkml-c-probe.2.0.0: Cross-compiler friendly definitions for C compiling Full-Stack Web Dev in OCaml Tutorial w/ Dream, Bonsai, and GraphQL Sketch.sh now supports multiple compiler versions, starting with 4.13.1 Explicit type binding and mutual recursion findlib-1.9.4 omake-0.10.4 Old CWN carray.0.0.1 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Deep in this threas, Fabian said =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Note that you can, to a certain degree, build your own flat structures with the `Bytes' module. Compared to bigarrays, `Bytes.t' has less indirection, a lower constant memory overhead and can be allocated on the minor heap. The contents of `Bytes.t' are not scanned by the GC, just like bigarrays. For example, a more efficient `int32 Array.t': =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 module Int32_array : sig =E2=94=82 type t =E2=94=82 val equal : t -> t -> bool =E2=94=82 val create : int -> t =E2=94=82 val length : t -> int =E2=94=82 val get : t -> int -> int32 =E2=94=82 val set : t -> int -> int32 -> unit =E2=94=82 val sub : t -> int -> int -> t =E2=94=82 val to_list : bytes -> int32 list =E2=94=82 end =3D struct =E2=94=82 type t =3D Bytes.t =E2=94=82 let equal =3D Bytes.equal =E2=94=82 let create len =3D Bytes.create (4 * len) =E2=94=82 let length t =3D Bytes.length t / 4 =E2=94=82 let get t i =3D Bytes.get_int32_le t (4 * i) =E2=94=82 let set t i x =3D Bytes.set_int32_le t (4 * i) x =E2=94=82 let sub t pos len =3D Bytes.sub t (4 * pos) (4 * len) =E2=94=82 let to_list t =3D List.init (length t) (get t) =E2=94=82 end =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 A more efficient `(int * int)': =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 module Point : sig =E2=94=82 type t =E2=94=82 val create : int -> int -> t =E2=94=82 val x : t -> int =E2=94=82 val y : t -> int =E2=94=82 end =3D struct =E2=94=82 external get_int64_unsafe : bytes -> int -> int64 =3D "%caml_= bytes_get64u" =E2=94=82 external set_int64_unsafe : bytes -> int -> int64 -> unit =3D= "%caml_bytes_set64u" =E2=94=82 type t =3D Bytes.t =E2=94=82 let create x y =3D =E2=94=82 let p =3D Bytes.create 16 in =E2=94=82 set_int64_unsafe p 0 (Int64.of_int x); =E2=94=82 set_int64_unsafe p 8 (Int64.of_int y); =E2=94=82 p =E2=94=82 let x t =3D Int64.to_int (get_int64_unsafe t 0) =E2=94=82 let y t =3D Int64.to_int (get_int64_unsafe t 8) =E2=94=82 end =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 (making a more efficient `(int * int) Array.t' is left as an exercise to the reader) The downside compared to bigarrays is that it doesn't support `sub' without copying. Also, bytes can be moved by the GC (during minor GCs or compaction), and therefore you cannot release the runtime lock when passing them to C. The latter point is less relevant with the multicore extensions, especially since there is no compactor yet. There is some related discussion on the eio repository: ML Family Workshop 2022: Final Call for Presentations =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90 Archive: Benoit Montagu announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 ML Family Workshop 2022: DEADLINE EXTENSION =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C= =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C To increase your chances of submitting your work to the ML workshop, *the submission deadline is extended by a week*. The new deadline is Friday 10th June (AoE). A quick reminder: =E2=80=A2 The workshop does not have proceedings, making it the perfect v= enue to run some ideas with the community or present some work in progress within a friendly environment. =E2=80=A2 The work load as an author is low: submissions are only 3 pages= long (excluding references) =E2=80=A2 YOU have the power to make the ML workshop a success! =E2=80=A2 You have one more full week to submit to (please register your submission early!) =E2=80=A2 All the details are here: =E2=80=A2 The ML workshop is colocated with ICFP 2022 OCaml Users and Developers Workshop 2022 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Matija Pretnar announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 To offer additional opportunities to contribute to the OCaml workshop, and to align with the [ML family workshop], to which you are also cordially invited, the submission deadline has been extended by a week to *Friday, June 10* (anywhere on Earth). [ML family workshop] dkml-c-probe.2.0.0: Cross-compiler friendly definitions for C compiling =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: jbeckford announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80 Summary: dkml-c-probe is a new package for maintainers who compile or link C code. Install it with `opam install dkml-c-probe'. Full docs are at [https://github.com/diskuv/dkml-c-probe#readme] [https://github.com/diskuv/dkml-c-probe#readme] Problem =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C You are creating an OCaml package that has foreign C code. Perhaps you need special C headers or libraries when you are targeting Apple users, or perhaps you need to execute custom OCaml code for Android users. More generally you need a way to determine whether your OCaml or C code is compiling for a Linux AMD/Intel 64-bit, Android ARM 32-bit, or any other ABI target. Solution =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C A user of your OCaml package may, for example, be on a 64-bit AMD/Intel Linux machine using a 32-bit OCaml system compiled with `gcc -m32'; additionally they have a 32-bit Android ARM cross-compiler toolchain. `dkml-c-probe' will tell you the target operating system is `Linux' and the target ABI is `Linux_x86' except when the cross-compiler toolchain is invoked. With the cross-compiler toolchain `dkml-c-probe' will tell you the target operating system is `Android' and the target ABI is `Android_arm32v7a'. How it works =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C `dkml-c-probe' uses C preprocessor definitions (ex. `#if TARGET_CPU_X86_64', `#if __ANDROID__', etc.) to determine which ABI the C compiler (ex. `ocamlopt -config | grep native_c_compiler') is targeting. This isn't a new idea. The pattern is used in Esy and Mirage code as well. `dkml-c-probe' just codifies the pattern for use in your own code. Usage =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C In OCaml code you can use the /versioned/ module: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 module V2 : =E2=94=82 sig =E2=94=82 type t_os =3D Android | IOS | Linux | OSX | Windows =E2=94=82 type t_abi =3D =E2=94=82 Android_arm64v8a =E2=94=82 | Android_arm32v7a =E2=94=82 | Android_x86 =E2=94=82 | Android_x86_64 =E2=94=82 | Darwin_arm64 =E2=94=82 | Darwin_x86_64 =E2=94=82 | Linux_arm64 =E2=94=82 | Linux_arm32v6 =E2=94=82 | Linux_arm32v7 =E2=94=82 | Linux_x86_64 =E2=94=82 | Linux_x86 =E2=94=82 | Windows_x86_64 =E2=94=82 | Windows_x86 =E2=94=82 | Windows_arm64 =E2=94=82 | Windows_arm32 =E2=94=82 val get_os : (t_os, Rresult.R.msg) result Lazy.t =E2=94=82 val get_abi : (t_abi, Rresult.R.msg) result Lazy.t =E2=94=82 val get_abi_name : (string, Rresult.R.msg) result Lazy.t =E2=94=82 end =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 In C code you can use the [provided `dkml_compiler_probe.h' header] from within Dune or Opam. Here is a snippet that handles part of the Linux introspection: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 #elif __linux__ =E2=94=82 # if __ANDROID__ =E2=94=82 # ... =E2=94=82 # else =E2=94=82 # define DKML_OS_NAME "Linux" =E2=94=82 # define DKML_OS_Linux =E2=94=82 # if __aarch64__ =E2=94=82 # define DKML_ABI "linux_arm64" =E2=94=82 # define DKML_ABI_linux_arm64 =E2=94=82 # elif __arm__ =E2=94=82 # if defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J= __) || =E2=94=82 defined(__ARM_ARCH_6K__) || defined(__ARM_ARCH_6Z__) || defined= (__ARM_ARCH_6ZK__) || =E2=94=82 defined(__ARM_ARCH_6T2__) =E2=94=82 # define DKML_ABI "linux_arm32v6" =E2=94=82 # define DKML_ABI_linux_arm32v6 =E2=94=82 # elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_= 7A__) || =E2=94=82 defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) || defined= (__ARM_ARCH_7S__) =E2=94=82 # define DKML_ABI "linux_arm32v7" =E2=94=82 # define DKML_ABI_linux_arm32v7 =E2=94=82 # endif /* __ARM_ARCH_6__ || ..., __ARM_ARCH_7__ || = ... */ =E2=94=82 # elif __x86_64__ =E2=94=82 # define DKML_ABI "linux_x86_64" =E2=94=82 # define DKML_ABI_linux_x86_64 =E2=94=82 # elif __i386__ =E2=94=82 # define DKML_ABI "linux_x86" =E2=94=82 # define DKML_ABI_linux_x86 =E2=94=82 # elif defined(__ppc64__) || defined(__PPC64__) =E2=94=82 # define DKML_ABI "linux_ppc64" =E2=94=82 # define DKML_ABI_linux_ppc64 =E2=94=82 # elif __s390x__ =E2=94=82 # define DKML_ABI "linux_s390x" =E2=94=82 # define DKML_ABI_linux_s390x =E2=94=82 # endif /* __aarch64__, __arm__, __x86_64__, __i386__, __= ppc64__ || __PPC64__, =E2=94=82 __s390x__ */ =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 [provided `dkml_compiler_probe.h' header] Versioning and Contributing =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C= =E2=95=8C=E2=95=8C Whenever a new ABI is added, it goes into a new version (ex. `module V3'). Your existing code that uses `module V2' will be unaffected. But each new ABI needs to have its own maintainer because I don't have access to every hardware platform on the planet! For example, PowerPC (`ppc64') and Linux on IBM Z (`s390x') are supported in the C Header but not the OCaml module because there are no PowerPC and S390x maintainers. Please consider contributing, especially if you want others to have an easier compilation story for your favorite hardware platform. Full-Stack Web Dev in OCaml Tutorial w/ Dream, Bonsai, and GraphQL =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Alexander (Sasha) Skvortsov announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80 Hi everyone! I=E2=80=99ve written a tutorial blog series about full-stack= web development in OCaml, and wanted to share it here. Last semester, I took Penn State's [CMPSC 431W], where our final project was to build a database-driven web application. Since I'm fairly familiar with web programming through my work on [Flarum] and past internships/side projects, I decided to use this opportunity to explore the OCaml web development ecosystem. I used [Dream] for the backend, and [Bonsai] for the frontend. While working on this project, I realized two things: =E2=80=A2 OCaml is very underrated for web development. In addition to al= l the language=E2=80=99s great features and safety guarantees, the ecosystem = is pretty good! Dream near-perfectly coincides with my vision of backend webdev, and Bonsai has a great balance of flexibility/elegance and safety. =E2=80=A2 I couldn=E2=80=99t find realistic but accessible full-stack web= projects in OCaml available for reference. I found [tutorials] for [bits] and [pieces], but nothing that connected all the dots. I really enjoyed writing an article series on [hardware design with OCaml], so I decided to do so for web development as well. In total, I wrote 7 articles that walk through my project=E2=80=99s: 1. [Full-Stack WebDev in OCaml Intro]. This includes some background on the project, and instructions for accessing the [live demo]. 2. [Backend WebDev w/ Dream and Caqti]. 3. [Building GraphQL APIs with Dream] 4. [Setting up Bonsai]. 5. [Understanding Bonsai]. I actually wrote the first draft of this before I decided to do a blog, while trying to, well, understand Bonsai. It goes over some underlying concepts (SPAs, Frontend State Management, Algebraic Effects, Monads), as well as Bonsai=E2=80=99s co= re design. 6. [Using GraphQL in Bonsai]. 7. [Routing in Bonsai and Project Conclusion]. Additionally, the [project=E2=80=99s README] has a comprehensive overview= of the tech stack, folder structure, and usage instructions. It also includes some reflections on design decisions and my experience working with these libraries. I had a lot of fun writing these, and I hope they=E2=80=99re useful to an= yone considering OCaml for web development. Would be happy to answer any questions or comments. [CMPSC 431W] [Flarum] [Dream] [Bonsai] [tutorials] [bits] [pieces] [hardware design with OCaml] [Full-Stack WebDev in OCaml Intro] [live demo] [Backend WebDev w/ Dream and Caqti] [Building GraphQL APIs with Dream] [Setting up Bonsai] [Understanding Bonsai] [Using GraphQL in Bonsai] [Routing in Bonsai and Project Conclusion] [project=E2=80=99s README] Alexander (Sasha) Skvortsov later added =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 Also, forgot to mention this originally, but I recommend accessing the demo with one of the emails from [this file] or [this file] (all passwords are still [here]), as those users can also demo create/update functionalities. [this file] [this file] [here] Daniel B=C3=BCnzli replied =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 People who are looking for more lightweight alternatives =E2=80=93 and wa= nt to do web programming without bothering too much about front end insanity can have a look at [hc] (yes indeed: sending HTML over `fetch', web programming excels at running in circles). The front JavaScript for that [CRUD webapp] comes out at 132Ko uncompressed without even trying to tweak anything. [hc] [CRUD webapp] Sketch.sh now supports multiple compiler versions, starting with 4.13.1 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Javier Ch=C3=A1varri announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 The interactive OCaml sketchbook [sketch.sh] has now support to store, edit and run sketches in different versions of the OCaml compiler. [sketch.sh] Support for 4.13 =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C Storing and running sketches using the compiler version 4.13.1 is now possible, this functionality has been added to the already existing support for version 4.06.1. The Reason parser and formatting tool refmt were also updated to a more recent version that supports 4.13.1. Here you can see a sketch showcasing the monadic let syntax, using the example from the official OCaml docs: [ZipSeq - Sketch.sh]. [ZipSeq - Sketch.sh] Existing sketches and forks =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C= =E2=95=8C=E2=95=8C Previously existing sketches remain in 4.06.1, while newly created sketches will be on 4.13.1. For now, the only way to "migrate" a sketch to the newer version of the compiler is by copying its content and pasting it in a new sketch. Forked sketches inherit the compiler version of the forked sketch. Future plans =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C In the future, there are plans to support version 4.14.0 of the compiler, and we are considering adding a way so that the version of the compiler can be chosen for a given sketch. We are also working on migrating the editor UI codebase to a more recent version of ReasonReact, and use JSX3 instead of JSX2. Feature requests and bugs =E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2= =95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95= =8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C=E2=95=8C Please [let us know] in case you have a feature request, or if you encounter any issues or bugs. Also, don't hesitate to reach out via DM or any other means if you would like to contribute or participate in the project in some way. Thanks to [Ahrefs] for supporting an Open Source Day initiative, which allowed to allocate time to work on this improvement for sketch.sh, and for providing the infrastructure to run the sketch.sh service for the community. Thanks as well to the authors and maintainers of the OCaml compiler, js_of_ocaml, and ReScript, that sketch.sh relies upon. [let us know] [Ahrefs] Explicit type binding and mutual recursion =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90= =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95= =90 Archive: Deep in this thread, octachron explained =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80= =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 For most use cases, if you want an explicit annotation for recursive function, it will be much simpler to use the `type a. ...' form: =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 let rec foo: type a. a -> a =3D fun x -> x =E2=94=82 and bar: type a. a -> a =3D fun x -> foo x =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 This form is a shortcut for both adding an explicit universal quantified and and a corresponding locally abstract type (in other words ~let f : 'a . =E2=80=A6. =3D fun (type a) -> =E2=80=A6 ~). The root issue with =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 let rec f (type a) (x:a) =3D f x =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 is that the locally abstract type `a' is introduced after `f'. Moreover, without an explicit type annotation, a recursive function like `f' is monomorphic in its body and a monorphic function cannot be called on a type that was defined after the function. In other words, the issue is that in term of type scopes, the function `f' is equivalent to =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 let f =3D ref Fun.id =E2=94=82 type t =3D A =E2=94=82 let x =3D !f A =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 which also fails with =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 Error: This expression has type t but an expression was expecte= d of type 'a =E2=94=82 The type constructor t would escape its scope =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 This is why the second solution proposed by @Gopiandcode works. Indeed, in =E2=94=8C=E2=94=80=E2=94=80=E2=94=80=E2=94=80 =E2=94=82 let foo, bar =3D fun (type a) -> =E2=94=82 let rec foo (x: a) : a =3D x =E2=94=82 and bar (x: a) : a =3D foo x in =E2=94=82 foo, bar =E2=94=94=E2=94=80=E2=94=80=E2=94=80=E2=94=80 the type `a' is defined before the recursive functions `foo' and `bar', thus `foo a' does not break any scope constraint. findlib-1.9.4 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Gerd Stolpmann announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 findlib-1.9.4 is out. It mainly includes a change in the configuration script needed for OCaml-4-14. For manual, download, manuals, etc. see here: An updated OPAM package will follow soon. omake-0.10.4 =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2= =95=90=E2=95=90=E2=95=90=E2=95=90 Archive: Gerd Stolpmann announced =E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2= =94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94= =80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80=E2=94=80 I just released omake-0.10.4, the build utility. This finally includes the fix for Apple Silicon, but also a couple of small changes (roughly everything since PR#100 to PR#146 on GitHub). For docs and the download link see . opam is underway. Old CWN =E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90=E2=95=90 If you happen to miss a CWN, you can [send me a message] and I'll mail it to you, or go take a look at [the archive] or the [RSS feed of the archives]. If you also wish to receive it every week by mail, you may subscribe [online]. [Alan Schmitt] [send me a message] [the archive] [RSS feed of the archives] [online] [Alan Schmitt] --=-=-= Content-Type: text/html; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: quoted-printable OCaml Weekly News

OCaml Weekly News

Previous Week<= /a> Up Next Week

Hello

Here is the latest OCaml Weekly News, for the week of May 31 to June 07, 20= 22.

carray.0.0.1

Deep in this threas, Fabian said

Note that you can, to a certain degree, build your own flat structures with= the Bytes module. Compared to bigarrays, Bytes.t has less indirection, a= lower constant memory overhead and can be allocated on the minor heap. The contents of Byte= s.t are not scanned by the GC, just like bigarrays.

For example, a more efficient int32 Array.t:

module Int32_array : sig
  type t
  val equal : t -> t -> bool
  val create : int -> t
  val length : t -> int
  val get : t -> int -> int32
  val set : t -> int -> int32 -> unit
  val sub : t -> int -> int -> t
  val to_list : bytes -> int32 list
end =3D struct
  type t =3D Bytes.t
  let equal =3D Bytes=
.equal
  let create len =3D Bytes.create (4 * len)
  let length t=
 =3D Bytes.length t / 4
  let get t i =3D =
Bytes.get_int32_le t (4 * i)
  let set t i x =3D Bytes.set_int32_le t (4 * i=
) x
  let sub t pos le=
n =3D Bytes.sub t (4 * pos) (=
4 * len)
  let to_list t =3D List.init (length t) (get t)
end

A more efficient (int * int):

module Point : sig
  type t
  val create : int -> int -> t
  val x : t -> int
  val y : t -> int
end =3D struct
  external get_int64_unsafe : bytes -> int -> i=
nt64 =3D "%caml_bytes_get64u"
  external set_int64_unsafe : bytes -> int -> i=
nt64 -> unit =3D "%caml_bytes_set64u"
  type t =3D Bytes.t
  let create x=
 y =3D
    let p =3D Bytes.<=
/span>create 16 in
    set_int64_unsafe p 0 (Int64.of_i=
nt x);
    set_int64_unsafe p 8 (Int64.of_i=
nt y);
    p
  let x t =3D =
Int64.to_int (get_int64_unsafe t 0)
  let y t =3D =
Int64.to_int (get_int64_unsafe t 8)
end

(making a more efficient (int * int) Array.t is left as an exe= rcise to the reader)

The downside compared to bigarrays is that it doesn't support sub without copying. Also, bytes can be moved by the GC (during minor GCs or compaction), and therefor= e you cannot release the runtime lock when passing them to C. The latter point is less r= elevant with the multicore extensions, especially since there is no compactor yet. There is = some related discussion on the eio repository: https://github.com/ocaml-multicore/eio/issues/140

ML Family Workshop 2022: Final Call for Presentations

Benoit Montagu announced

ML Family Workshop 2022: DEADLINE EXTENSION

To increase your chances of submitting your work to the ML workshop, the submission deadline is extended by a week. The new deadline is Friday 10th June (AoE).

A quick reminder:

OCaml Users and Developers Workshop 2022

Matija Pretnar announced

To offer additional opportunities to contribute to the OCaml workshop, and = to align with the ML family workshop, to which you are also cordially invited, the submission deadline has been exte= nded by a week to Friday, June 10 (anywhere on Earth).

dkml-c-probe.2.0.0: Cross-compiler friendly definitions for C = compiling

jbeckford announced

Summary: dkml-c-probe is a new package for maintainers who compile or link = C code. Install it with opam install dkml-c-probe. Full docs are at https://github.co= m/diskuv/dkml-c-probe#readme

Problem

You are creating an OCaml package that has foreign C code. Perhaps you need= special C headers or libraries when you are targeting Apple users, or perhaps you need to exe= cute custom OCaml code for Android users. More generally you need a way to determine whether = your OCaml or C code is compiling for a Linux AMD/Intel 64-bit, Android ARM 32-bit, or any = other ABI target.

Solution

A user of your OCaml package may, for example, be on a 64-bit AMD/Intel Lin= ux machine using a 32-bit OCaml system compiled with gcc -m32; additionally they = have a 32-bit Android ARM cross-compiler toolchain. dkml-c-probe will tell you the targe= t operating system is Linux and the target ABI is Linux_x86 except when the cross-compiler= toolchain is invoked. With the cross-compiler toolchain dkml-c-probe will tell you the ta= rget operating system is Android and the target ABI is Android_arm32v7a.

How it works

dkml-c-probe uses C preprocessor definitions (ex. #if TA= RGET_CPU_X86_64, #if __ANDROID__, etc.) to determine which ABI the C compiler (ex. = ocamlopt -config | grep native_c_compiler) is targeting.

This isn't a new idea. The pattern is used in Esy and Mirage code as well. = dkml-c-probe just codifies the pattern for use in your own code.

Usage

In OCaml code you can use the versioned module:

module V2 :
  sig
    type t_os =3D Android | IOS | Linux | OSX | Windows
    type t_abi =3D
        Android_=
arm64v8a
      | Android_=
arm32v7a
      | Android_=
x86
      | Android_=
x86_64
      | Darwin_a=
rm64
      | Darwin_x=
86_64
      | Linux_ar=
m64
      | Linux_ar=
m32v6
      | Linux_ar=
m32v7
      | Linux_x8=
6_64
      | Linux_x8=
6
      | Windows_=
x86_64
      | Windows_=
x86
      | Windows_=
arm64
      | Windows_=
arm32
    val get_os : (t_os, Rresult.R.msg) result Lazy.t
    val get_abi : (t_abi, Rresult.R.msg) result Lazy.t
    val get_abi_name : (string, Rresult.R.msg) result Laz=
y.t
  end

In C code you can use the provided dkml_compiler_probe.h header from within Dune or Opam. Here is a snippet that handles part of the Linux introspection:

#elif __lin=
ux__
#   if __ANDROID__
#       ...
#   else
#       define DKML_OS_NAME "Linux"
#       define DKML_OS_Linux
#       if __aarch64__
#           define DKML_ABI "linux_arm64=
"
#           define DKML_ABI_linux_arm64
#       elif __arm__
#           if defined(__ARM_ARCH_6__) || #               define DKML_ABI "linux=
_arm32v6"
#               define DKML_ABI_linux_arm32v6
#           elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) ||
defined(__ARM_ARCH_7R__) || defined(=
__ARM_ARCH_7M__) || defined(__ARM_ARCH_7S__)
#               define DKML_ABI "linux=
_arm32v7"
#               define DKML_ABI_linux_arm32v7
#           endif /* __ARM_ARCH_6__ || .=
..,  __ARM_ARCH_7__ || ... */
#       elif __x86_64__
#           define DKML_ABI "linux_x86_6=
4"
#           define DKML_ABI_linux_x86_64
#       elif __i386__
#           define DKML_ABI "linux_x86"<=
/span>
#           define DKML_ABI_linux_x86
#       elif defined(__ppc64__) || defin=
ed(__PPC64__)
#           define DKML_ABI "linux_ppc64=
"
#           define DKML_ABI_linux_ppc64
#       elif __s390x__
#           define DKML_ABI "linux_s390x=
"
#           define DKML_ABI_linux_s390x
#       endif /* __aarch64__, __arm__, _=
_x86_64__, __i386__, __ppc64__ || __PPC64__,
__s390x__ */

Versioning and Contributing

Whenever a new ABI is added, it goes into a new version (ex. module V= 3). Your existing code that uses module V2 will be unaffected.

But each new ABI needs to have its own maintainer because I don't have acce= ss to every hardware platform on the planet!

For example, PowerPC (ppc64) and Linux on IBM Z (s390x) are supported in the C Header but not the OCaml module because there are no PowerPC and S390x maintainers.

Please consider contributing, especially if you want others to have an easi= er compilation story for your favorite hardware platform.

Full-Stack Web Dev in OCaml Tutorial w/ Dream, Bonsai, and Gra= phQL

Alexander (Sasha) Skvortsov announced

Hi everyone! I=E2=80=99ve written a tutorial blog series about full-stack w= eb development in OCaml, and wanted to share it here.

Last semester, I took Penn State's CMPSC 431W, where our final project was to build a database-driven web application. Sin= ce I'm fairly familiar with web programming through my work on Flarum and past internships/side projects, I decided to use this opportunity to explore the= OCaml web development ecosystem. I used = Dream for the backend, and Bonsai for the fronten= d.

While working on this project, I realized two things:

  • OCaml is very underrated for web development. In addition to all the la= nguage=E2=80=99s great features and safety guarantees, the ecosystem is pre= tty good! Dream near-perfectly coincides with my vision of backend webdev, = and Bonsai has a great balance of flexibility/elegance and safety.
  • I couldn=E2=80=99t find realistic but accessible full-stack web project= s in OCaml available for reference. I found tutorials for bits and pieces, but n= othing that connected all the dots.

I really enjoyed writing an article series on hardware design= with OCaml, so I decided to do so for web development as well. In total, I wrote 7 articles = that walk through my project=E2=80=99s:

  1. Full-Stack WebDev in OCaml Intro. This includes some backgro= und on the project, and instructions for accessing the live demo.
  2. Backend WebDev w/ Dream and Caqti.
  3. Building GraphQL APIs with Dream
  4. Sett= ing up Bonsai.
  5. U= nderstanding Bonsai. I actually wrote the first draft of this before I = decided to do a blog, while trying to, well, understand Bonsai. It goes ove= r some underlying concepts (SPAs, Frontend State Management, Algebraic Effe= cts, Monads), as well as Bonsai=E2=80=99s core design.
  6. Using GraphQL in Bonsai.
  7. Routing in Bonsai and Project Conclusion.

Additionally, the project=E2=80=99s README has a comprehensive overview of the tech stack, folder structure, and usage instr= uctions. It also includes some reflections on design decisions and my experience working wit= h these libraries.

I had a lot of fun writing these, and I hope they=E2=80=99re useful to anyo= ne considering OCaml for web development. Would be happy to answer any questions or comments.

Alexander (Sasha) Skvortsov later added

Also, forgot to mention this originally, but I recommend accessing the demo with one of the emails from = this file or this file (all passwords are still here), as those users can also demo create/update functionalities.

Daniel B=C3=BCnzli replied

People who are looking for more lightweight alternatives =E2=80=93 and want= to do web programming without bothering too much about front end insanity = can have a look at hc (yes indeed: sending HT= ML over fetch, web programming excels at running in circles).

The front JavaScript for that CRUD webapp comes out at 132Ko uncompressed without even trying to = tweak anything.

Sketch.sh now supports multiple compiler versions, starting wi= th 4.13.1

Javier Ch=C3=A1varri announced

Existing sketches and forks

Previously existing sketches remain in 4.06.1, while newly created sketches= will be on 4.13.1. For now, the only way to "migrate" a sketch to the newer version of= the compiler is by copying its content and pasting it in a new sketch.

Forked sketches inherit the compiler version of the forked sketch.

Future plans

In the future, there are plans to support version 4.14.0 of the compiler, a= nd we are considering adding a way so that the version of the compiler can be chosen = for a given sketch. We are also working on migrating the editor UI codebase to a more r= ecent version of ReasonReact, and use JSX3 instead of JSX2.

Feature requests and bugs

Please let us= know in case you have a feature request, or if you encounter any issues or bugs. Also, don't hesita= te to reach out via DM or any other means if you would like to contribute or participate in= the project in some way.

Thanks to Ahrefs for supporting an Open= Source Day initiative, which allowed to allocate time to work on this improvement for sketch.sh, and for= providing the infrastructure to run the sketch.sh service for the community. Thanks as we= ll to the authors and maintainers of the OCaml compiler, js_of_ocaml, and ReScript, that sket= ch.sh relies upon.

Explicit type binding and mutual recursion

Deep in this thread, octachron explained

For most use cases, if you want an explicit annotation for recursive functi= on, it will be much simpler to use the type a. ... form:

let rec foo: type a. a -> a =3D fun x -> x
and bar: type a.=
 a -> a =3D fun x -> foo x

This form is a shortcut for both adding an explicit universal quantified an= d and a corresponding locally abstract type (in other words ~let f : 'a . …= . =3D fun (type a) -> … ~).

The root issue with

let rec f (a) (x:a) =3D f x

is that the locally abstract type a is introduced after = f. Moreover, without an explicit type annotation, a recursive function like f is monomorphic in= its body and a monorphic function cannot be called on a type that was defined after the function.

In other words, the issue is that in term of type scopes, the function f is equivalent to

let f =3D ref Fun.id
type t =3D A
let x =3D !f=
 A

which also fails with

Error: This expression has type t but an expression was expected of type 'a
       The type constructor t would escape its scope

This is why the second solution proposed by @Gopiandcode works. Indeed, in

let foo, bar =3D fun =
(type let rec foo (x: a) : a =3D=
 x
  and bar (x:<=
span style=3D"color: #228b22;"> a) :=
 a =3D foo x in
  foo, bar

the type a is defined before the recursive functions foo= and bar, thus foo a does not break any scope constraint.

findlib-1.9.4

Gerd Stolpmann announced

findlib-1.9.4 is out. It mainly includes a change in the configuration script needed for OCaml-4-14.

For manual, download, manuals, etc. see here:

http://proje= cts.camlcity.org/projects/findlib.html

An updated OPAM package will follow soon.

omake-0.10.4

Gerd Stolpmann announced

I just released omake-0.10.4, the build utility. This finally includes the fix for Apple Silicon, but also a couple of small changes (roughly everything since PR#100 to PR#146 on GitHub).

For docs and the download link see http://project= s.camlcity.org/projects/omake.html. opam is underway.

Old CWN

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

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

--=-=-=--