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 mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by sympa.inria.fr (Postfix) with ESMTPS id 737AB800BE for ; Thu, 9 Feb 2017 23:56:02 +0100 (CET) Authentication-Results: mail2-smtp-roc.national.inria.fr; spf=None smtp.pra=yallop@gmail.com; spf=Pass smtp.mailfrom=yallop@gmail.com; spf=None smtp.helo=postmaster@mail-qt0-f176.google.com Received-SPF: None (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of yallop@gmail.com) identity=pra; client-ip=209.85.216.176; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="yallop@gmail.com"; x-conformance=sidf_compatible Received-SPF: Pass (mail2-smtp-roc.national.inria.fr: domain of yallop@gmail.com designates 209.85.216.176 as permitted sender) identity=mailfrom; client-ip=209.85.216.176; receiver=mail2-smtp-roc.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 (mail2-smtp-roc.national.inria.fr: no sender authenticity information available from domain of postmaster@mail-qt0-f176.google.com) identity=helo; client-ip=209.85.216.176; receiver=mail2-smtp-roc.national.inria.fr; envelope-from="yallop@gmail.com"; x-sender="postmaster@mail-qt0-f176.google.com"; x-conformance=sidf_compatible IronPort-PHdr: =?us-ascii?q?9a23=3A6Fe/HB2Un1fmQVd3smDT+DRfVm0co7zxezQtwd8Z?= =?us-ascii?q?segXKPad9pjvdHbS+e9qxAeQG96Kt7QU1qGP6PGoGTRZp83e4DZaKN0EfiRGoP?= =?us-ascii?q?tVtjRoONSCB0z/IayiRA0BN+MGamVY+WqmO1NeAsf0ag6aiHSz6TkPBke3blIt?= =?us-ascii?q?dazdU7TfhMWv1u2054abI0AR3GL8MvtOK0CNsQjfuMQQybBnLaIyw1OduX5Pf+?= =?us-ascii?q?df7WhzY1mUhRDx4sP28ZJ+pXd+ofUkouxNS6j/buwJRLhcCyxuZ3E84MnsrTHM?= =?us-ascii?q?SAKO4j0XVWBAwUkAOBTM8ByvBsS5iSD9rOconXDCZcA=3D?= X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: =?us-ascii?q?A0BiAAB28pxYhrDYVdFdDg0BAQEDAQEBC?= =?us-ascii?q?QEBARUBAQEBAgEBAQEIAQEBAYUQB4NSigiSCoh8jDqCDYYiAoJlBz8YAQEBAQE?= =?us-ascii?q?BAQEBAQESAQEBCAsLCh0vgjMEARYBBIIXAQUjBBkBGx0BAwwGBQsNAgImAgIiA?= =?us-ascii?q?REBBQEcBhMIiVMBAxWjUj+MAoFrGAUBHIMJBYNiChknDVWDOQEBAQcBAQEBARs?= =?us-ascii?q?CBhJ5ijCHWoJfBZtyig+IBZEFkU4UHoEVH4E2HxMIFRU8F4QeIIEyO0A1iC2BT?= =?us-ascii?q?gEBAQ?= X-IPAS-Result: =?us-ascii?q?A0BiAAB28pxYhrDYVdFdDg0BAQEDAQEBCQEBARUBAQEBAgE?= =?us-ascii?q?BAQEIAQEBAYUQB4NSigiSCoh8jDqCDYYiAoJlBz8YAQEBAQEBAQEBAQESAQEBC?= =?us-ascii?q?AsLCh0vgjMEARYBBIIXAQUjBBkBGx0BAwwGBQsNAgImAgIiAREBBQEcBhMIiVM?= =?us-ascii?q?BAxWjUj+MAoFrGAUBHIMJBYNiChknDVWDOQEBAQcBAQEBARsCBhJ5ijCHWoJfB?= =?us-ascii?q?Ztyig+IBZEFkU4UHoEVH4E2HxMIFRU8F4QeIIEyO0A1iC2BTgEBAQ?= X-IronPort-AV: E=Sophos;i="5.35,138,1484002800"; d="scan'208";a="259638136" Received: from mail-qt0-f176.google.com ([209.85.216.176]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/AES128-GCM-SHA256; 09 Feb 2017 23:56:01 +0100 Received: by mail-qt0-f176.google.com with SMTP id k15so18958922qtg.3 for ; Thu, 09 Feb 2017 14:56:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=kmuTYfp8Lmv+WrgU0cT2nDRcUpVrdgVgtTsj6Tqbr6c=; b=J80jwPVEwWPoUypwNasS3LUq77xKfsxSWEVScReBrLAKTTMUGizcfWXTOduDOM9RbK LDMZ2Wo5gNPX/UuLDKgM8FgNVBEqmiCfKcim5g6bc6OEP+Aj1wjqqfAevlQsev3XSUyF XpWprWMEGfIF0oj819SI3cq5oKFnWquyPr9VzX/p8WtNBQHH6SOhsuho0/ilY1r1gUYF Q63rgflHQ+n9da7w3oLREUMyv/fxzxIkMz5QNpmBSN+OStLJlwpu+cUGJ6yk8RmBe57d 1dYyEfSOaFMqHgyzwvdIwsvgm2pQlR7NhmjKscjxz2kvUSRvJvhzQ7yfSJ8I/Xv4dSZq ZG4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:mime-version:in-reply-to:references:from:date :message-id:subject:to:cc; bh=kmuTYfp8Lmv+WrgU0cT2nDRcUpVrdgVgtTsj6Tqbr6c=; b=HX3lICB/owIyOXF4rq7DmiAueu1oQOpF+1RGbstpgsjjlrXha2lET0EUnPEid/d2JG XLtNwE/hRvYX7zzxteYRE6R9bQ0kvNuGsmrC6+XqiCRo00Mfyk67dbPGK0dZDevRc1TH 3mhwQ+/fn359kg+YbQNuPgpkdPEqicL2gBrf1EnTxg+GXzLleuH75YGmOaKGAZ/wTtaS R1K6K1jjSztBZpAXb+XMXBDOB/MXiCAwxDCjrYbNL0JdLqoCvuzqCwPD4dHF5V+6GkL8 qE9ZmjQr99/WK/gKtqLMTtUsqKOxlLzjltq2Tt0GEyn89bfFnoyoGUyEqIF6Y5QO/TnD oSUQ== X-Gm-Message-State: AMke39n1JBVmPvG3iLol497nQ0+C9ACf45K6UDOztiGtxtvec0MRqSl1svsJulNX8kFMYdQ+PX/8MSKzrJKISw== X-Received: by 10.200.50.18 with SMTP id x18mr5855906qta.58.1486680960496; Thu, 09 Feb 2017 14:56:00 -0800 (PST) MIME-Version: 1.0 Received: by 10.55.88.194 with HTTP; Thu, 9 Feb 2017 14:55:59 -0800 (PST) In-Reply-To: References: From: Jeremy Yallop Date: Thu, 9 Feb 2017 22:55:59 +0000 Message-ID: To: Steffen Smolka Cc: Caml List Content-Type: text/plain; charset=UTF-8 Subject: Re: [Caml-list] namespace inside object? Dear Steffen, On 9 February 2017 at 20:36, Steffen Smolka wrote: > Is it possible to create namespaces inside an object? Concretely, I would > like to write > > class buffer = object(self) > ... > method get = ... > > module Latin1 = struct > method get = ... > end > > module Utf8 = struct > method get = ... > end > end > > so that given an object b : buffer, I can call methods > b#get > b#Latin1.get > b#Utf8.get It's possible to achieve something like this using methods that return objects. If your nested objects don't need to access the internal state of the parent then you might write it like this: class buffer = let latin1 = object method get = ... end and utf8 = object method get = ... end in object(self) ... method get = ... method latin1 = latin1 method utf8 = utf8 end With this approach you can write b#get b#latin1#get b#utf8#get which, apart from some minor orthographic differences, looks like what you were aiming for. Your intuition that this isn't really idiomatic OCaml is right, though. In OCaml, unlike some other languages with classes and objects, classes are not usually used as namespaces; method names are globally (or, rather, "ambiently") scoped, and there's no real support for the kind of nesting that you're interested in. Instead, people typically build nested namespaces using modules: module Buffer = struct let get = ... module Latin1 = struct let get = ... end module Utf8 = struct let get = ... end end With the module approach you write the 'receiver' after the 'method' rather than before, but that doesn't seem like a huge hardship. (10% of the world manages to get by with VSO languages.) Buffer.get b ... Buffer.Latin1.get b ... Buffer.Utf8.get b ... If you're keen to stick with objects there are slightly more idiomatic ways to make it work. You could, of course, replace the '.' with a '_' and define methods 'latin1_get', 'utf8_get' in place of 'Latin1.get', 'Utf8.get'. Or you could select the encoding using a variant type: type enc = Latin1 | Utf8 class buffer = object (self) method get = function | Latin1 -> ... | Utf8 -> ... end Of course, the order of the words in an invocation changes again, but there's no real increase in complexity for the caller: b#get Latin1 b#get Utf8 This last approach can be taken quite far -- for example, you could enrich the type 'enc' so that the return type of 'get' varies according to the encoding. Kind regards, Jeremy