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.0 required=5.0 tests=none autolearn=disabled version=3.1.3 Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by yquem.inria.fr (Postfix) with ESMTP id 30363BC69 for ; Thu, 8 Mar 2007 11:08:56 +0100 (CET) Received: from orion.metastack.com (no-dns-yet.demon.co.uk [80.177.38.218] (may be forged)) by concorde.inria.fr (8.13.6/8.13.6) with ESMTP id l28A8sH1009351 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=FAIL) for ; Thu, 8 Mar 2007 11:08:55 +0100 Received: from treble (cpc2-cmbg6-0-0-cust535.cmbg.cable.ntl.com [81.107.34.24]) (authenticated bits=0) by orion.metastack.com (8.13.4/8.13.3) with ESMTP id l289K6iu012551 (version=TLSv1/SSLv3 cipher=RC4-MD5 bits=128 verify=NO) for ; Thu, 8 Mar 2007 09:20:07 GMT From: "David Allsopp" To: "OCaml List" Subject: Polymorphism question... Date: Thu, 8 Mar 2007 10:08:52 -0000 Organization: MetaStack Solutions Ltd. Message-ID: <00c501c76169$c625e0e0$6a7ba8c0@treble> MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Mailer: Microsoft Office Outlook 11 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3028 Thread-Index: AcdhacWWTEvqYjkXSGWyi928O9ehiQ== X-Miltered: at concorde with ID 45EFE0B6.001 by Joe's j-chkmail (http://j-chkmail . ensmp . fr)! X-Spam: no; 0.00; polymorphism:01 sml:01 val:01 o'caml:01 unboxing:01 sml:01 val:01 o'caml:01 polymorphic:01 polymorphic:01 functions:01 functions:01 int:01 inferred:02 variables:02 If I write: let n = ref 0 in fun x -> incr n; x then I get a function with type '_a -> '_a --- i.e. with a non-instantiated type variable rather than the slightly curious polymorphic identity function that I was expecting. If I write: let n = ref 0 fun x -> incr n; x then I get a polymorphic function with type 'a -> 'a which was what I was after. My question: why does declaring the int ref n locally prevent the type of the function being generalised when if I just put n at "global" scope it would be? I'm sure there's a reason relating to the standard problem of refs and inferred polymorphic type variables, but I'm curious as to what is different in the type system between the two ways of expressing this. Furthermore, in SML, the code: local val n = ref 0 in fun f x = (n := !n + 1; x) end; correctly produces f : 'a -> 'a So what's different in O'Caml? David PS I hit this by mistake when sharing state variables between two related functions in a module. Rather than declaring: let some_global = ref whatever let function1 = (* something that uses some_global *) let function2 = (* something else that uses some_global *) let function3 = (* something different that doesn't use some_global *) I prefer to say: let (function1, function2) = let some_global = ref whatever in let function1 = ... and function2 = ... in (function1, function2) let function3 = ... and accept the unnecessary boxing/unboxing at program launch for a bit of program neatness (i.e. the "global" is only available to the functions that need it). SML has a neater construct for this where you can say local val some_global = ref whatever in fun function1 = ... and function2 = ... end; which is something I rather miss in O'Caml!