* [Caml-list] monomorphic restriction or typing/scanf bug? @ 2002-10-15 3:29 Chris Hecker 2002-10-15 3:51 ` Jacques Garrigue 2002-10-15 12:19 ` Pierre Weis 0 siblings, 2 replies; 7+ messages in thread From: Chris Hecker @ 2002-10-15 3:29 UTC (permalink / raw) To: caml-list The "scan" function in the code below works if it's at global scope, but not if it's defined inside the test2 function. Is this a bug or a typing restriction? I assume the latter (and that I could have boiled this example to one of the ones in the FAQ?), but I don't understand these kinds of polymorphism typing issues. Chris type t = Foo of int | Bar of int * int exception FB of t (* works *) let scan s (fmt : ('a, Scanf.Scanning.scanbuf, 'b) format) f = try raise (FB (Scanf.sscanf s fmt f)) with End_of_file | Scanf.Scan_failure _ -> () let test () = let line = "Foo 1" in try scan line "Foo %d" (fun i -> Foo i); scan line "Bar %d %d" (fun i j -> Bar (i,j)); failwith "bad line" with FB t -> t (* doesn't work *) let test2 () = let line = "Foo 1" in let scan s (fmt : ('a, Scanf.Scanning.scanbuf, 'b) format) f = try raise (FB (Scanf.sscanf s fmt f)); () with End_of_file | Scanf.Scan_failure _ -> () in try scan line "Foo %d" (fun i -> Foo i); scan line "Bar %d %d" (fun i j -> Bar (i,j)); failwith "bad line" with FB t -> t ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] monomorphic restriction or typing/scanf bug? 2002-10-15 3:29 [Caml-list] monomorphic restriction or typing/scanf bug? Chris Hecker @ 2002-10-15 3:51 ` Jacques Garrigue 2002-10-15 12:19 ` Pierre Weis 1 sibling, 0 replies; 7+ messages in thread From: Jacques Garrigue @ 2002-10-15 3:51 UTC (permalink / raw) To: checker; +Cc: caml-list From: Chris Hecker <checker@d6.com> > The "scan" function in the code below works if it's at global scope, > but not if it's defined inside the test2 function. Is this a bug or a > typing restriction? I assume the latter (and that I could have boiled > this example to one of the ones in the FAQ?), but I don't understand > these kinds of polymorphism typing issues. This is a known issue: named type variables inside an expression are restricted to be monomorphic for the whole toplevel expression. They can only be generalized afterwards. (This is to ensure that two identical variable names in an expression refer to the same variable) The standard workaround is to use nameless ones. > (* this works *) > let test2 () = > let line = "Foo 1" in > let scan s (fmt : (_, Scanf.Scanning.scanbuf, _) format) f = > try > raise (FB (Scanf.sscanf s fmt f)); > () > with > End_of_file | Scanf.Scan_failure _ -> () > in > try > scan line "Foo %d" (fun i -> Foo i); > scan line "Bar %d %d" (fun i j -> Bar (i,j)); > failwith "bad line" > with > FB t -> t Jacques Garrigue ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] monomorphic restriction or typing/scanf bug? 2002-10-15 3:29 [Caml-list] monomorphic restriction or typing/scanf bug? Chris Hecker 2002-10-15 3:51 ` Jacques Garrigue @ 2002-10-15 12:19 ` Pierre Weis 2002-10-15 21:03 ` Chris Hecker 1 sibling, 1 reply; 7+ messages in thread From: Pierre Weis @ 2002-10-15 12:19 UTC (permalink / raw) To: Chris Hecker; +Cc: caml-list > The "scan" function in the code below works if it's at global scope, > but not if it's defined inside the test2 function. Is this a bug or a > typing restriction? I assume the latter (and that I could have boiled > this example to one of the ones in the FAQ?), but I don't understand > these kinds of polymorphism typing issues. > > Chris > > > type t = > Foo of int > | Bar of int * int > > exception FB of t > > > (* works *) > let scan s (fmt : ('a, Scanf.Scanning.scanbuf, 'b) format) f = > try > raise (FB (Scanf.sscanf s fmt f)) > with > End_of_file | Scanf.Scan_failure _ -> () > > let test () = > let line = "Foo 1" in > try > scan line "Foo %d" (fun i -> Foo i); > scan line "Bar %d %d" (fun i j -> Bar (i,j)); > failwith "bad line" > with > FB t -> t > > (* doesn't work *) > let test2 () = > let line = "Foo 1" in > let scan s (fmt : ('a, Scanf.Scanning.scanbuf, 'b) format) f = > try > raise (FB (Scanf.sscanf s fmt f)); > () > with > End_of_file | Scanf.Scan_failure _ -> () > in > try > scan line "Foo %d" (fun i -> Foo i); > scan line "Bar %d %d" (fun i j -> Bar (i,j)); > failwith "bad line" > with > FB t -> t > > ------------------- > To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr > Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ > Beginner's list: http://groups.yahoo.com/group/ocaml_beginners This is unrelated to Scanf (apart from the fact that sscanf is polymorphic). This is not a bug, this is not a typing restriction, this is an ugly semantics of type constraints. The problem is that type variables in type constraints are shared (are not generalized whatsoever) in a whole definition. Hence, the 'a and 'b in your format specification accumulate incompatible type constraints (type instance unifications), hence the typing error reported by the compiler. On the other hand, when the scan function is global, 'a and 'b are generalized at the hand of the definition as usual (since their is no use of scan, hence no instanctiation of 'a nor 'b). Hence the global definition does not behave teh same as the local one. To give a simpler example, consider this simple (working) code snippet: # let test () = let f x = x in f 1; f "1";; Warning: this expression should have type unit. val test : unit -> string = <fun> Now, consider I add a single (and useless) type constraint on the x parameter of f, just stating that it should have a type: # let test () = let f (x : 'a) = x in f 1; f "1" ;; Warning: this expression should have type unit. This expression has type string but is here used with type int The phrase it rejected since the type ('a) of the parameter (x) of f has been instantiated once with int, and then further instantiation to string fails (the warning emitted by the compiler clearly states that "f 1" was properly type-checked). Thnaks for the interesting example, that could help us to revised the semantics of type constraints in Caml, still having in mind that global and local definition should always behave the same. Pierre Weis INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://pauillac.inria.fr/~weis/ ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] monomorphic restriction or typing/scanf bug? 2002-10-15 12:19 ` Pierre Weis @ 2002-10-15 21:03 ` Chris Hecker 2002-10-15 21:20 ` Chris Hecker [not found] ` <Pine.LNX.4.44.0210151424320.453-100000@grace.speakeasy.net > 0 siblings, 2 replies; 7+ messages in thread From: Chris Hecker @ 2002-10-15 21:03 UTC (permalink / raw) To: caml-list jacques: >The standard workaround is to use nameless ones. Excellent, that's a fine workaround for my case! pierre: >Thanks for the interesting example, that could help us to revised the >semantics of type constraints in Caml, still having in mind that >global and local definition should always behave the same. No problem. That's the part that confused me about it, since I figured any type restriction problem (a la the FAQ) would manifest itself both globally and locally (except, now that I think about it the "can't generalize ref" only happens globally). Now, if only we could have local exceptions to make those "C break-like exception patterns" easier! Thanks guys, Chris ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [Caml-list] monomorphic restriction or typing/scanf bug? 2002-10-15 21:03 ` Chris Hecker @ 2002-10-15 21:20 ` Chris Hecker [not found] ` <Pine.LNX.4.44.0210151424320.453-100000@grace.speakeasy.net > 1 sibling, 0 replies; 7+ messages in thread From: Chris Hecker @ 2002-10-15 21:20 UTC (permalink / raw) To: caml-list >Excellent, that's a fine workaround for my case! Actually, I just realized that I didn't need the explicit type declaration on there at all. Hmm, I could have sword there was some case like this where I needed it with printf et al. Oh well. Chris ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 7+ messages in thread
[parent not found: <Pine.LNX.4.44.0210151424320.453-100000@grace.speakeasy.net >]
* Re: [Caml-list] monomorphic restriction or typing/scanf bug? [not found] ` <Pine.LNX.4.44.0210151424320.453-100000@grace.speakeasy.net > @ 2002-10-16 1:53 ` Chris Hecker 2002-10-16 6:42 ` [Caml-list] Local open (was: monomorphic restriction or typing/scanf bug?) Alain Frisch 0 siblings, 1 reply; 7+ messages in thread From: Chris Hecker @ 2002-10-16 1:53 UTC (permalink / raw) To: caml-list [Brian sent this to me privately, but it was a good point I forgot about, so I'm replying publicly.] At 14:31 10/15/2002 -0700, brogoff@speakeasy.net wrote: >On Tue, 15 Oct 2002, Chris Hecker wrote: > > Now, if only we could have local exceptions to make those "C break-like > > exception patterns" easier! >Why do the exceptions need anything more than module locality, especially >when function locality can be achieved with local modules? Ack, I forgot about that solution, and forgot the specifics of the fact that I asked about this and there was a thread about it over a year ago: http://groups.google.com/groups?th=6f10c8b9743e7f20 I actually didn't forget that I asked, but for some reason I thought the restrictions on types escaping the local modules applied to exceptions as well. Oops! Thanks for pointing it out! Of course, as that thread says, "let exception Blah" would be nice, or "local open" to make this pattern nicer to work with. Anyway, using all of the ideas from this thread leads me to the following simple answer to my earlier post (which is closely related to the earlier post about scanf in pattern matching): type t = Foo of int | Bar of int * int let test line = let module Scan = struct exception Result of t let scan s fmt f = try raise (Result (Scanf.sscanf s fmt f)) with End_of_file | Scanf.Scan_failure _ -> () end in try Scan.scan line "Foo %d" (fun i -> Foo i); Scan.scan line "Bar %d %d" (fun i j -> Bar (i,j)); failwith "bad line" with Scan.Result t -> t # test "Foo 1";; - : t = Foo 1 # test "Bar 1 2";; - : t = Bar (1, 2) # test "Bar 1";; Exception: Failure "bad line". Chris ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 7+ messages in thread
* [Caml-list] Local open (was: monomorphic restriction or typing/scanf bug?) 2002-10-16 1:53 ` Chris Hecker @ 2002-10-16 6:42 ` Alain Frisch 0 siblings, 0 replies; 7+ messages in thread From: Alain Frisch @ 2002-10-16 6:42 UTC (permalink / raw) To: Chris Hecker; +Cc: caml-list On Tue, 15 Oct 2002, Chris Hecker wrote: > Of course, as that thread says, "let exception Blah" would be nice, or > "local open" to make this pattern nicer to work with. cf http://www.eleves.ens.fr/home/frisch/soft#openin With the syntax extension below, you can do: glouglou ~/openin $ ocaml camlp4o.cma pa_openin.cmo Objective Caml version 3.06 Camlp4 Parsing version 3.06 # let () = open Unix in ();; # let () = struct exception E end in raise E;; Exception: E. That is: local open and local structure items. Of course, you get ugly error messages when trying to have a type escape its scope: # let () = struct type t = A end in A;; This `let module' expression has type OPENIN_5.t In this type, the locally bound module name OPENIN_5 escapes its scope Here is the code of the syntax extension: let no = ref 0 let local_struct loc st e = incr no; let x = "OPENIN_" ^ (string_of_int !no) in let st = st @ [<:str_item< value res = $e$ >>] in <:expr< let module $x$ = struct $list: st$ end in ($uid:x$.res) >> EXTEND GLOBAL: Pcaml.expr; Pcaml.expr: LEVEL "expr1" [ [ "open"; i = LIST1 UIDENT SEP "."; "in"; e = Pcaml.expr LEVEL "top" -> local_struct loc [<:str_item< open $i$ >>] e | "struct"; st = LIST0 [ s = Pcaml.str_item; OPT ";;" -> s ]; "end"; "in"; e = Pcaml.expr LEVEL "top" -> local_struct loc st e ] ]; END -- Alain ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2002-10-16 6:43 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2002-10-15 3:29 [Caml-list] monomorphic restriction or typing/scanf bug? Chris Hecker 2002-10-15 3:51 ` Jacques Garrigue 2002-10-15 12:19 ` Pierre Weis 2002-10-15 21:03 ` Chris Hecker 2002-10-15 21:20 ` Chris Hecker [not found] ` <Pine.LNX.4.44.0210151424320.453-100000@grace.speakeasy.net > 2002-10-16 1:53 ` Chris Hecker 2002-10-16 6:42 ` [Caml-list] Local open (was: monomorphic restriction or typing/scanf bug?) Alain Frisch
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox