From: Didier Remy <Didier.Remy@inria.fr>
To: David Monniaux <David.Monniaux@ens.fr>
Cc: Liste CAML <caml-list@inria.fr>
Subject: Re: generalization in tuples
Date: Tue, 17 Oct 2000 10:11:55 +0200 [thread overview]
Message-ID: <20001017101155.A16955@morgon.inria.fr> (raw)
In-Reply-To: <Pine.GSO.4.03.10010161015350.24630-100000@basilic.ens.fr>
On Mon, Oct 16, 2000 at 02:42:11PM +0200, David Monniaux wrote:
> 1/ Is it possible to do what I want to do, even if it means using a
> kludge? The above code, using multiple let's, is not good: it's not
> useable in the middle of an expression (this is for CamlP4-generated
> code).
>
> (acceptable kludges include the use of Obj.magic)
In principle, Obj.magic should do the job, but it does not:
Obj.magic (fun x -> x)
is treated as an application and returns a weak type ;-(
The problem is that "Obj.magic" is defined as a primitive and the above is
typed as any other application, but I don't see any reason except technical
to treat Obj.magic as a constructor. Anyway, I don't think Obj.magic is
a good fix...
> 2/ Is there a finer notion of a "generalizable" expression that
> encompasses the above code, and could the "let generalization" procedure
> in the compiler be improved so that the above code gets a polymorphic
> type?
Yes, there is a very simple generalization of the value-only polymorphism
restriction.
Expressions need to be partitioned into two sets: expansive and
non-expansive expressions, such that the evaluation of non-expansive is
guaranteed not to create any storage.
For instance, non-expansive expressions may include variables, values (hence
functions), as well as constructors applied to non-expansive expressions.
Note that subexpressions of non-expansive expression are often expansive
(e.g. typically when the expression is under lambda-abstraction).
Given an expression e, we are only interested in outer expansive
sub-expressions of e, i.e. those that are not sub-expressions of a
non-expansive sub-expression of e (in which case, they are protected from
evaluation).
When typing an expression e, all type variables appearing in at least one
outer expansive sub-expression of e may also be the type of a store cell
allocation and should not be generalized. All other type variables can be
generalized.
For instance, in (a simpler version of) your example:
let x = (ref [], fun x -> x);;
The expression (ref [], fun x -> x) has type 'a ref * ('b -> 'b);
here, "ref []" is an application, hence an (outer) expansive expression and
'a appearing in its type cannot be generalized. Conversely, "fun x -> x" is
non-expansive and since variable "'b" only appear in the type of this
non-expansive subexpression, it can be generalized.
A few more examples:
---------------------
let x = (let y = fun x -> x in ref y, y)
: ('a -> 'a) ref * ('a -> 'a)
Here 'a appears both in an outer expansive expansive expression and in a
non-expansive expressions. Hence it is dangerous can cannot be generalized.
let x = fun x -> ref x
: ('a -> 'a ref)
The expression is protected, i.e. non-expansive and "'a" can be
generalized.
(Note that this is a strict generalization of the actual solution.()
The implementation
-------------------
This is actually quite simple: while typeckecking an expression, just keep
track of whether the expression is the outermost non-expansive part of a
let-bound expression, and if not, make its variable non-generalizable.
In fact, I experimented this in MLART a while ago:
#morgon:~/caml/camlart/src$ ./camlrun ./camltop -I lib
> Caml Light version 0.5 (modified with extensible records)
#(ref 1, fun x -> x);;
- : int ref * ('a -> 'a) = ref 1, <fun>
or, using extensible records :-)
#{!a = fun x -> x};;
> Toplevel input:
>{!a = fun x -> x};;
>^^^^^^^^^^^^^^^^^^^
> Cannot generalize 'a in {a : mut. 'a -> 'a; abs. 'b}
#{!a =1; b = fun x -> x};;
- : {a : mut. int; b : pre. 'a -> 'a; abs. 'b} = {!a = 1; b = <fun>}
#
-Didier
PS:
This has never been implemented in Ocaml, probably because, besides me,
you are one of first persons to complain about the drastic implementation of
value-only polymorphism restriction.
next prev parent reply other threads:[~2000-10-17 15:58 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2000-10-16 12:42 David Monniaux
2000-10-17 8:11 ` Didier Remy [this message]
2000-10-17 19:17 ` Didier Remy
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=20001017101155.A16955@morgon.inria.fr \
--to=didier.remy@inria.fr \
--cc=David.Monniaux@ens.fr \
--cc=caml-list@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