Mailing list for all users of the OCaml language and system.
 help / color / mirror / Atom feed
From: oleg@okmij.org
To: omeragacan@gmail.com
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Problems with printing MetaOCaml generated code
Date: Wed,  6 May 2015 05:50:12 -0400 (EDT)	[thread overview]
Message-ID: <20150506095012.91063C382B@www1.g3.pair.com> (raw)
In-Reply-To: <CAMQQO3=nirMojoCsdGvK0EVov6FZj059p3xdUC7h8w84-eQXAQ@mail.gmail.com>


Leo has given an excellent explanation. I merely wish to stress two
subtle points, which are worth repeating.

If we restrict ourselves to two stages for the sake of explanation, a
cross-stage persistent identifier is the one that is bound outside the
brackets but used within. What will appear in the generated code
depends on whether that identifier is ``global'' or not.  If it is
global, the name of that identifier will appear. If it is local,
MetaOCaml will try to lift the corresponding value one way or
another.

I should stress the special meaning of the ``global identifier''. In
the discussions about CSP, a global identifier is a top-level
identifier *in a different compilation unit*. Emphatically, the
top-level identifier in the current compilation unit is *not*
considered a global identifier.  Therefore, if you write

let foo = fun x -> x
.<foo 1>.
you will see the CSP 
- : int code = .<(* CSP foo *) 1>. 

rather than the expected .<foo 1>..

The reason top-level identifiers in the current module are not
considered global is because they may be re-defined -- even at a
different type. For example, the above program may continue with
        let foo = true
If the generated code were .<foo 1>., which particular foo it would
refer to? BTW, the global references generated by OCaml proper (which
one may refer too) do not have disambiguating timestamps. If you
examine the object file generated by OCaml, you will see just 'foo'.

MetaOCaml-specific processing is done definition-by-definition. When
MetaOCaml typechecker sees 'foo', it has no knowledge if that identifier
will be later redefined.


Suppose the identifier x is not global, and and it appears within
brackets, for example

        .<fun u ->  x>.
You can read this expression as if it were

        .<fun u -> .~(lift_it x)>.

where 'lift_it' is one of the lifting function that MetaOCaml chooses
for you. For example, if x is of the type int, then lift_it is essentially
string_of_int. If x is not one of the few types MetaOCaml knows a
priori how to lift (or if x is polymorphic and so its exact type
cannot be determined), then lift_it is chosen to be a dynquote, a
function that examines the run-time representation of the value and
tries to do something intelligent. Since the type information is
erased by that time (or was not available to start with, if x was
polymorphic), we cannot distinguish the integer 0 from None from []
or from the first 0-ary constructor of any data type. All of them are
represented internally as 0. That's why you see Obj.magic 0 in the
generated code.

Of course MetaOCaml serialization can be improved. What I'd like to
stress is that you don't have to wait for the improvement. You can
always, instead of
        .<fun u ->  x>.
write
        .<fun u -> .~(mylift x)>.
where
        mylift : t -> t code
is *your* function that does whatever _you_ like it to do at that
particular type t (it should still produce something of the type (t
code)).

If some particular mylift functions turn out popular, they can be
added to MetaOCaml, to save everyone trouble writing them.

And I generally agree with Leo that this implicit lifting is
baroque. At present I'm not sure if requiring the explicit lifting is
too much of a burden. I'm sure that with modular implicits, it won't
be.


  parent reply	other threads:[~2015-05-06  9:50 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-04-30 18:36 Ömer Sinan Ağacan
2015-04-30 19:52 ` Jacques Carette
2015-04-30 20:25   ` Ömer Sinan Ağacan
2015-04-30 20:57     ` Ömer Sinan Ağacan
2015-04-30 21:35       ` Jeremy Yallop
2015-05-01 11:21       ` oleg
2015-05-01 14:34         ` Ömer Sinan Ağacan
2015-05-01 16:16           ` Leo White
2015-05-01 16:41             ` Ömer Sinan Ağacan
2015-05-01 16:45               ` Leo White
2015-05-01 16:53                 ` Ömer Sinan Ağacan
2015-05-02 18:45                   ` Ömer Sinan Ağacan
2015-05-02 20:49                     ` Jacques Carette
2015-05-03  1:56                       ` Ömer Sinan Ağacan
2015-05-03  2:28                         ` Jacques Carette
2015-05-03  3:19                           ` Ömer Sinan Ağacan
2015-05-03  8:40                             ` Gabriel Scherer
2015-05-03 14:28                               ` Ömer Sinan Ağacan
2015-05-03 15:24                                 ` Leo White
2015-05-03 15:50                                   ` Ömer Sinan Ağacan
2015-05-06  9:50           ` oleg [this message]
2015-05-06 15:58             ` Jeremy Yallop
2015-05-06 16:45               ` Yotam Barnoy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20150506095012.91063C382B@www1.g3.pair.com \
    --to=oleg@okmij.org \
    --cc=caml-list@inria.fr \
    --cc=omeragacan@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox