# 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.
\tn.id:   id := 773;          // \tn.id works as expected.
`print id == tn.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;                // Output: [a: 0, b: 0, a: 0, b: 0]

\[Pp]: tupP := Pp;         // De-settify using: \[].
`print tupP.name;             // 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.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.