From mboxrd@z Thu Jan 1 00:00:00 1970 X-Sympa-To: caml-list@inria.fr Received: from mail4-relais-sop.national.inria.fr (mail4-relais-sop.national.inria.fr [192.134.164.105]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id q0AFj5EK026968 for ; Tue, 10 Jan 2012 16:45:09 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AmUBAGBcDE+K57AEmWdsb2JhbABDqiWCNSIBAQEBAQgLCwcUJYFyAQEFJwsBBUARCyEWDwkDAgECAUUTCAK/CIh3gxwEml2Mag X-IronPort-AV: E=Sophos;i="4.71,487,1320620400"; d="scan'208";a="126280482" Received: from ariane.ens-cachan.fr ([138.231.176.4]) by mail4-smtp-sop.national.inria.fr with ESMTP/TLS/ADH-AES256-SHA; 10 Jan 2012 16:45:09 +0100 Received: from localhost (localhost [127.0.0.1]) by ariane.ens-cachan.fr (Postfix) with ESMTP id 48D88BD08A for ; Tue, 10 Jan 2012 16:45:09 +0100 (CET) X-Virus-Scanned: Debian amavisd-new at ens-cachan.fr Received: from ariane.ens-cachan.fr ([127.0.0.1]) by localhost (ariane.ens-cachan.fr [127.0.0.1]) (amavisd-new, port 10026) with ESMTP id 4FvOyEmeq12k for ; Tue, 10 Jan 2012 16:45:09 +0100 (CET) Received: from olive.lsv.ens-cachan.fr (olive.lsv.ens-cachan.fr [138.231.81.248]) by ariane.ens-cachan.fr (Postfix) with ESMTP id 293F3BD057 for ; Tue, 10 Jan 2012 16:45:09 +0100 (CET) Received: from [138.231.81.43] (unknown [138.231.81.43]) by olive.lsv.ens-cachan.fr (Postfix) with ESMTP id 24A844C01CD for ; Tue, 10 Jan 2012 16:45:09 +0100 (CET) Message-ID: <4F0C5D33.7030405@lsv.ens-cachan.fr> Date: Tue, 10 Jan 2012 16:45:55 +0100 From: Romain Bardou User-Agent: Mozilla/5.0 (X11; U; Linux x86_64; en-US; rv:1.9.2.24) Gecko/20111114 Icedove/3.1.16 MIME-Version: 1.0 To: caml-list@inria.fr References: <1326209342.96423.YahooMailNeo@web111502.mail.gq1.yahoo.com> In-Reply-To: <1326209342.96423.YahooMailNeo@web111502.mail.gq1.yahoo.com> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 8bit X-Validation-by: bardou@lsv.ens-cachan.fr Subject: Re: [Caml-list] References and polymorphism Le 10/01/2012 16:29, Dario Teixeira a écrit : > Hi, > > Consider functions foobar1 and foobar2: > > > type 'a t = {id: int; x: 'a} > > let foobar1: 'a -> 'a t = > fun x -> {id = 0; x} > > let foobar2: 'a -> 'a t = > let ctr = ref 0 in > fun x -> incr ctr; {id = !ctr; x} > > > > I would expect them to have the same type, because foobar2's > use of a reference cell is kept private. However, they don't. > In fact, foobar2 is not really polymorphic: > > > type 'a t = { id : int; x : 'a; } > val foobar1 : 'a -> 'a t > val foobar2 : '_a -> '_a t > > > It's easy to get around this issue by putting the reference cell > outside of foobar2. Function foobar3 does just this, and behaves > as expected: > > > let next = > let ctr = ref 0 in > fun () -> incr ctr; !ctr > > let foobar3: 'a -> 'a t = > fun x -> {id = next (); x} > > > > Could someone point me to a good explanation of what's going on? > (I have the feeling I've read about this restriction before.) > > Best regards, > Dario Teixeira > > > Hello, This is, basically, the value restriction: you cannot let-generalize something which is not *syntactically* a value. Function foobar1 is syntactically a function, and a function is a value. Function foobar2 is not: it starts with a let-binding. It computes something before returning a function. It cannot be generalized. Cheers, -- Romain Bardou