From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: 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 1BCFD7FCCB for ; Fri, 1 May 2015 16:35:33 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of omeragacan@gmail.com) identity=pra; client-ip=209.85.212.177; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="omeragacan@gmail.com"; x-sender="omeragacan@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of omeragacan@gmail.com designates 209.85.212.177 as permitted sender) identity=mailfrom; client-ip=209.85.212.177; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="omeragacan@gmail.com"; x-sender="omeragacan@gmail.com"; 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@mail-wi0-f177.google.com) identity=helo; client-ip=209.85.212.177; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="omeragacan@gmail.com"; x-sender="postmaster@mail-wi0-f177.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0BKAgCtjkNVlLHUVdFcg19cBYMYwl6BVIYEAoFTBzkTAQEBAQEBAREBAQEBBwsLCR8whCEBAQMBEhEEGQEbGAUBAwELBgULDwImAgIiAREBBQEcGRsHh3QBAwkIDac/PjGLOYFrgnaIYQoZJw1VhEMBAQEBAQEBAwEBAQEBAQEVAQUOgROKF4RSMweCaIFFBZV5hkCBIz2LBoVHggYSI4EMCYIIHwMcgW0iMYJFAQEB X-IPAS-Result: A0BKAgCtjkNVlLHUVdFcg19cBYMYwl6BVIYEAoFTBzkTAQEBAQEBAREBAQEBBwsLCR8whCEBAQMBEhEEGQEbGAUBAwELBgULDwImAgIiAREBBQEcGRsHh3QBAwkIDac/PjGLOYFrgnaIYQoZJw1VhEMBAQEBAQEBAwEBAQEBAQEVAQUOgROKF4RSMweCaIFFBZV5hkCBIz2LBoVHggYSI4EMCYIIHwMcgW0iMYJFAQEB X-IronPort-AV: E=Sophos;i="5.13,350,1427752800"; d="scan'208";a="114185662" Received: from mail-wi0-f177.google.com ([209.85.212.177]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 01 May 2015 16:35:32 +0200 Received: by widdi4 with SMTP id di4so49853429wid.0 for ; Fri, 01 May 2015 07:35:31 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc:content-type:content-transfer-encoding; bh=gVn+Bz9DUtwULjF0vHYa3zCNCMOX0StoyHiWBhKx7kc=; b=n9byr+6LEHFXIrYvjnW4HbQrZIIijA2fopGZTKB7xDG5wWKKBWmHAi6DiuzEB0YTMV G+noSq+YA+0n4kInjdoHLrw3oLLdWkpLTup9enMItQWWLxpPYdzZmLVWhOOc93tITde4 sTDB645hUeTd8mm+Dsf5ZC3jTnr4EC/6MDSWPsPZT2Cu1uhsdkkAv1ECPYhg3HGPwmxr 8QC0bC2o9FkbndWLv/0f25fG1B55sj9o5uJLcBgX9vlF3Fd4APeabJef8is62VxHZbDa xqgYUJWlNdJVxzbSIy20Oq3BrUichq84OCfOC/JT6pIH6hTgqr9HK9GIRIb4k+JkA/Z1 qH1w== X-Received: by 10.180.91.76 with SMTP id cc12mr15271677wib.67.1430490931575; Fri, 01 May 2015 07:35:31 -0700 (PDT) MIME-Version: 1.0 Received: by 10.194.187.212 with HTTP; Fri, 1 May 2015 07:34:51 -0700 (PDT) In-Reply-To: <20150501112114.1C8DFC382A@www1.g3.pair.com> References: <20150501112114.1C8DFC382A@www1.g3.pair.com> From: =?UTF-8?Q?=C3=96mer_Sinan_A=C4=9Facan?= Date: Fri, 1 May 2015 10:34:51 -0400 Message-ID: To: oleg@okmij.org Cc: yallop@gmail.com, OCaml Mailing List Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: quoted-printable Subject: Re: [Caml-list] Problems with printing MetaOCaml generated code Thanks for all the answers, > MetaOCaml always prints the generated code. However, if the generated code > contains non-serializable CSP, they are printed in a way that makes saving > the code to a file and then compiling separately impossible. Can we talk about what is non-serializable here? I pushed some code to a public repo for demonstration purposes. I have a simple interpreter for a simple language. I'm experimenting with different levels of interpreter specializations(aka. first Futamura projections). As a simplest specialization, I want to eliminate parsing costs. The code that's supposed to do this is here: https://github.com/osa1/int-proj/blob/master/Unlambda.ml#L204 `p'` in that code is lifted, and it's parsed syntax tree of given source file. Syntax tree is defined here: https://github.com/osa1/int-proj/blob/master/Syntax.ml#L63 I think it doesn't have anything that's not serializable: It's just a simple monomorphic type, doesn't have any closures etc. But MetaOCaml is failing to print this code. To try it yourself, make sure you have metaocamlc in $PATH, and run: =E2=9E=9C unlambda git:(master) =E2=9C=97 make unlambda_metaocaml metaocamlc -c Syntax.ml metaocamlc Syntax.cmo Unlambda.ml -o unlambda_metaocaml =E2=9E=9C unlambda git:(master) =E2=9C=97 ./unlambda_metaocaml programs/= Hello.unl stage0 File "Unlambda.ml", line 204, characters 67-69: Warning 22: The CSP value is a closure or too deep to serialize File "Unlambda.ml", line 204, characters 58-66: Warning 22: The CSP value is a closure or too deep to serialize .<(* CSP eval_ref *) (* CSP p' *) []>. To make my point clear: I don't actually need to print the code, even though offline compilation would be awesome, I'm fine with just (.!)ing my code for now. But I should be able to see the transformations I'm doing. I'm perfectly fine with just (.!)ing my code, as long as I can see what I'm running. But in this case MetaOCaml is failing to print a code that IMO is completely printable. Thanks again for very helpful responses. 2015-05-01 7:21 GMT-04:00 : > > After Jeremy's thorough reply, there is little more to say. I'd like > to reinforce a few points. First of all, I was confused by > > > The problem is MetaOCaml never prints generated code, > > it's always failing with `Warning 22: The CSP value is a closure or > > too deep to serialize`. > > because Warning 22 is a warning, it is not an error or > failure. Second, MetaOCaml always prints the generated code, with the > proviso that non-seriealizable CSP are printed in a way that make the > code unsuitable for separate compilation. But the code is still > suitable for Runcode.run. (see below). Your concrete example helped. > >> So now that I've expressed my frustration about this, I guess my main >> question is: In what cases does MetaOCaml prints generated code? In >> what cases it doesn't? Note that it fails to generate code even after >> calling `print_closed_code (close_code ...)`, so being closed or not >> doesn't seem very relevent here. Is this a bug in MetaOCaml? Are there >> any workarounds? Any ideas what am I doing wrong? > > MetaOCaml always prints the generated code. However, if the generated > code contains non-serializable CSP, they are printed in a way that > makes saving the code to a file and then compiling separately > impossible. > Warning 22 was specifically introduced to tell that the generated code > contains a non-serializable CSP. That means that separately compiling > such code is impossible in principle. (I should admit that when CSP is > serializable, it may still be in many cases printed badly -- but at > least that problem is fixable in principle. Or even in practice: CSPs > used internally by MetaOCaml are serializable and are printed in a > good way.) > > BTW, one should distinguish ``code with badly printed CSP'' from > ``fails to generate code''. The code with badly printed CSP is still a > good code and can be run. So, seeing (* CSP x *) in the output is NOT > a failure of code generation. > > Perhaps a concrete example will help. > > # let lift x =3D ..;; > val lift : 'a -> 'a code =3D > > # lift "aa";; > - : string code =3D .<"aa">. > > The generated code can be saved to a file and compiled separately. > > # lift 1;; > - : int code =3D .<(* CSP x *) Obj.magic 1>. > > Here, the generated code looks odd but it is still a well-formed OCaml > code, which may be saved into a file and compiled separately. > > > # let p =3D lift (+);; > val p : (int -> int -> int) code =3D .<(* CSP x *)>. > > This code cannot be compiled separately (and it is accompanied by > Warning 22). Here, CSP is a function (closure). How do you print > closures (other than a sequence of bytes in memory, which is not very > informative)? Saving it to a file is also problematic. > > Yet this is NO failure of code generation. The code p can be used as > any other code value, for example being spliced: > > # let p1 =3D .<.~p 1 2>.;; > val p1 : int code =3D .<(* CSP x *) 1 2>. > > And we can run the result: > > # Runcode.run p1;; > - : int =3D 3 > > There is no problems here. > > I should stress that there are two ways of using MetaOCaml: run-time > code specialization and generating code for off-line use. In the > former case, it is appropriate, and even beneficial, to share values > between the generator and the generated code, via the common > heap. This is especially good for large values or for closures, open > channels, etc. Such sharing through the common heap is bad for > off-line use, because there is no common heap any more. Warning 22 is > emitted when there is shared through the common heap. This warning is > issued at run-time of the generator: it is difficult to detect > heap-based sharing at compile time: look at the function lift above. > It is polymorphic, so we can't tell if sharing through the heap will > be required from the type of the function (or its definition). In some > uses of this function, like (lift "aa") and (lift 1), no heap sharing > occurs (or, at least, it is not essential and irrelevant). In some > cases, like (lift (+)), the heap-sharing is essential. > > That said, there is something we can do. For example, we can prohibit > polymorphic lifting, like lift above. The user will have to supply > their own function of the type t -> t code for some the concrete type > t. Perhaps that is the way to go, and I am evaluating it. Warning 22 > is specifically introduced to help determine how much work the user > will have to do if this solution is implemented. Basically, Warning 22 > will become a compile-time error, and the user will have to supply > their own lifting function. That's where modular implicits will be of > great help. > > >> and `print_code_as_ast` is printing something that definitely doesn't >> look like an AST for any imaginable programming language.(okay... I >> might have exaggerated a bit, but it's definitely not OCaml AST and it >> contains some references to generator program source, like >> "Generator.ml[248]" for example) > > It may be hard to accept this, but what you see as the output of > print_code_as_ast is indeed the OCaml AST, printed by OCaml's own > Printast.implementation function. >