# Revelations

A revelation introduces information about an opaque type into a scope. Unlike other declarations, revelations introduce no new names.

There are two kinds of revelations, partial and complete. A program can contain any number of partial revelations for an opaque type; it must contain exactly one complete revelation.

A partial revelation has the form:

        REVEAL T <: V

where `V` is a type expression (possibly just a name) and `T` is an identifier (possibly qualified) declared as an opaque type. It reveals that `V` is a supertype of `T`.

In any scope, the revealed supertypes of an opaque type must be linearly ordered by the subtype relation. That is, if it is revealed that `T <: U1` and `T <: U2`, it must also be revealed either that `U1 <: U2` or that `U2 <: U1`.

A complete revelation has the form:

        REVEAL T = V

where `V` is a type expression (not just a name) whose outermost type constructor is a branded reference or object type and `T` is an identifier (possibly qualified) that has been declared as an opaque type. The revelation specifies that `V` is the concrete type for `T`. It is a static error if any type revealed in any scope as a supertype of `T` is not a supertype of `V`. Generally this error is detected at link time.

Distinct opaque types have distinct concrete types, since `V` includes a brand and all brands in a program are distinct.

A revelation is allowed only in an interface or in the outermost scope of a module. A revelation in an interface can be imported into any scope where it is required, as illustrated by the stack example.

For example, consider:

        INTERFACE I; TYPE T <: ROOT; PROCEDURE P(x:T): T; END I.

        INTERFACE IClass; IMPORT I; REVEAL I.T <: MUTEX; END IClass.

        INTERFACE IRep; IMPORT I;
          REVEAL I.T = MUTEX BRANDED OBJECT count: INTEGER END;
        END IRep.

An importer of `I` sees `I.T` as an opaque subtype of `ROOT`, and is limited to allocating objects of type `I.T`, passing them to `I.P`, or declaring subtypes of `I.T`. An importer of `IClass` sees that every `I.T` is a `MUTEX`, and can therefore lock objects of type `I.T`. Finally, an importer of `IRep` sees the concrete type, and can access the `count` field.

    Last modified on Wed Apr  3 09:38:57 PST 1996 by heydon
         modified on Mon Apr 18 14:06:59 PDT 1994 by kalsow