From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by yquem.inria.fr (Postfix) with ESMTP id 0669BBC37 for ; Tue, 9 Feb 2010 19:48:55 +0100 (CET) X-IronPort-AV: E=Sophos;i="4.49,437,1262559600"; d="scan'208";a="56533406" Received: from 91-168-189-208.rev.libertysurf.net (HELO [192.168.1.2]) ([91.168.189.208]) by mail4-relais-sop.national.inria.fr with ESMTP/TLS/DHE-RSA-AES256-SHA; 09 Feb 2010 19:48:54 +0100 Message-ID: <4B71AD39.8020503@irisa.fr> Date: Tue, 09 Feb 2010 19:45:13 +0100 From: Tiphaine Turpin User-Agent: Thunderbird 2.0.0.19 (X11/20090216) MIME-Version: 1.0 To: Rich Neswold Cc: caml-list@inria.fr Subject: Re: [Caml-list] Preventing values from escaping a context References: <14cf844b1002081907y2900c313q97ae0cb6f4c92394@mail.gmail.com> <20100209.123813.39168535.garrigue@math.nagoya-u.ac.jp> <4B711D44.7040509@irisa.fr> <14cf844b1002091009p1a3181j793c2d6b2cdcbae5@mail.gmail.com> In-Reply-To: <14cf844b1002091009p1a3181j793c2d6b2cdcbae5@mail.gmail.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit X-Spam: no; 0.00; irisa:01 irisa:01 compiler:01 ocaml:01 sig:01 val:01 struct:01 accessors:01 intuitively:01 read-only:01 polymorphic:01 polymorphic:01 wrote:01 partial:01 caml-list:01 Rich Neswold a écrit : > On Tue, Feb 9, 2010 at 2:31 AM, Tiphaine Turpin > > wrote: > > Jacques Garrigue a écrit : > > From: Rich Neswold > > >> 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") *)