caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
From: Xavier Leroy <xavier.leroy@inria.fr>
To: Michael Vanier <mvanier@cs.caltech.edu>
Cc: pierre.weis@inria.fr, caml-list@inria.fr
Subject: Re: [Caml-list] simple typing question
Date: Tue, 2 Jul 2002 13:42:26 +0200	[thread overview]
Message-ID: <20020702134226.A18305@pauillac.inria.fr> (raw)
In-Reply-To: <200207020949.g629nQ606959@orchestra.cs.caltech.edu>; from mvanier@cs.caltech.edu on Tue, Jul 02, 2002 at 02:49:26AM -0700

> I *almost* understand.  I understand the need for restrictions with
> polymorphic references.  The stated rule is that for
> 
>   let name = expr1 ...
> 
>   The type of expr1 is generalized when expr1 is a function, an identifier
>   or a constant. Otherwise the identifier name is not polymorphic (type
>   variables are not generalized).
> 
> And later it's stated that when expr1 is "map (function x -> x)" it's an
> application, so it isn't generalized.  However, it's an application that
> evaluates to a function, so it seems like it would meet the stated
> criteria.

No, it doesn't.  There is a major difference between a literal
function "fun x -> ..." and an expression that evaluates to a
function.  The latter can create and hide polymorphic references, as
shown below.

> Also, I'm not sure why such a restrictive rule is needed.  If
> expr1 doesn't manipulate references, why can't it be generalized?

Because very similar expressions do manipulate references.  In
particular, consider that a (polymorphic) function can "hide" a
(polymorphic) reference.  For instance:

# let make_toggle () =
    let r = ref [] in fun x -> let old = !r in r := x; old
val make_toggle : unit -> 'a -> 'a list = <fun>

The result of make_toggle() is a function with type _a list -> _a list
that returns the argument that it received the last time it was called.

# let f = make_toggle();;
val f : '_a list -> '_a list = <fun>

# f [1;2;3];;
- : int list = []
# f [4;5;6];;
- : int list = [1; 2; 3]

Now, consider what happens if we were to generalize '_a in the type of f:

# let f = make_toggle();;
val f : 'a list -> 'a list = <fun>

# f [1;2;3];;
- : int list = []
# f ["hello"; "world"];;
- : string list = [1; 2; 3]    <--- crash! (wrong value for the type)

The gist of this example is that "make_toggle()" looks a lot like
"List.map (fun x -> x)" :  both are function applications that return
a function from '_a list to '_a list.  Yet, one is safe to generalize
and not the other.

No reasonably simple type system can distinguish both examples.  Many
have been proposed -- this was a hot research topic in the 1980-1993
time frame, and I even did my PhD on this very topic -- but none was
found to be really usable in practice.  The value restriction on
polymorphism (i.e. what Caml implements) is far from perfect, but is
the "least bad" of the known solutions.

- Xavier Leroy

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


  parent reply	other threads:[~2002-07-02 11:42 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2002-07-02  4:14 Michael Vanier
2002-07-02  9:14 ` Pierre Weis
2002-07-02  9:49   ` Michael Vanier
2002-07-02 11:29     ` Daniel de Rauglaudre
2002-07-02 11:42     ` Xavier Leroy [this message]
2002-07-02 18:57       ` Pixel
2002-07-02 20:59         ` Pierre Weis
2002-07-03  0:39           ` Pixel
2002-07-03  1:49             ` Jacques Garrigue
2002-07-03 23:24               ` Pixel
2002-07-03  7:51             ` Francois Pottier
2002-07-03 11:25               ` Pixel
2002-07-03 18:10       ` Lauri Alanko
2002-07-02 14:56     ` Pierre Weis

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20020702134226.A18305@pauillac.inria.fr \
    --to=xavier.leroy@inria.fr \
    --cc=caml-list@inria.fr \
    --cc=mvanier@cs.caltech.edu \
    --cc=pierre.weis@inria.fr \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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).