Re: Is this supposed to happen?

Xavier Leroy (xavier@Theory.Stanford.EDU)
Tue, 16 Nov 1993 13:37:40 -0800 (PST)

From: Xavier Leroy <xavier@Theory.Stanford.EDU>
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)
In-Reply-To: <199311161813.KAA02998@mail.netcom.com> from "Young and Loud" at Nov 16, 93 10:14:56 am

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 <blush>.

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.