From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Original-To: caml-list@sympa.inria.fr Delivered-To: caml-list@sympa.inria.fr Received: from mail3-relais-sop.national.inria.fr (mail3-relais-sop.national.inria.fr [192.134.164.104]) by sympa.inria.fr (Postfix) with ESMTPS id 5F6F37EC76 for ; Wed, 13 May 2015 00:36:26 +0200 (CEST) Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of yallop@gmail.com) identity=pra; client-ip=209.85.220.169; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail3-smtp-sop.national.inria.fr: domain of yallop@gmail.com designates 209.85.220.169 as permitted sender) identity=mailfrom; client-ip=209.85.220.169; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible; x-record-type="v=spf1" Received-SPF: None (mail3-smtp-sop.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-qk0-f169.google.com) identity=helo; client-ip=209.85.220.169; receiver=mail3-smtp-sop.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="postmaster@mail-qk0-f169.google.com"; x-conformance=sidf_compatible X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: A0DyAQB1f1JVlKncVdFchEEGgxjJcgKBMQc8EAEBAQEBAQERAQEBAQcLCwkfMIQhAQEEEhEdARsdAQMMBgULDQICJgICIgERAQUBHAYTIod0AQMSqhM+MYs4gWuCd4lCChknDVeEJQEBAQEGAQEBARgBBQ6BE4oYhQUHgmiBRQWdOZUjEiOBDAmCKR+BUz0xgkYBAQE X-IPAS-Result: A0DyAQB1f1JVlKncVdFchEEGgxjJcgKBMQc8EAEBAQEBAQERAQEBAQcLCwkfMIQhAQEEEhEdARsdAQMMBgULDQICJgICIgERAQUBHAYTIod0AQMSqhM+MYs4gWuCd4lCChknDVeEJQEBAQEGAQEBARgBBQ6BE4oYhQUHgmiBRQWdOZUjEiOBDAmCKR+BUz0xgkYBAQE X-IronPort-AV: E=Sophos;i="5.13,418,1427752800"; d="scan'208";a="118098427" Received: from mail-qk0-f169.google.com ([209.85.220.169]) by mail3-smtp-sop.national.inria.fr with ESMTP/TLS/RC4-SHA; 13 May 2015 00:36:25 +0200 Received: by qku63 with SMTP id 63so16675459qku.3 for ; Tue, 12 May 2015 15:36:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=zJGMmpxSEek4zvIyLks7k8N4XNFmj8f4rvYmNts58vk=; b=uXZNdfPwQ1nOWNvLcg1JF3Xak8G4iaaGZqGGPfLAMu5YN0PBpsFWfmaE1QEuc7hcCs 8RCVT2q9lW8rLofY18s8iwZeMBMf9gNWO/qBBZmImrCMRoMA/JEj5fQa3lHKiLKmuVFR b9OG51JB3y7fE+9i25Tptz9NOLiofHkIp+V2xz+meIQx91ue0PhrflRhNUutvBo91QQ9 wqjlSThEZhclu5mw8bDAfJnAFzTI05spxPzuGYiTtRradLwnvxi3T6kVbnfHRiiRBbVx mKxbRHj8XpEKDQrj5ZlqAmZWZHYayOW3xDMBzBDBlhoMG8I1U3u6HFPuo9GThjG/5YL7 koGQ== MIME-Version: 1.0 X-Received: by 10.140.108.201 with SMTP id j67mr22493484qgf.79.1431470184189; Tue, 12 May 2015 15:36:24 -0700 (PDT) Received: by 10.229.40.7 with HTTP; Tue, 12 May 2015 15:36:24 -0700 (PDT) In-Reply-To: References: Date: Tue, 12 May 2015 23:36:24 +0100 Message-ID: From: Jeremy Yallop To: peterfrey Cc: "caml-list@inria.fr" Content-Type: text/plain; charset=UTF-8 Subject: Re: [Caml-list] Repacking modules gives unexpected results On 12 May 2015 at 22:47, peterfrey wrote: > (* I am running into a very strange problem with re-packed modules: > re-packed instances of variables take on their new values, but internal > functions that depend on those values are still tied to the initial > values. I think you're thinking of modules as a way of defining something like objects, where variables bound within the module behave like member variables that can be overridden. In fact, modules are not very much like objects, and variables bound in modules have the same lexical scope as most of the rest of the language. In particular, in this definition: struct let buf = Data.initial let len = (Bytes.length Data.initial) let show() = sprintf"len:%i\tbuf:%s" len buf end the names 'len' and 'buf' in the definition of 'show' will always refer to the nearest bindings for those names in the scope *in which show was defined*, no matter what you do elsewhere in the program. OCaml programmers tend to think of this kind of lexical scope as a feature, since it makes it quite straightforward to understand and refactor code. A little further down you have include (val env:ELT) let buf = "aBar" let len = 4 which, when you substitute in the value of 'env', and expand the 'include', gives you something equivalent to this: let buf = Data.initial let len = (Bytes.length Data.initial) let show() = sprintf"len:%i\tbuf:%s" len buf let buf = "aBar" let len = 4 Although the names 'buf' and 'len' are rebound, the rebindings don't have any effect on the uses of the previous bindings in the definition of 'show'. Again, there's nothing module-specific going on here; you'll see the same behaviour if you enter the definitions at the top-level. OCaml does have a system of objects and classes which behaves in something like the way that you're expecting. For example, you can write: class make ~initial = object val buf = initial val len = String.length initial method show = Printf.sprintf "len:%i\tbuf:%s" len buf method repack ~buf ~len = {< buf = buf; len = len >} end and then # let s = new make ~initial:"foo";; val s : make = # s#show;; - : string = "len:3\tbuf:foo" # let s' = s#repack ~buf:"aBar" ~len:4;; val s' : make = # s'#show;; - : string = "len:4\tbuf:aBar" Jeremy.