🔍

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.

Avoid relying on internal type ids' exact vаlues in your programs. They may change in any later version.

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)

The ! verb has one nice property - it might be evaluated at parse time if its argument is constant.

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)