Chapter 8

Collections

Limited Collection Types

Limited collections are subtypes of <collection> that are constrained to have a particular size or dimensions and that are constrained to hold elements of a particular type.

If C is a subclass of <collection> whose element type is indefinite T1, then it is possible to create any number of limited collection types that can be described as limited(C, of: T2, size: S).

Like a collection class, a limited collection type has a conceptual element type. The element type of limited(C, of: T2, size: S) is T2. T2 must be an instance of <type> and a subtype of T1. C is the base class of the new limited collection type.

S limits the size of instances of a limited collection type. S can be #f, which means no limitation, or a non-negative integer, which means that every instance of the limited collection type has exactly that many elements.

S must be #f if C is stretchy (e.g. <table>, <stretchy-vector>, or <deque>).

If C is <array> then it is also possible to create any number of limited collection types, which can be described as limited(<array>, of: T, dimensions: D). D must be a sequence of non-negative integers; the rank of each instance is size(D) and the dimensions of each instance are the elements of D. You cannot specify both size: and dimensions: in the same type.

Some limited collection types are instantiable. make(limited(C, ), ) returns a direct instance of some subclass of C. Typically this class is not standardized and its name is not exported, but it is valid for this class to be C itself. There is nothing special about this class; it is simply a class known to the applicable limited method and its creation is subject to all the usual sealing restrictions.

An object X is an instance of a limited collection type limited(C, of: T2, size: S) if and only if all of the following are true:

An object X is an instance of a type limited(C, of: T2, dimensions: D) if and only if all of the following are true:

Each element of an instance of a limited collection type must be an instance of the element type. Fetching an element of the collection is guaranteed to return an instance of the element type. Setting or initializing an element will check that the new element is an instance of the element type and signal an error of type <type-error> if it is not.

If L1 is a subtype of L2 and L2 is a limited collection type, then L1 is either a singleton of an instance of L2 or a limited collection type that satisfies one of the following sets of rules:

  1. If neither L1 nor L2 specifies a dimensions: attribute, let L1 be limited(C1, of: T1, size: S1), and L2 be limited(C2, of: T2, size: S2). All of the following must be true:
    • C1 is a subclass of C2.
    • If S2 is not #f, S1 = S2.
    • T1 and T2 are equivalent types.
  2. If either L1 or L2, specifies a dimensions: attribute, then all of the following must be true. Let L1 be limited(C1, of: T1, dimensions: D1), and L2 be either limited(C2, of: T2, dimensions: D2) or limited(C2, of: T2, size: S2).
    • C1 is a subclass of C2.
    • D1 is present (i.e. L1 must specify a dimensions attribute).
    • If D2 is present, D1 = D2.
    • If S2 is not #f, reduce1(\*, D1) = S2.
    • T1 and T2 are equivalent types.

The limited collection type limited(C, of: T, size: S) is a subtype of C. The limited collection type limited(C, of: T, dimensions: D) is a subtype of C.

Element Type Subclassing

The element type subclassing rules are generalized to limited collection types as follows (this is implied by the preceding and is included here for explanatory purposes only):

If the element type of a limited collection type L1 is T1, each instance of L1 stores elements of type T1. The element method will always return an instance of T1 and the element-setter method will accept any instance of T1. Each limited collection type that is a subtype of L1 must have an element type T2 that is equivalent to T1.

If the element type of a class C1 is indefinite T1, each limited collection type that is a subtype of C1 has an element type T2 and T2 must be a subtype of T1. Thus element on any instance of C1 will return an instance of T1 (and will not return all possible instances of T1 if T2 is a proper subtype of T1), and it is not determined by C1 what the applicable element-setter method will accept (hence the term indefinite).

The above statements about the value returned by element only apply when no default: keyword argument is specified.

Creating Limited Collection Types

You obtain a type object for a limited collection type by calling the limited generic function on a collection class. There are several built-in methods for limited specialized for specific subclasses of <collection>. Each of these methods accepts a required keyword argument of: and also accepts an optional keyword argument size: if the class is not stretchy. If the class is <array> the optional keyword argument dimensions: is also accepted. Each method returns a type. The returned type is never a class. If the size: keyword argument is accepted but not supplied, it defaults to #f.

Users cannot write portable methods for limited. There are no built-in methods for limited applicable to user-defined classes.

Uninstantiable Limited Collection Types

Methods on limited support the creation of uninstantiable limited types for the following classes:

Although limited types created from these classes cannot be instantiated, they are still useful as specializers.

Instantiable Limited Collection Types

Methods on limited support the creation of instantiable limited types for the following classes:

These methods are described in Chapter 12, The Built-In Functions, on page 263.

Errata: In the published book, <deque> is missing from the list of instantiable limited collection types. There is a method specialized on <deque> in the list of methods for limited, the discussion of which indicates that it is instantiable.