caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Gabriel Scherer <gabriel.scherer@gmail.com>
To: Marc Weber <marco-oweber@gmx.de>
Cc: caml-list <caml-list@inria.fr>
Subject: Re: [Caml-list] Re: ocamlopt vs camlc, different behaviour - how to track down?
Date: Sat, 29 Jun 2013 09:31:28 +0200	[thread overview]
Message-ID: <CAPFanBF+8JBzTiaYRV4t2d3FVoVjM1RJ1Tx4fQPDQe6RhN5mjQ@mail.gmail.com> (raw)
In-Reply-To: <1372463499-sup-1099@nixos>

The problem you hit is the so-called "Value restriction" in ML, which
makes certain expressions that possibly have side-effects
non-polymorphic, in order to avoid having polymorphic expressions that
allocated memory location (allocating mutable memory is a particular
kind of side-effects, but the over-zealous static judgment has to
forbid other things as well, in particular any unknown functional
call, and dubious "let..in..." constructs).

You can in fact solve that problem by turning

   let empty =
          let () = print_string "[\"pMap.ml\": 81:12-42 81:42]\n"
          in { cmp = compare; map = Empty; };

into

   let empty =
          (print_string "[\"pMap.ml\": 81:12-42 81:42]\n";
          { cmp = compare; map = Empty; })

While the two expression have the exact same dynamic semantics (they
execute in the same way), with the (e1; e2) form the compiler can
trivially see that no memory allocation that would have been done in
e1 will be reused in the value of e2, so it's safe to generalize
(e1;e2) as soon as e2 only is effect-free. In the general case (let p
= e1 in e2), parts of e1 may be reused in e2, so this expression is
not generalized as soon as e1 has effects. In that case (let () = e1
in e2), it would be safe to ignore e1 as no part of it is bound and
reused in e2, and more generally one may do an escape analysis do
refine generalization here. But as all expressions (let p = e1 in e2)
where no part of e1 are reused in e2 can be rewritten into (e1; e2),
it makes sense to simplify the specification of the type-checker and
favor the latter form. The camlp4 code generator you use was just not
aware of this subtlety.




On Sat, Jun 29, 2013 at 1:54 AM, Marc Weber <marco-oweber@gmx.de> wrote:
> Error: The implementation m.ml does not match the interface m.cmi:
>        Values do not match:
>          val empty : ('_a, 'b) t
>        is not included in
>          val empty : ('a, 'b) t
>        File "m.ml", line 11, characters 4-9: Actual declaration
> make: *** [m.cmo] Error 2
>
>
> files as zip: http://mawercer.de/tmp/test-case.zip
> contents:
>
>   makefile =========================
>
>   default: m.cmo
>
>   m.cmi: m.mli
>           ocamlc -o $@ -c $<
>
>   m.cmo: m.ml m.cmi
>           ocamlc -o $@ -c $<
>   m.ml ============================
>
>
>   type ('k, 'v) map =
>     | Empty
>     | Node of ('k, 'v) map * 'k * 'v * ('k, 'v) map * int
>
>   type ('k, 'v) t =
>     {
>       cmp : 'k -> 'k -> int;
>       map : ('k, 'v) map;
>     }
>
>   let empty =
>          let () = print_string "[\"pMap.ml\": 81:12-42 81:42]\n"
>          in { cmp = compare; map = Empty; };
>
>
>   m.mli ============================
>
>
>   type ('a, 'b) t
>
>   val empty : ('a, 'b) t
>
>
> In cases like first, find_all I was able to workaround this compilation
> error by adding explicit parameters, eg
>
> find_all a b = find a b instead of find_all = find
>
> However in the "empty" case I need more help. How to make this case
> compile ?
>
> Marc Weber
>
> --
> Caml-list mailing list.  Subscription management and archives:
> https://sympa.inria.fr/sympa/arc/caml-list
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs

  reply	other threads:[~2013-06-29  7:32 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-06-24 16:03 [Caml-list] " Marc Weber
2013-06-25  1:12 ` [Caml-list] " Marc Weber
2013-06-25  5:45 ` [Caml-list] " Stéphane Glondu
2013-06-28 23:54 ` [Caml-list] " Marc Weber
2013-06-29  7:31   ` Gabriel Scherer [this message]
2013-07-10  1:56 ` Marc Weber

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=CAPFanBF+8JBzTiaYRV4t2d3FVoVjM1RJ1Tx4fQPDQe6RhN5mjQ@mail.gmail.com \
    --to=gabriel.scherer@gmail.com \
    --cc=caml-list@inria.fr \
    --cc=marco-oweber@gmx.de \
    /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;
as well as URLs for NNTP newsgroup(s).