From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr 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 579F67EE6B for ; Wed, 27 Nov 2013 08:30:33 +0100 (CET) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of oleg@okmij.org) identity=pra; client-ip=66.39.3.115; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="oleg@okmij.org"; x-sender="oleg@okmij.org"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of oleg@okmij.org designates 66.39.3.115 as permitted sender) identity=mailfrom; client-ip=66.39.3.115; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="oleg@okmij.org"; x-sender="oleg@okmij.org"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@www1.g3.pair.com) identity=helo; client-ip=66.39.3.115; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="oleg@okmij.org"; x-sender="postmaster@www1.g3.pair.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AoAEAIKelVJCJwNzY2dsb2JhbABZgz+pJwGTbgMYBw4IPIJTTVSJAw2fY6AnjQuGMQOYEwGBMIstiF88 X-IPAS-Result: AoAEAIKelVJCJwNzY2dsb2JhbABZgz+pJwGTbgMYBw4IPIJTTVSJAw2fY6AnjQuGMQOYEwGBMIstiF88 X-IronPort-AV: E=Sophos;i="4.93,780,1378850400"; d="scan'208";a="38152552" Received: from www1.g3.pair.com ([66.39.3.115]) by mail3-smtp-sop.national.inria.fr with SMTP; 27 Nov 2013 08:30:31 +0100 Received: (qmail 28964 invoked by uid 9370); 27 Nov 2013 07:30:30 -0000 Date: 27 Nov 2013 07:30:30 -0000 Message-ID: <20131127073030.28963.qmail@www1.g3.pair.com> From: oleg@okmij.org To: caml-list@inria.fr Subject: [Caml-list] ANN: improved BER MetaOCaml N101, for OCaml 4.01 BER MetaOCaml N101 is now available. It is a strict superset of OCaml 4.01, extending it with staging annotations to construct and run typed code values. Besides being compatible with the current version of OCaml, BER N101 has a number of improvements and significant changes compared to BER N100. The new API for running code will hopefully encourage the development of new ways to execute code values. The new BER N101 is not only source-compatible with OCaml 4.01 -- it is also binary compatible. Any 4.01-built OCaml library and plugin (including findlib) can be used with BER N101 in their binary form as they are. The building of BER N101 no longer involves bootstrapping and is hence much faster. The staging annotations are: bracket: .< e >. to delay computation (to the future stage) escape: .~ e to perform a computation e and splice-in the result run: !. e to run a future-stage computation, or code, now A special type constructor, called 'code' builds the type of future-stage computations, or code expressions: # .< 2 + 4 >.;; - : int code = .<2 + 4>. The type constructor 'code' takes as its argument the type of the future-stage expression. Future-stage expressions are executed later, but are type-checked now. Therefore, the generated code is assuredly well-typed. Code fragments can be spliced into larger code contexts by using the escape construct: # let x = .< 2 + 4 >. in .< .~ x + .~ x >. ;; - : int code = .<(2 + 4) + (2 + 4)>. The run construct takes a code value, executes it and returns its result. It is actually an ordinary function Runcode.run, which is also bound to the prefix operation (!.). These operations are in the module Runcode (which is not opened by default). For example: # Runcode.run .< 2 + 3 >.;; - : int = 5 # open Runcode;; # !. . x + y >. 2 3;; - : int = 5 The run construct only works on closed code values. Attempting to run open code leads to an exception in the generator (which can be traced as any other exception). To the user, the two major differences of BER N101 from the previous version are: -- the absence of environment classifiers (see below for more detail). -- The operation to run code is no longer a special form. It is an ordinary function [run : 'a code -> 'a] in the module Runcode. For historical reasons, Runcode.run is also defined to be a prefix operation (!.) (note the placement of the dot -- different from before). These two changes do require updating old MetaOCaml code. From experience, the updates are very light: essentially put "open Runcode" at the top of the file and globally replace all ".!" with "!.". The scope extrusion check first introduced in BER N100 made it possible to remove environment classifiers while still preserving the static guarantee: if the generator finishes successfully, the generated code is well-typed and well-scoped. Environment classifiers ensured well-scopedness when type-checking the generator -- but only for pure generators. The scope extrusion check is executed when the generator is run; however the check is comprehensive. Scope extrusion is always caught, and caught early, whether the generator is effectful or not. Another notable change is a new API for running code, with the special type closed_code and the operations val close_code : 'a code -> 'a closed_code val open_code : 'a closed_code -> 'a code The latter is total, the former does a scope extrusion check. There may be many way to 'run' closed_code. Currently, MetaOCaml provides val run_bytecode : 'a closed_code -> 'a to run closed code by bytecode compiling it and then executing. More such functions are possible. The function Runcode.run : 'a code -> 'a and its alias, the prefix operation (!.), are the composition of close_code and run_bytecode. BER N101 added a test for the well-formedness of recursive let: .. and .. are now prohibited. They were allowed in all previous versions of MetaOCaml, which caused a problem: a well-typed generator will produce well-typed code which will nevertheless fail to compile. The new version builds code values faster, especially for functions and nonbinding functions. The speed of the generation has not been a problem. Now it got even faster. BER MetaOCaml N101 is available: -- as a set of patches to the OCaml 4.01 distribution. http://okmij.org/ftp/ML/ber-metaocaml-101.tar.gz See the INSTALL document in that archive. You need the source distribution of OCaml 4.01, see the following URL for details. http://ocaml.org/install.html -- as a GIT bundle containing the changes relative to OCaml 4.01 http://okmij.org/ftp/ML/metaocaml.bundle First, you have to obtain the base git clone https://github.com/ocaml/ocaml.git -b 4.01 ometa4 and then apply the bundle. The older, N100 version, is available via OPAM. The new version will come to OPAM, hopefully soon. For more explanation, please see http://okmij.org/ftp/ML/MetaOCaml.html as well as NOTES.txt in the BER MetaOCaml distribution. Hopefully the release of BER MetaOCaml N101 would further stimulate using and researching typed meta-programming.