caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* [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

* 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;
as well as URLs for NNTP newsgroup(s).