Version française
Home     About     Download     Resources     Contact us    
Browse thread
Preventing values from escaping a context
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
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") *)