From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail2-relais-roc.national.inria.fr (mail2-relais-roc.national.inria.fr [192.134.164.83]) by walapai.inria.fr (8.13.6/8.13.6) with ESMTP id p0IA2dIS011773 for ; Tue, 18 Jan 2011 11:02:39 +0100 X-IronPort-Anti-Spam-Filtered: true X-IronPort-Anti-Spam-Result: AgMBAKrzNE2LEwExhWdsb2JhbACkVRUBAQEVChgFH7YOAYxDBYVQiyI X-IronPort-AV: E=Sophos;i="4.60,338,1291590000"; d="scan'208";a="87323798" Received: from hera.mpi-sb.mpg.de ([139.19.1.49]) by mail2-smtp-roc.national.inria.fr with ESMTP/TLS/AES256-SHA; 18 Jan 2011 11:02:34 +0100 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=mpi-sb.mpg.de; s=mail200803; h=Message-ID:In-Reply-To: References:Date:Subject:From:To:Cc:MIME-Version:Content-Type: Content-Transfer-Encoding; bh=eNayVNyjf1MrSNGEbmWJwLId8yTYjCfl8s cXJukEC00=; b=pD6dKJmHpghajXDJ30pMrBD/sHfzV0hqAEG+nLEMW1d9gxWKJ9 MJmy5T6nN46/Byn+vLP85rsF64j/JDAcoPo9tqB9F2LKukgc8BHu5P0X2lIhiyOM Z3wFKrU+jxgCkOqSvyxldYhvvhckm54HWztLai/p4645X4yJt1cCAy3G0= Received: from maniac.mpi-klsb.mpg.de ([139.19.1.26]:59144) by hera.mpi-sb.mpg.de (envelope-from ) with esmtp (Exim 4.69) id 1Pf8OV-0003W3-Hx; Tue, 18 Jan 2011 11:02:33 +0100 Received: from local by maniac.mpi-klsb.mpg.de (envelope-from ) with local (Exim 4.69) id 1Pf8OV-0004gN-0v; Tue, 18 Jan 2011 11:02:31 +0100 Received: from 74.125.57.233 (SquirrelMail authenticated user rossberg) by mail.mpi-sws.org with HTTP; Tue, 18 Jan 2011 11:02:31 +0100 (CET) Message-ID: <7f9a42a3cac8ea539f9f48432cd8a5af.squirrel@mail.mpi-sws.org> In-Reply-To: <20110118020018.GI323@melkinpaasi.cs.helsinki.fi> References: <20110118020018.GI323@melkinpaasi.cs.helsinki.fi> Date: Tue, 18 Jan 2011 11:02:31 +0100 (CET) From: rossberg@mpi-sws.org To: "Lauri Alanko" Cc: caml-list@inria.fr User-Agent: SquirrelMail/1.4.15 MIME-Version: 1.0 Content-Type: text/plain;charset=iso-8859-15 Content-Transfer-Encoding: 8bit X-Priority: 3 (Normal) Importance: Normal Subject: Re: [Caml-list] Signature monomorphism in functors > module type S1 = sig > type t > end > > module type S2 = sig > include S1 > val v : t > end > > module type S3 = sig > module M : S1 > end > > module M2 : S2 = struct > type t = int > let v = 42 > end > > module M3A : S3 with module M = M2 = struct > module M = M2 > end > > module F(M_ : S1) : S3 with module M = M_ = struct > module M = M_ > end > > module M3B : S3 with module M = M2 = F(M2) > > > Here, M3A compiles ok, but when I try to do the same thing through a > functor, I get an error upon the definition of M3B: > > Error: Signature mismatch: > Modules do not match: > sig module M : sig type t = M2.t end end > is not included in > sig module M : sig type t = M2.t val v : t end end > Modules do not match: > sig type t = M2.t end > is not included in > sig type t = M2.t val v : t end > The field `v' is required but not provided > > I can kind of understand the problem: modules are implemented as > records, and signature coercions are translated to record > relayouts. The functor code expects the layout for S1, so the argument > M2 : S2 gets coerced into S1 and thus the extra fields in S2 are > hidden and cannot be exposed in the result of the functor. > > In my particular situation, this isn't a horrible problem, and I can > live with F(M2) : S3 with type M.t = M2.t, since the module M2 with > its extra fields is visible directly and doesn't need to be accessed > through F(M2). But still, this seems like a very unintuitive > limitation: abstracting a module member into a functor suddenly > changed the expressivity of the program. I disagree with this assessment: you can abstract the module just fine, as long as you do it at the signature you were using it at, namely S2, not S1. I don't think it should be surprising that you narrow the type of an expression when you narrow the types of its free variables. > It also seems to stem > directly from implementation limitations instead of any theoretical > problems. I wouldn't say so. Coercive subtyping is not just an implementation detail, it is an essential part of the language design and semantics, and visible in other places. It might not be the only possible design, but it's not clear what the alternatives would be, either. Consider for example: module F (X : sig val x : int end) = struct val y = 1 include X val z = x + y end Without coercive subtyping semantics, what would be the meaning of: module A = F (struct val x = 2 val y = 3 end) Would it even be legal? If not, why not? And then consider the case where y isn't a value but a type. /Andreas