Re: anonymous record types in variants

From: Xavier Leroy (Xavier.Leroy@inria.fr)
Date: Wed Feb 17 1999 - 10:32:59 MET


Date: Wed, 17 Feb 1999 10:32:59 +0100
From: Xavier Leroy <Xavier.Leroy@inria.fr>
To: Christopher Jeris <cjeris@math.mit.edu>, caml-list@inria.fr
Subject: Re: anonymous record types in variants
In-Reply-To: <Pine.SUN.4.03.9902121547070.10961-100000@severi.mit.edu>; from Christopher Jeris on Fri, Feb 12, 1999 at 03:53:57PM -0500

Christopher Jeris wrote:

> The argument of a variant type constructor cannot be an anonymous record
> type, i.e.:
>
> type foo = One of {one: int} | Two of {two: string}
>
> is rejected at the first {. Of course this is easy to work around, just
> give the record types names:
>
> type foo_one = {one: int}
> type foo_two = {two: string}
> type foo = One of foo_one | Two of foo_two
>
> But, just out of curiosity, is there a quick explanation of why it is this
> way?

Basically, because "{one : int}" is not a type expression, and the
argument of a constructor must be a type expression.

The reason why "{one : int}" is not a type expression but must be
declared and bound to a type name have to do with type inference
and the existence of principal types. If you allow record types in
type expressions (as in SML), some functions have no principal type,
such as fun x -> x.l.

Manuel Fahndrich wrote:

> I also find this the major annoying feature of CAML records. I frequently
> use variant datatypes with a number of fields. Without records, the field
> order matters and has to be remembered when creating and accessing such
> variants. Anonymous records would be ideal on variants, since they would not
> introduce the extra level of indirection that you get when you declare an
> explicit record type.

It could be implemented this way. However, if you declare the
datatype as

        type foo = A of {lbl1 : int; lbl2 : int}

you would be forced to pattern-match it as follows

        match x with A{lbl1 = x; lbl2 = y} -> ...

but you can't get access to the record itself and use the dot notation
on it, as in

        match x with A r -> ... r.x ... r.y ...

That's basically the same restrictions we currenty have on
constructors with multiple arguments (A of int * int) vs.
constructors taking a tuple (A of (int * int)), so maybe that's not
too bad.

Anton Moscal wrote:

> I agree. I often need the following usage of anonymous types:
> type text = int(*length*) * (File of string | Str of string | ...)
> (factorizing of the common fields in the variant types).
> SML allow this construction.

No, it doesn't. It has a "withtype" construct that just works around
the fact that type abbreviations and datatype declarations cannot be
mutually recursive. But in Caml we don't have this problem.

> Probably an optimal solution would
> be to allow anonymous types in any context.

You can kiss type inference goodbye, then.

Don Syme wrote:

> BTW, the type language of Mercury (and probably some other FP languages?)
> allows variants and records pretty much anywhere in a type structure.

What kind of type inference do they have?

- Xavier Leroy



This archive was generated by hypermail 2b29 : Sun Jan 02 2000 - 11:58:19 MET