caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [Caml-list] ocamlopt vs camlc, different behaviour - how to track down?
@ 2013-06-24 16:03 Marc Weber
  2013-06-25  1:12 ` [Caml-list] " Marc Weber
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Marc Weber @ 2013-06-24 16:03 UTC (permalink / raw)
  To: caml-list

I'd like to find out why a ocamlc complied application behaves
differently than a ocamlopt compiled one.

Because "deriving show" for arbitrary data blocks is kind of hard
(it looks like derivig fails on parameterized types?) the next best
thing which comes to my mind is making each instruction trace its source
position. This way it should be easy to find out why ocamlopt result
behaves differently than ocamlc by diffing the traces.

Is there any starting point - such as a camlp4 post processor I could
use and adopt?

Marc Weber

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Caml-list] Re: ocamlopt vs camlc, different behaviour - how to track down?
  2013-06-24 16:03 [Caml-list] ocamlopt vs camlc, different behaviour - how to track down? Marc Weber
@ 2013-06-25  1:12 ` Marc Weber
  2013-06-25  5:45 ` [Caml-list] " Stéphane Glondu
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 6+ messages in thread
From: Marc Weber @ 2013-06-25  1:12 UTC (permalink / raw)
  To: caml-list

Adopting the code at Camlp4Profiler (which ships with ocaml) seems
to do what I want.

trace: trace.ml
	ocamlc -dtypes -pp 'camlp4r -I +camlp4 -parser Camlp4QuotationCommon  -parser Camlp4QuotationExpander' -I +camlp4 -o $@ -c $<

Marc Weber

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] ocamlopt vs camlc, different behaviour - how to track down?
  2013-06-24 16:03 [Caml-list] ocamlopt vs camlc, different behaviour - how to track down? Marc Weber
  2013-06-25  1:12 ` [Caml-list] " Marc Weber
@ 2013-06-25  5:45 ` Stéphane Glondu
  2013-06-28 23:54 ` [Caml-list] " Marc Weber
  2013-07-10  1:56 ` Marc Weber
  3 siblings, 0 replies; 6+ messages in thread
From: Stéphane Glondu @ 2013-06-25  5:45 UTC (permalink / raw)
  To: caml-list

Le 24/06/2013 18:03, Marc Weber a écrit :
> I'd like to find out why a ocamlc complied application behaves
> differently than a ocamlopt compiled one.

There are no guarantees on the evaluation order for some constructions,
I have already experienced differences between ocamlc and ocamlopt.
Looking at the bug tracker, we can find some reports about it:

  http://caml.inria.fr/mantis/view.php?id=2910
  http://caml.inria.fr/mantis/view.php?id=4072

-- 
Stéphane


^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Caml-list] Re: ocamlopt vs camlc, different behaviour - how to track down?
  2013-06-24 16:03 [Caml-list] ocamlopt vs camlc, different behaviour - how to track down? 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 ` Marc Weber
  2013-06-29  7:31   ` Gabriel Scherer
  2013-07-10  1:56 ` Marc Weber
  3 siblings, 1 reply; 6+ messages in thread
From: Marc Weber @ 2013-06-28 23:54 UTC (permalink / raw)
  To: caml-list

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [Caml-list] Re: ocamlopt vs camlc, different behaviour - how to track down?
  2013-06-28 23:54 ` [Caml-list] " Marc Weber
@ 2013-06-29  7:31   ` Gabriel Scherer
  0 siblings, 0 replies; 6+ messages in thread
From: Gabriel Scherer @ 2013-06-29  7:31 UTC (permalink / raw)
  To: Marc Weber; +Cc: caml-list

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

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [Caml-list] Re: ocamlopt vs camlc, different behaviour - how to track down?
  2013-06-24 16:03 [Caml-list] ocamlopt vs camlc, different behaviour - how to track down? Marc Weber
                   ` (2 preceding siblings ...)
  2013-06-28 23:54 ` [Caml-list] " Marc Weber
@ 2013-07-10  1:56 ` Marc Weber
  3 siblings, 0 replies; 6+ messages in thread
From: Marc Weber @ 2013-07-10  1:56 UTC (permalink / raw)
  To: caml-list

It turned out to be a evaluation order problem of a tuple.

Marc Weber

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2013-07-10  1:55 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-06-24 16:03 [Caml-list] ocamlopt vs camlc, different behaviour - how to track down? 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
2013-07-10  1:56 ` Marc Weber

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).