caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* '_a
@ 2005-01-27  0:19 Mike Hamburg
  2005-01-27  0:51 ` [Caml-list] '_a Jacques Garrigue
  0 siblings, 1 reply; 19+ messages in thread
From: Mike Hamburg @ 2005-01-27  0:19 UTC (permalink / raw)
  To: caml-list

The appearance of '_a in places where it shouldn't appear causes some 
annoyance, and a good deal of confusion among beginners to O'Caml.  In 
particular, List.map (fun x -> x) "ought to" have type 'a list -> 'a 
list, whereas it instead has type '_a list -> '_a list.

Some types are treated specially for creation of '_a, such as refs and 
arrays.  For instance, if you have the following two declarations:

# let a = let f x () = [x] in f [];;
val a : unit -> 'a list list = <fun>
# let b = let f x () = [|x|] in f [];;
val b : unit -> '_a list array = <fun>

Although I haven't read the code for O'Caml, I deduce from this that 
there is deep magic in place to determine when to turn 'a into '_a, and 
in many cases, the heuristic is wrong (in the conservative direction: 
in this case, 'a should not be turned into '_a until b is applied).

The cause of the problem is that programs may create a closure with a 
mutable variable of type 'a, which if we were to let 'a generalize 
could be replaced with a subtype 'b of 'a, and then used as another 
subtype 'c of 'a, which would be unsafe.

As a fix, I propose the following: the type system should keep track of 
where a mutable or immutable reference to a polymorphic variable with 
type parameter 'a is created on the stack.  Call these places [m'a] and 
[i'a].  For example, ref should have type 'a -> [m'a] 'a, and ref [] 
should have type [m'a] 'a (which is equivalent to the current '_a).  I 
don't propose that the printing should show this complexity, just as it 
hides whatever heuristic O'Caml is using now, except in the case where 
there is a mutable reference at top level, in which case it should 
convert 'a to '_a.

Of course, module interfaces shouldn't have to show when they keep 
references to things, so we probably can't do much about applying 
List.map to the identity without modifying List (for instance, what if 
List.map decided to memoize the function fed into it using a hash 
table?).

Is this a reasonable idea?  If so, can someone give me a pointer on how 
to go about implementing it (or proving that it is type-safe with 
appropriate unification rules?)?

Mike


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

end of thread, other threads:[~2005-02-03  7:42 UTC | newest]

Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-01-27  0:19 '_a Mike Hamburg
2005-01-27  0:51 ` [Caml-list] '_a Jacques Garrigue
2005-01-27  9:34   ` skaller
2005-01-27 10:02     ` Alex Baretta
2005-01-27 14:13     ` '_a Vincenzo Ciancia
2005-01-27 19:39       ` [Caml-list] '_a Jacques Carette
2005-01-28  0:57       ` skaller
2005-01-28 13:25         ` '_a Stefan Monnier
2005-01-28 14:46           ` [Caml-list] '_a skaller
2005-01-28 14:46           ` Keith Wansbrough
2005-01-28 15:48             ` skaller
2005-01-29  1:37               ` Michael Walter
2005-01-28 13:42         ` Christophe TROESTLER
2005-01-28 14:50           ` skaller
2005-01-28 12:54       ` Richard Jones
2005-01-28 14:39         ` Alex Baretta
2005-01-29  0:33   ` [Caml-list] '_a Dave Berry
2005-02-02  9:17     ` Jacques Garrigue
2005-02-03  7:41   ` Florian Hars

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