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 9E6597FCCB for ; Fri, 1 May 2015 13:21:31 +0200 (CEST) Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of oleg@okmij.org) identity=pra; client-ip=66.39.3.115; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="oleg@okmij.org"; x-sender="oleg@okmij.org"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.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=mail2-smtp-roc.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 (mail2-smtp-roc.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=mail2-smtp-roc.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: A0CWAQB6YUNVd3MDJ0Jcg19cx0GGDAKBWjwQAQEBAQEBAREBDAcPB0+EIQEBAwEnUgUWIRMhHSs0iAgIxwgBAQEHAgEfiziFBQeDF4EWBY9Lhi6GPwGBIz2LBoVHg1CCCB8DHIFtIjGCRQEBAQ X-IPAS-Result: A0CWAQB6YUNVd3MDJ0Jcg19cx0GGDAKBWjwQAQEBAQEBAREBDAcPB0+EIQEBAwEnUgUWIRMhHSs0iAgIxwgBAQEHAgEfiziFBQeDF4EWBY9Lhi6GPwGBIz2LBoVHg1CCCB8DHIFtIjGCRQEBAQ X-IronPort-AV: E=Sophos;i="5.13,350,1427752800"; d="scan'208";a="138450774" Received: from www1.g3.pair.com ([66.39.3.115]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/ADH-AES256-SHA; 01 May 2015 13:21:15 +0200 Received: by www1.g3.pair.com (Postfix, from userid 9370) id 1C8DFC382A; Fri, 1 May 2015 07:21:14 -0400 (EDT) From: oleg@okmij.org To: omeragacan@gmail.com cc: yallop@gmail.com cc: caml-list@inria.fr In-reply-to: Message-Id: <20150501112114.1C8DFC382A@www1.g3.pair.com> Date: Fri, 1 May 2015 07:21:14 -0400 (EDT) Subject: Re: [Caml-list] Problems with printing MetaOCaml generated code 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 = ..;; val lift : 'a -> 'a code = # lift "aa";; - : string code = .<"aa">. The generated code can be saved to a file and compiled separately. # lift 1;; - : int code = .<(* 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 = lift (+);; val p : (int -> int -> int) code = .<(* 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 = .<.~p 1 2>.;; val p1 : int code = .<(* CSP x *) 1 2>. And we can run the result: # Runcode.run p1;; - : int = 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.