caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* weird behavior with built-in ignore function (a bug?)
@ 2007-11-23 16:09 Peng Zang
  2007-11-23 16:19 ` [Caml-list] " Vincent Aravantinos
  2007-11-24  0:31 ` Julien Moutinho
  0 siblings, 2 replies; 6+ messages in thread
From: Peng Zang @ 2007-11-23 16:09 UTC (permalink / raw)
  To: caml-list

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Hi all,

I have run into what appears to be very odd behavior with the built-in
function "ignore".  I will demonstrate below.  It's a little
complicated, but it's the smallest testcase I could make it:

# type 'a fruit = 'a
and 'b veggie = 'b
and ('a,'b) kitchen = { source : <make : 'a fruit>;
                        sink : <trans : 'a fruit -> 'b veggie>; }
;;

# let bar sink x = sink#trans x;;
val bar : < trans : 'a -> 'b; .. > -> 'a -> 'b = <fun>

# let foo src snk =
    let m = { source = src; sink = snk } in
      ignore (bar m.sink m.source#make);
      ignore (bar m.sink m.source#make);
      ()
;;
val foo : < make : 'a fruit > -> < trans : 'a fruit -> '_b veggie > -> unit = 
<fun>


Basically, we have two objects.  One is producing fruits (source) and
the other is transforming them into vegetables (sink).  Note the
inferred typesig of foo, it thinks the trans method returntype is '_b
veggie.  This seems strange.  I think it should return a fully
polymorphic 'b veggie.

To verify.  I now re-define foo without the use of ignore:

# let foo src snk =
    let m = { source = src; sink = snk } in
    let _ = bar m.sink m.source#make in
    let _ = bar m.sink m.source#make in
      ();;
val foo : < make : 'a fruit > -> < trans : 'a fruit -> 'b veggie > -> unit = 
<fun>

This time the return type for trans is fully polymorphic!  Using
ignore as in the first case broke something.

For a strange turn, I make my own ignore function and redefine foo
with that:

# let myignore x = ();;
val myignore : 'a -> unit = <fun>
# let foo src snk =
  let m = { source = src; sink = snk } in
    myignore (bar m.sink m.source#make);
    myignore (bar m.sink m.source#make);
    ()
;;
val foo : < make : 'a fruit > -> < trans : 'a fruit -> 'b veggie > -> unit = 
<fun>

This also yields returns a fully polymorphic veggie!  So it's
something unique to the build-in ignore function?

So now my puzzling question: what is going on?  What is wrong with the
build-in ignore function that would make it mess up the return type of
the trans method?  Is this a bug?

Thanks,

Peng

PS. I'm using OCaml 3.09.3, haven't tried with 3.10
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)

iD8DBQFHRvtLfIRcEFL/JewRAlaUAKDILTX5yx7vsK0z8qRWFXMosywfUgCfcFqv
zfcI8DJ4qOuDzF+S3zsrFBM=
=fBnk
-----END PGP SIGNATURE-----


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

* Re: [Caml-list] weird behavior with built-in ignore function (a bug?)
  2007-11-23 16:09 weird behavior with built-in ignore function (a bug?) Peng Zang
@ 2007-11-23 16:19 ` Vincent Aravantinos
  2007-11-24  0:31 ` Julien Moutinho
  1 sibling, 0 replies; 6+ messages in thread
From: Vincent Aravantinos @ 2007-11-23 16:19 UTC (permalink / raw)
  To: peng.zang; +Cc: caml-list


Le 23 nov. 07 à 17:09, Peng Zang a écrit :

> PS. I'm using OCaml 3.09.3, haven't tried with 3.10

Same behaviour with 3.10

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

* Re: [Caml-list] weird behavior with built-in ignore function (a bug?)
  2007-11-23 16:09 weird behavior with built-in ignore function (a bug?) Peng Zang
  2007-11-23 16:19 ` [Caml-list] " Vincent Aravantinos
@ 2007-11-24  0:31 ` Julien Moutinho
  2007-11-24 18:48   ` Peng Zang
  1 sibling, 1 reply; 6+ messages in thread
From: Julien Moutinho @ 2007-11-24  0:31 UTC (permalink / raw)
  To: caml-list

On Fri, Nov 23, 2007 at 11:09:44AM -0500, Peng Zang wrote:
> I have run into what appears to be very odd behavior with the built-in
> function "ignore".  I will demonstrate below.  It's a little
> complicated, but it's the smallest testcase I could make it:
> 
> # type 'a fruit = 'a
> and 'b veggie = 'b
> and ('a,'b) kitchen = { source : <make : 'a fruit>;
>                         sink : <trans : 'a fruit -> 'b veggie>; }
> ;;
> 
> # let bar sink x = sink#trans x;;
> val bar : < trans : 'a -> 'b; .. > -> 'a -> 'b = <fun>
> 
> # let foo src snk =
>     let m = { source = src; sink = snk } in
>       ignore (bar m.sink m.source#make);
>       ignore (bar m.sink m.source#make);
>       ()
> ;;
> val foo : < make : 'a fruit > -> < trans : 'a fruit -> '_b veggie > -> unit = 
> <fun>
> 
> 
> Basically, we have two objects.  One is producing fruits (source) and
> the other is transforming them into vegetables (sink).  Note the
> inferred typesig of foo, it thinks the trans method returntype is '_b
> veggie.  This seems strange.  I think it should return a fully
> polymorphic 'b veggie.
[..]

AFAICS it has been fixed in the release310 branch:
  http://caml.inria.fr/mantis/view.php?id=4350

% git checkout release310
Switched to branch "release310"
% make ocamlc
[...]
% ./ocamlc -i peng__071123.ml
type 'a fruit = 'a
and 'a veggie = 'a
and ('a, 'b) kitchen = {
  source : < make : 'a fruit >;
  sink : < trans : 'a fruit -> 'b veggie >;
}
val bar : < trans : 'a -> 'b; .. > -> 'a -> 'b
val foo : < make : 'a fruit > -> < trans : 'a fruit -> 'b veggie > -> unit

% git-log --grep='PR#4350'
commit 4240263b7cbe15e87cc24e797aac6917eacb9f71
Author: garrigue <garrigue>
Date:   Mon Oct 29 04:40:34 2007 +0000

    PR#4350
% git-revert 4240263b
% make ocamlc
% ./ocamlc -i peng__071123.ml
type 'a fruit = 'a
and 'a veggie = 'a
and ('a, 'b) kitchen = {
  source : < make : 'a fruit >;
  sink : < trans : 'a fruit -> 'b veggie >;
}
val bar : < trans : 'a -> 'b; .. > -> 'a -> 'b
val foo : < make : 'a fruit > -> < trans : 'a fruit -> '_b veggie > -> unit

% git-reset --hard 'HEAD^'

> To verify.  I now re-define foo without the use of ignore:
> 
> # let foo src snk =
>     let m = { source = src; sink = snk } in
>     let _ = bar m.sink m.source#make in
>     let _ = bar m.sink m.source#make in
>       ();;
> val foo : < make : 'a fruit > -> < trans : 'a fruit -> 'b veggie > -> unit = 
> <fun>
> 
> This time the return type for trans is fully polymorphic!  Using
> ignore as in the first case broke something.
> 
> For a strange turn, I make my own ignore function and redefine foo
> with that:
> 
> # let myignore x = ();;
> val myignore : 'a -> unit = <fun>
> # let foo src snk =
>   let m = { source = src; sink = snk } in
>     myignore (bar m.sink m.source#make);
>     myignore (bar m.sink m.source#make);
>     ()
> ;;
> val foo : < make : 'a fruit > -> < trans : 'a fruit -> 'b veggie > -> unit = 
> <fun>
> 
> This also yields returns a fully polymorphic veggie!  So it's
> something unique to the build-in ignore function?
Perhaps the fact that Pervasives.ignore is defined like that:

  external ignore : 'a -> unit = "%ignore"

BTW be aware that:
% ocaml
        Objective Caml version 3.10.1+dev2 (2007-11-20)

# ignore == ignore;;
- : bool = false
# let ignore _ = ();;
val ignore : 'a -> unit = <fun>
# ignore == ignore;;
- : bool = true

> So now my puzzling question: what is going on?  What is wrong with the
> build-in ignore function that would make it mess up the return type of
> the trans method?  Is this a bug?
> 
> Thanks,
> 
> Peng
> 
> PS. I'm using OCaml 3.09.3, haven't tried with 3.10

HTH,
  Julien.


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

* Re: [Caml-list] weird behavior with built-in ignore function (a bug?)
  2007-11-24  0:31 ` Julien Moutinho
@ 2007-11-24 18:48   ` Peng Zang
  2007-11-25  6:05     ` Julien Moutinho
  0 siblings, 1 reply; 6+ messages in thread
From: Peng Zang @ 2007-11-24 18:48 UTC (permalink / raw)
  To: caml-list; +Cc: Julien Moutinho

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Ahhh... it's good to know this is a bug and that it has been fixed.  I think 
for the interim I will simply define my own ignore function.  It also bothers 
me that even in the fixed version ignore does not equal itself.  I also don't 
see why ignore is even defined externally.  Doesn't the compiler optimize 
ignore calls away?

Peng

On Friday 23 November 2007 07:31:11 pm Julien Moutinho wrote:
> On Fri, Nov 23, 2007 at 11:09:44AM -0500, Peng Zang wrote:
> > I have run into what appears to be very odd behavior with the built-in
> > function "ignore".  I will demonstrate below.  It's a little
> > complicated, but it's the smallest testcase I could make it:
> >
> > # type 'a fruit = 'a
> > and 'b veggie = 'b
> > and ('a,'b) kitchen = { source : <make : 'a fruit>;
> >                         sink : <trans : 'a fruit -> 'b veggie>; }
> > ;;
> >
> > # let bar sink x = sink#trans x;;
> > val bar : < trans : 'a -> 'b; .. > -> 'a -> 'b = <fun>
> >
> > # let foo src snk =
> >     let m = { source = src; sink = snk } in
> >       ignore (bar m.sink m.source#make);
> >       ignore (bar m.sink m.source#make);
> >       ()
> > ;;
> > val foo : < make : 'a fruit > -> < trans : 'a fruit -> '_b veggie > ->
> > unit = <fun>
> >
> >
> > Basically, we have two objects.  One is producing fruits (source) and
> > the other is transforming them into vegetables (sink).  Note the
> > inferred typesig of foo, it thinks the trans method returntype is '_b
> > veggie.  This seems strange.  I think it should return a fully
> > polymorphic 'b veggie.
>
> [..]
>
> AFAICS it has been fixed in the release310 branch:
>   http://caml.inria.fr/mantis/view.php?id=4350
>
> % git checkout release310
> Switched to branch "release310"
> % make ocamlc
> [...]
> % ./ocamlc -i peng__071123.ml
> type 'a fruit = 'a
> and 'a veggie = 'a
> and ('a, 'b) kitchen = {
>   source : < make : 'a fruit >;
>   sink : < trans : 'a fruit -> 'b veggie >;
> }
> val bar : < trans : 'a -> 'b; .. > -> 'a -> 'b
> val foo : < make : 'a fruit > -> < trans : 'a fruit -> 'b veggie > -> unit
>
> % git-log --grep='PR#4350'
> commit 4240263b7cbe15e87cc24e797aac6917eacb9f71
> Author: garrigue <garrigue>
> Date:   Mon Oct 29 04:40:34 2007 +0000
>
>     PR#4350
> % git-revert 4240263b
> % make ocamlc
> % ./ocamlc -i peng__071123.ml
> type 'a fruit = 'a
> and 'a veggie = 'a
> and ('a, 'b) kitchen = {
>   source : < make : 'a fruit >;
>   sink : < trans : 'a fruit -> 'b veggie >;
> }
> val bar : < trans : 'a -> 'b; .. > -> 'a -> 'b
> val foo : < make : 'a fruit > -> < trans : 'a fruit -> '_b veggie > -> unit
>
> % git-reset --hard 'HEAD^'
>
> > To verify.  I now re-define foo without the use of ignore:
> >
> > # let foo src snk =
> >     let m = { source = src; sink = snk } in
> >     let _ = bar m.sink m.source#make in
> >     let _ = bar m.sink m.source#make in
> >       ();;
> > val foo : < make : 'a fruit > -> < trans : 'a fruit -> 'b veggie > ->
> > unit = <fun>
> >
> > This time the return type for trans is fully polymorphic!  Using
> > ignore as in the first case broke something.
> >
> > For a strange turn, I make my own ignore function and redefine foo
> > with that:
> >
> > # let myignore x = ();;
> > val myignore : 'a -> unit = <fun>
> > # let foo src snk =
> >   let m = { source = src; sink = snk } in
> >     myignore (bar m.sink m.source#make);
> >     myignore (bar m.sink m.source#make);
> >     ()
> > ;;
> > val foo : < make : 'a fruit > -> < trans : 'a fruit -> 'b veggie > ->
> > unit = <fun>
> >
> > This also yields returns a fully polymorphic veggie!  So it's
> > something unique to the build-in ignore function?
>
> Perhaps the fact that Pervasives.ignore is defined like that:
>
>   external ignore : 'a -> unit = "%ignore"
>
> BTW be aware that:
> % ocaml
>         Objective Caml version 3.10.1+dev2 (2007-11-20)
>
> # ignore == ignore;;
> - : bool = false
> # let ignore _ = ();;
> val ignore : 'a -> unit = <fun>
> # ignore == ignore;;
> - : bool = true
>
> > So now my puzzling question: what is going on?  What is wrong with the
> > build-in ignore function that would make it mess up the return type of
> > the trans method?  Is this a bug?
> >
> > Thanks,
> >
> > Peng
> >
> > PS. I'm using OCaml 3.09.3, haven't tried with 3.10
>
> HTH,
>   Julien.
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)

iD8DBQFHSHH2fIRcEFL/JewRAmZUAKCn7EQXCVEGdSNaxSUu7XYGwQ2tuQCcChv1
WK/7GzYGRj5Vs4WGaULXTnE=
=gE5n
-----END PGP SIGNATURE-----


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

* Re: [Caml-list] weird behavior with built-in ignore function (a bug?)
  2007-11-24 18:48   ` Peng Zang
@ 2007-11-25  6:05     ` Julien Moutinho
  2007-11-25 14:21       ` Peng Zang
  0 siblings, 1 reply; 6+ messages in thread
From: Julien Moutinho @ 2007-11-25  6:05 UTC (permalink / raw)
  To: caml-list

On Sat, Nov 24, 2007 at 01:48:18PM -0500, Peng Zang wrote:
> Ahhh... it's good to know this is a bug and that it has been fixed.  I think 
> for the interim I will simply define my own ignore function.  It also bothers 
> me that even in the fixed version ignore does not equal itself.
Have a glance at this little thread:
  http://caml.inria.fr/pub/ml-archives/caml-list/2005/04/838a1399a42491c4db9aeaa684458a6b.en.html

> I also don't see why ignore is even defined externally.
> Doesn't the compiler optimize ignore calls away?
Well, in bytecomp/translcore.ml in the primitives_table
"%ignore" is associated with Pignore

and in asmcomp/cmmgen.ml:
  | Pignore ->
      return_unit(remove_unit (transl arg))

So I guess Pervasives.ignore is defined like that
to be able to segregate it at compile time to avoid
a function call.

% cat t.ml
ignore (Random.bits ())

% ocamlopt -dcmm t.ml
[...]
(function camlT__entry ()
 (app{random.ml:157,14-32} "camlRandom__bits_89" (load (+a "camlRandom" 52))
   unit)
 1a)
[...]


% cat tt.ml
let ignore _ = ()
in ignore (Random.bits ())

% ocamlopt -dcmm tt.ml
[...]
(data int 2295 "camlTt__1": addr "camlTt__ignore_58" int 3)
(function camlTt__ignore_58 (x/59: addr) 1a)

(function camlTt__entry ()
 (let ignore/58 "camlTt__1"
   (app{random.ml:157,14-32} "camlRandom__bits_89"
     (load (+a "camlRandom" 52)) unit))
 1a)
[...]


BTW that's the use of return_unit which disables tail-rec optimization:
% ocaml
        Objective Caml version 3.10.1+dev2 (2007-11-20)

# let rec f () = ignore (f ());;
val f : unit -> unit = <fun>
# f ();;
Stack overflow during evaluation (looping recursion?).

# let rec f () = f ();;
val f : unit -> 'a = <fun>
# f ();;
Interrupted.

# let rec f () = let _ = f () in ();;
val f : unit -> unit = <fun>
# f ();;
Stack overflow during evaluation (looping recursion?).

# let rec f () : unit = Obj.magic (f ());;
val f : unit -> unit = <fun>
# f ();;
Interrupted.

Regards,
  Julien.


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

* Re: [Caml-list] weird behavior with built-in ignore function (a bug?)
  2007-11-25  6:05     ` Julien Moutinho
@ 2007-11-25 14:21       ` Peng Zang
  0 siblings, 0 replies; 6+ messages in thread
From: Peng Zang @ 2007-11-25 14:21 UTC (permalink / raw)
  To: caml-list; +Cc: Julien Moutinho

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Thanks for the link to that thread and the examples, it was very helpful.

Peng


On Sunday 25 November 2007 01:05:49 am Julien Moutinho wrote:
> On Sat, Nov 24, 2007 at 01:48:18PM -0500, Peng Zang wrote:
> > Ahhh... it's good to know this is a bug and that it has been fixed.  I
> > think for the interim I will simply define my own ignore function.  It
> > also bothers me that even in the fixed version ignore does not equal
> > itself.
>
> Have a glance at this little thread:
>  
> http://caml.inria.fr/pub/ml-archives/caml-list/2005/04/838a1399a42491c4db9a
>eaa684458a6b.en.html
>
> > I also don't see why ignore is even defined externally.
> > Doesn't the compiler optimize ignore calls away?
>
> Well, in bytecomp/translcore.ml in the primitives_table
> "%ignore" is associated with Pignore
>
> and in asmcomp/cmmgen.ml:
>   | Pignore ->
>
>       return_unit(remove_unit (transl arg))
>
> So I guess Pervasives.ignore is defined like that
> to be able to segregate it at compile time to avoid
> a function call.
>
> % cat t.ml
> ignore (Random.bits ())
>
> % ocamlopt -dcmm t.ml
> [...]
> (function camlT__entry ()
>  (app{random.ml:157,14-32} "camlRandom__bits_89" (load (+a "camlRandom"
> 52)) unit)
>  1a)
> [...]
>
>
> % cat tt.ml
> let ignore _ = ()
> in ignore (Random.bits ())
>
> % ocamlopt -dcmm tt.ml
> [...]
> (data int 2295 "camlTt__1": addr "camlTt__ignore_58" int 3)
> (function camlTt__ignore_58 (x/59: addr) 1a)
>
> (function camlTt__entry ()
>  (let ignore/58 "camlTt__1"
>    (app{random.ml:157,14-32} "camlRandom__bits_89"
>      (load (+a "camlRandom" 52)) unit))
>  1a)
> [...]
>
>
> BTW that's the use of return_unit which disables tail-rec optimization:
> % ocaml
>         Objective Caml version 3.10.1+dev2 (2007-11-20)
>
> # let rec f () = ignore (f ());;
> val f : unit -> unit = <fun>
> # f ();;
> Stack overflow during evaluation (looping recursion?).
>
> # let rec f () = f ();;
> val f : unit -> 'a = <fun>
> # f ();;
> Interrupted.
>
> # let rec f () = let _ = f () in ();;
> val f : unit -> unit = <fun>
> # f ();;
> Stack overflow during evaluation (looping recursion?).
>
> # let rec f () : unit = Obj.magic (f ());;
> val f : unit -> unit = <fun>
> # f ();;
> Interrupted.
>
> Regards,
>   Julien.
>
> _______________________________________________
> Caml-list mailing list. Subscription management:
> http://yquem.inria.fr/cgi-bin/mailman/listinfo/caml-list
> Archives: http://caml.inria.fr
> Beginner's list: http://groups.yahoo.com/group/ocaml_beginners
> Bug reports: http://caml.inria.fr/bin/caml-bugs


-----BEGIN PGP SIGNATURE-----
Version: GnuPG v2.0.7 (GNU/Linux)

iD8DBQFHSYT6fIRcEFL/JewRAj6eAJ49xNEBIF37V/rC56wlJmApUPkmMwCgo3K4
/8yXSailKazYrspH57e29u8=
=rGYM
-----END PGP SIGNATURE-----


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

end of thread, other threads:[~2007-11-25 14:21 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-23 16:09 weird behavior with built-in ignore function (a bug?) Peng Zang
2007-11-23 16:19 ` [Caml-list] " Vincent Aravantinos
2007-11-24  0:31 ` Julien Moutinho
2007-11-24 18:48   ` Peng Zang
2007-11-25  6:05     ` Julien Moutinho
2007-11-25 14:21       ` Peng Zang

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