Types, casting, etc
Types and related verbs
Each expression in O has its type. Type in O defines vаlue domain/set of supported vаlues and is heavily to define the polymorphic behaviour of verbs. Internally it's coded using special undocumented integer vаlue:
o)@1
320
o)
Monadic verb @
rеturns the numeric representation of internal type id. Interpreter uses its exact vаlue internally.
The only valid operation on numeric type representation is checking for equality.
o)(@2)=@1
1b
o)
Now, what's a better practice of type referencing if not using internal ids? That's what !
monadic verb is for.
o)!`s`int
256
o)!`s`long
320
o)
That way you are referencing type id of scalar int. A single argument for !
is called type spec. First symbol in type spec defines structure (scalar, vector, etc), second symbol defines scalar type name. For other scalar type names, see Scalars
Encoding structure in type spec is as follows:
Structure | Typespec | Example |
---|---|---|
Scalar | `s | `s`bool |
Vector | `v | `v`int |
Using the .o.typedesc you can find the type that corresponds to an integer type id:
o).o.typedesc 320
`s`long
o).o.typedesc[@1 2 3i]
`v`int
o)
Another useful monadic verb for getting type spec is type. It rеturns type spec for a given vаlue:
o)type 10#0
`v`long
o)type 0
`s`long
o)
This example just assigns constant integer vаlue at runtime:
o)a:!`v`int
45312
o)
Casting
Type casting in O is done using $ dyadic. Its left argument defines "destination" type, right argument is the "source".
Giving a single symbol as type spec means - leave right argument structure intact and just change its element type.
o)`int$10 20 30
10 20 30i
o)`symbol$10 20 30
`10`20`30
o)`float$10 20 30
10 20 30f
o)
For element type names, see Scalars.
A better practice to define full type is using the !
verb:
o)(!`s`int)$10
10i
o)(!`v`int)$10 20 30
10 20 30i
o)(!`s`float)$0
0f
o)
Here is an idiomatic way to ensure that two vectors have the same type:
o)a:1 2 3; b:10 20 30i; (@b)$a
1 2 3i
o)
And yes, an internal type id can be given as left argument but it's better to use it only in REPL.
o)a:1 2 3; b:10 20 30i; (@b)$a
1 2 3i
o)
Beware of collapsing lists in cases like:
o)`int$(1;2.0;3)
1 2 3i
o)
Casting and over/underflows
When casting, you can encounter vаlues that are too large or too small to be held by type. Infinities are used to signal that:
o)`int$1000000000000 -1000000000000
0W -0Wi
o)
Nulls/NaN are retained between types.
o)`int$1.0 0n 0w
1 0N 0Wi
o)