caml-list - the Caml user's mailing list
 help / color / mirror / Atom feed
* Is this supposed to happen?
@ 1993-11-16 18:14 Young and Loud
  1993-11-16 21:37 ` Xavier Leroy
  0 siblings, 1 reply; 2+ messages in thread
From: Young and Loud @ 1993-11-16 18:14 UTC (permalink / raw)
  To: caml-list

        (I've posted this to comp.lang.ml as well, but thought it ought to
be sent to the CAML list as well)


        This seems strange -- it's not at all what I wanted
to happen.  I'm running CAML-LIGHT on a Mac Centris 660AV.

(* begin code fragment *)
type foo ={
        a : int;
        b : string
} ;;

type bar = {
        a : int;
        c : float
} ;;

let v1 = {
        a = 1;
        b = "typefoo?"
} ;;

(* end fragment *)

        Running it through the interpreter, I get the following
error:
>.........{
>       a = 1;
>       b = "typefoo?"
>}...
> Expression of type bar
> cannot be used with type foo
- : unit = ()

        I'm a novice ML programmer, but I don't think I should
be getting that error -- help?

        Thanks in advance!

        -o






^ permalink raw reply	[flat|nested] 2+ messages in thread

* Re: Is this supposed to happen?
  1993-11-16 18:14 Is this supposed to happen? Young and Loud
@ 1993-11-16 21:37 ` Xavier Leroy
  0 siblings, 0 replies; 2+ messages in thread
From: Xavier Leroy @ 1993-11-16 21:37 UTC (permalink / raw)
  To: Young and Loud; +Cc: caml-list

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.




^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~1993-11-17 14:41 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
1993-11-16 18:14 Is this supposed to happen? Young and Loud
1993-11-16 21:37 ` Xavier Leroy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).