From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.1.3 (2006-06-01) on yquem.inria.fr X-Spam-Level: X-Spam-Status: No, score=0.9 required=5.0 tests=AWL,DNS_FROM_RFC_ABUSE autolearn=disabled version=3.1.3 X-Original-To: caml-list@yquem.inria.fr Delivered-To: caml-list@yquem.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by yquem.inria.fr (Postfix) with ESMTP id 0A471BBAF for ; Sun, 5 Apr 2009 12:04:46 +0200 (CEST) X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: Av4CACsf2EnUGyoDlGdsb2JhbACWJgEBAQEJCwgJEQOzBoQPBg X-IronPort-AV: E=Sophos;i="4.39,325,1235948400"; d="scan'208";a="25664207" Received: from smtp3-g21.free.fr ([212.27.42.3]) by mail3-smtp-sop.national.inria.fr with ESMTP; 05 Apr 2009 12:04:44 +0200 Received: from smtp3-g21.free.fr (localhost [127.0.0.1]) by smtp3-g21.free.fr (Postfix) with ESMTP id 521C1818131; Sun, 5 Apr 2009 12:04:37 +0200 (CEST) Received: from [192.168.17.1] (ivr94-8-88-162-26-239.fbx.proxad.net [88.162.26.239]) by smtp3-g21.free.fr (Postfix) with ESMTP id F14F481810A; Sun, 5 Apr 2009 12:04:34 +0200 (CEST) Message-ID: <49D8828C.40402@users.sourceforge.net> Date: Sun, 05 Apr 2009 12:06:04 +0200 From: Zheng Li User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1b4pre) Gecko/20090404 Lightning/1.0pre Shredder/3.0b3pre MIME-Version: 1.0 To: David Rajchenbach-Teller Cc: Goswin von Brederlow , Daniel Buenzli , OCaml List Subject: Re: Strings References: <200904031256.33357.jon@ffconsultancy.com> <200904031546.14071.jon@ffconsultancy.com> <49D63EE6.2020407@ens-lyon.org> <8697F924-0485-4E00-81DF-9BCF74D872EA@erratique.ch> <87prftifa3.fsf@frosties.localdomain> <1238836234.6250.6.camel@Blefuscu> In-Reply-To: <1238836234.6250.6.camel@Blefuscu> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit X-Spam: no; 0.00; 0200,:01 mutable:01 foo:01 ocaml:01 foo:01 read-only:01 abstraction:01 val:01 val:01 compiler:01 read-only:01 mutable:01 2009:98 2009:98 sourceforge:01 On 4/4/2009 11:10 AM, David Rajchenbach-Teller wrote: > > On Fri, 2009-04-03 at 23:44 +0200, Goswin von Brederlow wrote: >> It wouldn't be too hard to change the string module to allow for both >> mutable and immutable strings: > > [...] > > Done in Batteries. > > # "foo";; (*OCaml base string*) > - : string = "foo" > # ro"foo";;(*Read-only string*) > - : [ `Read ] Batteries.String.Cap.t = ro"foo" With phantom type alone, the abstraction can still leak. ---- # open Batteries.String.Cap;; # let s = "asdf";; val s : string = "asdf" # let ro_s = read_only (of_string s);; val ro_s : [ `Read ] Batteries.String.Cap.t = ro"asdf" # s.[3] <- 'z';; # ro_s;; - : [ `Read ] Batteries.String.Cap.t = ro"asdz" ---- Well, this example is artificial. A more intuitive example would be (Look how similar it is with the previous os_type string example !): ---- # let ro_s = ro"asdf";; val ro_s : [ `Read ] Batteries.String.Cap.t = ro"asdf" # (to_string ro_s).[3] <- 'z';; .... ---- however, with no covariants defined in batteries' String.Cap.t type (why?), the second example won't compile. The compiler simply doesn't allow me to print out a read-only string, nor does it allow many reasonable things like <> etc. I understand that the phantom trick can't guarantee the immutability in a whole since the underlying data type (if exposed) can still be mutable. However, String.Cap.t is not dealing with arbitrary polymorphic types here! it deals with just the specific primitive string type, and controlling capacity over standard string is the only thing it intend to do. String.copy on the border might solve this problem, even though there could still be other issues left. All the best -- Zheng