Browse thread
Preventing values from escaping a context
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2010-02-09 (18:48) |
From: | Tiphaine Turpin <Tiphaine.Turpin@i...> |
Subject: | Re: [Caml-list] Preventing values from escaping a context |
Rich Neswold a écrit : > On Tue, Feb 9, 2010 at 2:31 AM, Tiphaine Turpin > <Tiphaine.Turpin@irisa.fr <mailto:Tiphaine.Turpin@irisa.fr>> wrote: > > Jacques Garrigue a écrit : > > From: Rich Neswold <rich.neswold@gmail.com > <mailto:rich.neswold@gmail.com>> > >> My question is this: Is there a way to make the compiler reject > a function > >> parameter from returning the context parameter? > > The short answer is no. > > Types are not sufficient to prevent values from escaping. > > In ocaml, you have both functions and references. > > > There is at least a partial solution using polymorhic records or other > ways of quantifying type variables inside a type expression : If you > artificially parameterise the type context with an unused > parameter (and > hide the type definition), you can then require the argument > function to > be polymorphic with respect to this parameter, which should prevent it > from returning or storing its argument. > > > I'm not understanding you fully, sorry. I tried this: > Sorry, I shouldn't have suggested such an exotic feature (polymorphic records) without any explanation. Here is an adaptation of your example. Of course, this kind of trick is not very intuitive, and using it in an API may not always be a good idea. Tiphaine module type Test = sig type 'a context = Context of int * int type 'b contextUser = {f : 'a . 'a context -> 'b} val usingContext : 'b contextUser -> 'b end module InsTest : Test = struct type 'a context = Context of int * int type 'b contextUser = {f : 'a . 'a context -> 'b} let usingContext f = f.f (Context (1, 2)) end open InsTest (* Allowed *) let _ = usingContext {f = function Context (x, _) -> x} (* Rejected *) let _ = usingContext {f = function x -> x} (* Allowed *) let _ = usingContext {f = function Context (x, y) -> Context (x, y)} (* If you also wanted to prevent this one, you could make the type "context" either asbtract, with accessors (if you want context information to be accessed only in restricted, "consistent" way) or private (intuitively, "read-only") *)