# Chapter 10. More about types

Table of Contents

Type conversions

## Type conversions

Rax is a strong-typed language, which means that values of one type cannot be in general assigned to variables of a different type. The only exception to this rule is auto-casting of number values to the real type, if necessary. For example, the following are valid Rax statements:

```    &: real_number := 5;     // A constant of type # is auto-promoted to type &

& <- &: func <-
{ out := 2*in; };       // A constant of type # is auto-promoted to type &
// so that it can be multiplied by a value of type &

#: number := 10
`print func(number);      // A variable of type # is auto-promoted to type &
// so that 'func' can take it as a parameter
```

Auto-promotion of numbers to reals is not recursive, which means that composite types containing `#` cannot be auto-promoted to similar complex types containing `&`. For example, the following are not valid Rax expressions:

```    [&,&]: tuple := [1.0,2];
// Error: Type mismatch assigning '[&, #]' to '[&, &]'

{&}: set := {1..10};
// Error: Type mismatch assigning '{#}' to '{&}'
```

For all other type conversions, explicit type casting needs to be used. The type-cast operator in Rax is `()`, like in C. For example, to explicitly cast a number to real:

```    &: real := (&)5;
```

Not all types can be cast to all other types. The following table describes the possible type conversions.

Table 10.1. Type conversions in Rax

type totype fromconversion
`?``?`Implicit conversion.
`#`Explicit conversion. Returns `false` for numbers equal to 0, `true` otherwise. For example: `(?)3 == true`.
`&`Explicit conversion. Returns `false` for numbers equal to 0, `true` otherwise. For example: `(?)1.54 == true`.
`\$`Explicit conversion. Returns `false` for empty string, `true`, otherwise. For example, a nice test for an empty string: ````print (?)s ? "string not empty" : "string is empty";```.
`@`No conversion.
`^`No conversion.
`~`No conversion.
`|`No conversion.
`[]`No conversion.
`{}`No conversion.
`#`?Explicit conversion. For example: `(#)true == 1`, `(#)false == 0`.
`#`Implicit conversion.
`&`Explicit conversion. Casting a real to number rounds the real to the nearest integral. For example: ```(#)1.8 == 2```.
`\$` Explicit conversion. The string must represent an integer number, otherwise an error will be thrown. For example: `(#)"1234" == 1234`.
`@`No conversion.
`^`No conversion.
`~`No conversion.
`|`No conversion.
`[]`No conversion.
`{}`No conversion.
`&`? Explicit conversion. For example: `(&)true == 1.0`, `(&)false == 0.0`.
`#`Implicit - auto-promotion
`&`Implicit conversion.
`\$`No conversion.
`@`No conversion.
`^`No conversion.
`~`No conversion.
`|`No conversion.
`[]`No conversion.
`{}`No conversion.
`\$`? Explicit conversion. For example: `(\$)true == "true"`, `(\$)false == "false"`.
`#` Explicit conversion. Casting a number to string results in a string representing this number. For example: `(\$)42 == "42"`.
`&` Explicit conversion. Casting a real to string results in a string representing this real. This can be either scientific notation or decimal point notation, depending on which one is shorter. For example: `(\$)2.3 == "2.3"` and `(\$)1000000.0 == "1e+06"`.
`\$`Implicit conversion.
`@` Explicit conversion. Casting a time to string results in a string in ISO 8601 format.
`^` Explicit conversion. Casting an absolute to string results in a string in ISO 8601 format.
`~` Explicit conversion. Casting a relative to string results in a string in ISO 8601 format.
`|` Explicit conversion. Casting an interval to string results in a string in ISO 8601 format.
`[]`No conversion.
`{}`No conversion.
`@`?No conversion.
`#`No conversion.
`&`No conversion.
`\$` Explicit conversion. Only literal strings in ISO 8601 format can be cast to time. For example: `(@)"2001-03-12"` or `(@)"2003-12-12T23:01:03.22"`, also `(@)"now"` is allowed to get the current date/time.
`@`Implicit conversion.
`^`No conversion.
`~`No conversion.
`|`No conversion.
`[]`No conversion.
`{}`No conversion.
`^`?No conversion.
`#` Explicit conversion. Casting a number to an absolute results in an absolute duration of the given number of days. For example: `(^)4 == (^)"P4D"`.
`&` Explicit conversion. Casting a real to an absolute results in an absolute duration of the given number of days. For example: `(^)4.5 == (^)"P4DT12H"`.
`\$` Explicit conversion. Only literal strings in ISO 8601 format can be cast to absolute. For example: `(^)"P4DT12H5M3.23S"`.
`@`No conversion.
`^`Implicit conversion.
`~`No conversion.
`|`No conversion.
`[]`No conversion.
`{}`No conversion.
`~`?No conversion.
`#`No conversion.
`&` Explicit conversion. Casting a real to a relative results in a relative duration where the integral part of the real is the number of months and the fractional part times one hundred is the number of days. Note that therefore the maximum number of days is `99`. For example: `(~)2.03 == (~)"P2M3D"`, `(~)2.30 == (~)"P2M4W2D"`, or `(~)2.302 == (~)"P2M4W2DT4H48M"`.
`\$` Explicit conversion. Only literal strings in ISO 8601 format can be cast to relative. For example: `(~)"P4Y2M"` or `(~)"P1MT1M"`.
`@` Explicit conversion. Casting a time to a relative results in a relative duration of the given time from the start of the year. This can be useful when a representation of a birthday like value is needed. For example: `(~)(@)"1966-08-20T12:00" == (~)"P7M2W5DT12H"`, `(~)(@)"2000-02-29" == (~)"P1M4W"`, `(~)(@)"2000-02-28" == (~)"P1M3W6D"`, or `(~)(@)"2001-02-28" == (~)"P1M3W6D"`.
`^` Explicit conversion. Casting an absolute to a relative results in a relative duration of the given absolute duration. The relative duration with have a zero relative part, i.e., zero months. For example: `(~)(^)"P2.4D" == (~)"P2.4D"` or `(~)(^)"P2W2DT12H" == (~)"P2W2DT12H"`.
`~`Implicit conversion.
`|`No conversion.
`[]`No conversion.
`{}`No conversion.
`|`?No conversion.
`#`No conversion.
`&`No conversion.
`\$` Explicit conversion. Only literal strings in ISO 8601 format can be cast to and intervals. For example: `"2007-03-01T13:00:00/2008-05-11T15:30:00"` or `"2007-03-01T13:00:00/P1Y2M10DT2H30M"`.
`@`No conversion.
`^`Implicit conversion.
`~`No conversion.
`|`Implicit conversion.
`[]` Explicit conversion. Only tuples of the following types can be cast to an interval: `[@,@]`, `[@,^]`, `[@,~]`, `[^,@]` and `[~,@]`.
`{}`No conversion.

The are no conversions between different composite types. For example, there is no cast operator that could convert `{[#,@]}` to `{[&,\$]}`. For such conversions, you need to use a `project` operator (see Chapter the section called “Relational operators”) with a base-type conversion:

```    {[&]}: RealStringTab := project [(&).#1, (\$).#2] NumberTimeTab;
```