Chapter 6. Type-Of Operators

In Rax, every variable has to be given a type upon declaration. When long type definitions are used (e.g., sets of tuples with many fields), this can lead to a lot of copy-pasting of type definitions. To avoid this, Rax provides a type-of operator: \. For example, take a look at this code snippet:

    &: AU := 1.495978707E11;      // Type-of with normal real,
    \AU: Jupiter := 5.2;          // might even make code clearer.
    `print Jupiter * AU;          // Output: 777908927640

    {#}: setOfNum;
    \setOfNum: N := {1..4};       // \SetOfNum acts like a class.
    `print N;                     // Output: {1,2,3,4}

    [#:id, $:name]: tupName;
    \tupName: tn := [455, "jms"]; // \tupName works as expected.
    \   id := 773;          // \ works as expected.
    `print id ==;           // Output: false

    {\tupName}: Names;            // Make an id,name table.
    {[#: id, @:bday]}: Bdays;     // Make an id,bday table.

As the above example demonstrates, the type-of operator (\) can be used to get the type of even a field of a tuple. In Rax, the type-of operator can be used anywhere a type specifier can be used. The type-of operator in Rax also comes with two type-join operators that will combine two table types into the resulting type mirroring the way the join operator would combine two values into a resulting value. These two type-joins, >< and |><| work in conjunction with the join type-of operator: \() as the code below demonstrates:

    \(Names |><| Bdays): Pp :=    // Use type-of with type-|><|.
      {[1, "Jill", (@)"2015W22"]}; //
                                  //: id| name|        bday
    `print Pp;             // Output: --|-----|-------------------
                                  //:  1|"Jill"|2014-11-30T00:00:00

    \([#:a] >< [#:b]): T;         // Type-joins works on tuples!
    `print T;                     // Output: [a: 0, b: 0]

Note that the type-joins work on table types but also on tuple types, where the (value-) joins only work on table values and not on tuple values. There are two other type-of operators: the settify type-of: \{}, to join tuple types and settify the result into a table type, and the de-settify type-of: \[], to peal the set element type out of a set type. Below is a short example of how these two type-of operators can be used in conjunction with the aforementioned type-join operators:

    \({\T} >< {\T} |><| {\T}): D; // This quadruple type-of
    \{T >< T |><| T}: TTT;        // has a shorthand: \{}.
    `print TTT[1];                // Output: [a: 0, b: 0, a: 0, b: 0]

    \[Pp]: tupP := Pp[1];         // De-settify using: \[].
    `print;             // Output: Jill

Note that the last three type-of operator variations: \(), \{}, and \[] take either one or more tuple types or one or more table types as arguments to the type-join operators: >< and |><|. Note, however, that an ordered set of a non-tuple can be used as if it were a table with one column. Below an example of that followed by an disallowed combination of a table type and a tuple type:

    \(Pp >< {$}): tabPpColor;     // All osets are in fact tables.
    `print tabPpColor[1].id;      // Output: 0

    \{Pp >< T}: bad;              // Don't mix tables and tuples:

    // Error: Type mismatch in >< expected "[]", seen "{}"

A note to the language purists: all four type-of constructs can be seen as syntactic sugar since they can only be used by previously defined types.