From mboxrd@z Thu Jan 1 00:00:00 1970 Received: by margaux.inria.fr, Wed, 17 Nov 93 15:41:42 +0100 Received: from concorde.inria.fr by margaux.inria.fr, Tue, 16 Nov 93 22:34:51 +0100 Received: from Tamuz.Stanford.EDU by concorde.inria.fr; Tue, 16 Nov 1993 22:37:57 +0100 Received: by Tamuz.Stanford.EDU (5.61/25-theory-eef) id AA28706; Tue, 16 Nov 93 13:37:45 -0800 From: Xavier Leroy Message-Id: <9311162137.AA28706@Tamuz.Stanford.EDU> Subject: Re: Is this supposed to happen? To: onomoto@netcom.com (Young and Loud) Date: Tue, 16 Nov 1993 13:37:40 -0800 (PST) Cc: caml-list@margaux In-Reply-To: <199311161813.KAA02998@mail.netcom.com> from "Young and Loud" at Nov 16, 93 10:14:56 am Content-Type: text/plain Sender: weis@margaux Dear Young and Loud, The short answer to your question is: yes, this is supposed to happen. One could argue that what actually happens is, always, in some sense, supposed to happen, but let's not get into philosophy. In this particular case, it's not even a bug; it's a feature -- though the error message could indeed be made more informative . What happens is that in Caml record type declarations are generative, just like sum type ("concrete" type) declarations. Hence, when you define type bar = { a : int; c : float } ;; you define two labels, "a" from int to bar, and "c" from float to bar. Following the standard lexical scoping rules, this label "a" hides the one defined before as part of the declaration of "foo". Hence, when you write let v1 = { a = 1; b = "typefoo?" } ;; the typechecker complains that you're mixing labels from two different record types: "a" from "bar" and "b" from "foo". It says this in slightly less explicit terms, but that's the, uh, intended meaning. The bottom line is: once you've declared "bar", you won't be able to build any values of type "foo", because the "a" label of "foo" is no longer reachable. The behavior you expected -- if you give "a" and "b", then that's a record of type "foo"; if you give "a" and "c", that's a record of type "bar" -- requires a different treatment of record labels, as in SML or Caml V3.1. SML does not declare record types; Caml V3.1 declares record types, but allows overloading of labels. Both approaches make programming with record more comfortable, but add considerable complexity to the type inference algorithm, and result in some programs being rejected as ambiguous for reasons that are hard to figure out. Hope this helps, - Xavier Leroy PS. Just for the record, Caml Light is not an "interpreter", but a bytecode compiler. Admittedly, it's not GCC, but it's not QBasic either.