* [Caml-list] Type inference and marshalling @ 2011-07-05 13:59 malc 2011-07-05 14:18 ` Wojciech Meyer 2011-07-05 23:24 ` Jacques Garrigue 0 siblings, 2 replies; 7+ messages in thread From: malc @ 2011-07-05 13:59 UTC (permalink / raw) To: caml-list Perhaps someone could explain why following behaves the way it does: ~$ ocaml Objective Caml version 3.11.2 # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in ic i;; Warning Y: unused variable j. val f : in_channel -> unit = <fun> # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in ic j;; Error: This expression has type int but an expression was expected of type int64 -- mailto:av1474@comtv.ru ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Type inference and marshalling 2011-07-05 13:59 [Caml-list] Type inference and marshalling malc @ 2011-07-05 14:18 ` Wojciech Meyer 2011-07-05 14:54 ` Mathias Kende 2011-07-05 23:24 ` Jacques Garrigue 1 sibling, 1 reply; 7+ messages in thread From: Wojciech Meyer @ 2011-07-05 14:18 UTC (permalink / raw) To: malc; +Cc: caml-list [-- Attachment #1: Type: text/plain, Size: 1311 bytes --] I think that's because i is being unified with int64 type in the seek_in call. So the type of i will be int64, and input_value polymorphic type variable will be int64. The unused binding j is not taken account and thrown away, so the type system will not take into account + operator that will cause i to be int. Why the unused binding is being thrown away before type checker, I don't know, maybe somebody could explain possibly. So from this is obvious why the second statement fails to type check. Cheers; Wojciech On Tue, Jul 5, 2011 at 2:59 PM, malc <av1474@comtv.ru> wrote: > Perhaps someone could explain why following behaves the way it does: > > ~$ ocaml > Objective Caml version 3.11.2 > > # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in > ic i;; > Warning Y: unused variable j. > val f : in_channel -> unit = <fun> > # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in > ic j;; > Error: This expression has type int but an expression was expected of type > int64 > > -- > mailto:av1474@comtv.ru > > -- > Caml-list mailing list. Subscription management and archives: > https://sympa-roc.inria.fr/wws/info/caml-list > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners > Bug reports: http://caml.inria.fr/bin/caml-bugs > > [-- Attachment #2: Type: text/html, Size: 1956 bytes --] ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Type inference and marshalling 2011-07-05 14:18 ` Wojciech Meyer @ 2011-07-05 14:54 ` Mathias Kende 0 siblings, 0 replies; 7+ messages in thread From: Mathias Kende @ 2011-07-05 14:54 UTC (permalink / raw) To: caml-list Le mardi 05 juillet 2011 à 15:18 +0100, Wojciech Meyer a écrit : > The unused binding j is not taken account and thrown away, so the type > system will not take into account + operator that will cause i to be int. > Why the unused binding is being thrown away before type checker, I don't > know, maybe somebody could explain possibly. This is not the reason for the acceptance of this input because the following also typecheck (in 3.12.0): let f ic = let i = input_value ic in let j = i + 1 in (j, i, LargeFile.seek_in ic i); with (apparently wrong) type: val f : in_channel -> int * 'a * unit = <fun> This looks like a bug in the type checker. A smaller triggering program is: let f () = let i = input_value stdin in let j = i + 1 in i, j;; Mathias ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Type inference and marshalling 2011-07-05 13:59 [Caml-list] Type inference and marshalling malc 2011-07-05 14:18 ` Wojciech Meyer @ 2011-07-05 23:24 ` Jacques Garrigue 2011-07-06 5:11 ` malc 1 sibling, 1 reply; 7+ messages in thread From: Jacques Garrigue @ 2011-07-05 23:24 UTC (permalink / raw) To: malc; +Cc: caml-list On 2011/07/05, at 22:59, malc wrote: > Perhaps someone could explain why following behaves the way it does: > > ~$ ocaml > Objective Caml version 3.11.2 > > # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in ic i;; > Warning Y: unused variable j. > val f : in_channel -> unit = <fun> The return type of input_value being 'a, which gets generalized by the relaxed value restriction, i gets the polymorphic type "forall 'a. 'a". So you can use it both as an int and an int64. ==> input_value is an unsafe function, you should always write a type annotation on its return type. > # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in ic j;; > Error: This expression has type int but an expression was expected of type > int64 j being the result of an integer addition, it has type int, and cannot be used as int64. Jacques ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Type inference and marshalling 2011-07-05 23:24 ` Jacques Garrigue @ 2011-07-06 5:11 ` malc 2011-07-06 7:44 ` Jacques Garrigue 0 siblings, 1 reply; 7+ messages in thread From: malc @ 2011-07-06 5:11 UTC (permalink / raw) To: Jacques Garrigue; +Cc: caml-list On Wed, 6 Jul 2011, Jacques Garrigue wrote: > On 2011/07/05, at 22:59, malc wrote: > > > Perhaps someone could explain why following behaves the way it does: > > > > ~$ ocaml > > Objective Caml version 3.11.2 > > > > # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in ic i;; > > Warning Y: unused variable j. > > val f : in_channel -> unit = <fun> > > The return type of input_value being 'a, which gets generalized by the > relaxed value restriction, i gets the polymorphic type "forall 'a. 'a". > So you can use it both as an int and an int64. > ==> input_value is an unsafe function, you should always write a type > annotation on its return type. Sure i'm well aware of that, but to me "let j = i + 1" means that i has type int and after that "LargeFile.seek ic i" makes no sense yet is accepted by the type checker. > > > # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in ic j;; > > Error: This expression has type int but an expression was expected of type > > int64 > > j being the result of an integer addition, it has type int, and cannot be used > as int64. > > Jacques > > -- mailto:av1474@comtv.ru ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Type inference and marshalling 2011-07-06 5:11 ` malc @ 2011-07-06 7:44 ` Jacques Garrigue 2011-07-06 8:31 ` malc 0 siblings, 1 reply; 7+ messages in thread From: Jacques Garrigue @ 2011-07-06 7:44 UTC (permalink / raw) To: malc; +Cc: caml-list On 2011/07/06, at 14:11, malc wrote: > On Wed, 6 Jul 2011, Jacques Garrigue wrote: > >> On 2011/07/05, at 22:59, malc wrote: >> >>> Perhaps someone could explain why following behaves the way it does: >>> >>> ~$ ocaml >>> Objective Caml version 3.11.2 >>> >>> # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in ic i;; >>> Warning Y: unused variable j. >>> val f : in_channel -> unit = <fun> >> >> The return type of input_value being 'a, which gets generalized by the >> relaxed value restriction, i gets the polymorphic type "forall 'a. 'a". >> So you can use it both as an int and an int64. >> ==> input_value is an unsafe function, you should always write a type >> annotation on its return type. > > Sure i'm well aware of that, but to me "let j = i + 1" means that i has > type int and after that "LargeFile.seek ic i" makes no sense yet is > accepted by the type checker. But this is just the definition of let polymorphism... If the type of a let-bound value contains variables, they can be generalized (with some restriction for soundness). So i can perfectly have several types. What makes no sense here is the return type of input_value, yet this cannot be avoided since there is currently no mechanism in ocaml to actually check the type of the value received. I have no simple solution for this with the current standard library. A potential way to avoid this problem would be to force the user to provide a monomorphic type: module type T = sig type t end let input_value ic (type a) (t : (module T with type t = a)) : a = Pervasives.input_value ic let f ic = let i = input_value ic (module struct type t = int end : T with type t = int) in let _ = i + 1 in seek_in ic i;; This is verbose, but some syntactic sugar could be easily provided. In the long term, safe input primitives are the solution. Jacques Garrigue ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] Type inference and marshalling 2011-07-06 7:44 ` Jacques Garrigue @ 2011-07-06 8:31 ` malc 0 siblings, 0 replies; 7+ messages in thread From: malc @ 2011-07-06 8:31 UTC (permalink / raw) To: Jacques Garrigue; +Cc: caml-list On Wed, 6 Jul 2011, Jacques Garrigue wrote: > On 2011/07/06, at 14:11, malc wrote: > > > On Wed, 6 Jul 2011, Jacques Garrigue wrote: > > > >> On 2011/07/05, at 22:59, malc wrote: > >> > >>> Perhaps someone could explain why following behaves the way it does: > >>> > >>> ~$ ocaml > >>> Objective Caml version 3.11.2 > >>> > >>> # let f ic = let i = input_value ic in let j = i + 1 in LargeFile.seek_in ic i;; > >>> Warning Y: unused variable j. > >>> val f : in_channel -> unit = <fun> > >> > >> The return type of input_value being 'a, which gets generalized by the > >> relaxed value restriction, i gets the polymorphic type "forall 'a. 'a". > >> So you can use it both as an int and an int64. > >> ==> input_value is an unsafe function, you should always write a type > >> annotation on its return type. > > > > Sure i'm well aware of that, but to me "let j = i + 1" means that i has > > type int and after that "LargeFile.seek ic i" makes no sense yet is > > accepted by the type checker. > > But this is just the definition of let polymorphism... Thing is - the original code looked something like this: let offset = input_value ic in Printf.printf "%d" offset; LargeFile.seek_in other_ic offset; And it also worked... and caught me by surprise.. > If the type of a let-bound value contains variables, they can be generalized > (with some restriction for soundness). > So i can perfectly have several types. > What makes no sense here is the return type of input_value, > yet this cannot be avoided since there is currently no mechanism > in ocaml to actually check the type of the value received. > > I have no simple solution for this with the current standard library. > A potential way to avoid this problem would be to force the user to > provide a monomorphic type: > > module type T = sig type t end > > let input_value ic (type a) (t : (module T with type t = a)) : a = > Pervasives.input_value ic > > let f ic = > let i = > input_value ic (module struct type t = int end : T with type t = int) in > let _ = i + 1 in seek_in ic i;; > > This is verbose, but some syntactic sugar could be easily provided. > In the long term, safe input primitives are the solution. > -- mailto:av1474@comtv.ru ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2011-07-06 8:31 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2011-07-05 13:59 [Caml-list] Type inference and marshalling malc 2011-07-05 14:18 ` Wojciech Meyer 2011-07-05 14:54 ` Mathias Kende 2011-07-05 23:24 ` Jacques Garrigue 2011-07-06 5:11 ` malc 2011-07-06 7:44 ` Jacques Garrigue 2011-07-06 8:31 ` malc
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox