ReferenceControlArcReferenceTypes

Types

Arc type system reference for primitives, channels, series, units, and type casting

Primitive types

Integer types

Table

Type Size Range
i8 8-bit signed -128 to 127
i16 16-bit signed -32,768 to 32,767
i32 32-bit signed -2,147,483,648 to 2,147,483,647
i64 64-bit signed -9.2×1018 to 9.2×1018
u8 8-bit unsigned 0 to 255
u16 16-bit unsigned 0 to 65,535
u32 32-bit unsigned 0 to 4,294,967,295
u64 64-bit unsigned 0 to 1.8×1019

Floating point types

Table

Type Size Precision
f32 32-bit ~7 decimal digits
f64 64-bit ~15 decimal digits

String type

Table

Type Description
str Immutable UTF-8 string

Boolean type

Table

Type Description
bool true or false, stored as one byte

Type defaults

When you write a literal without an explicit type, Arc infers a default:

Table

Literal Default type
42 i64
3.14 f64
"text" str
true bool
[1, 2, 3] series i64
[1.0, 2.0] series f64

Channel types

Channels connect Arc to Synnax telemetry data. Declare channel types with chan:

chan f64  // channel of float64
chan i32  // channel of int32
chan bool // channel of boolean

Channel names reference channels that exist in your Synnax cluster. Binding one to a name declares a channel read/write variable that reads and writes the channel:

sequence {
    value := source_ch  // binds to source_ch
    value -> sink_ch    // writes to sink_ch
}

Reading from a channel that has no data returns the zero value for that type.

Series types

Series are homogeneous arrays. Declare series types with series:

series f64  // array of float64
series i32  // array of int32
series bool // array of booleans

Series literals

data := [1.0, 2.0, 3.0] // series f64
empty series f64 := [] // empty series (type required)

Series operations

length := len(data) // i64: number of elements
first := data[0] // indexing (0-based)
subset := data[1:3] // slicing [start:end)

Element-wise operations

Arithmetic and comparison operators work element-wise on series:

data := [1.0, 2.0, 3.0]

// Scalar operations
scaled := data * 2.0 // [2.0, 4.0, 6.0]
offset := data + 10.0 // [11.0, 12.0, 13.0]

// Series-to-series (must be equal length)
sum := data + [4.0, 5.0, 6.0] // [5.0, 7.0, 9.0]

// Comparisons return series bool
mask := data > 2.0 // [false, false, true]

// Logical operators apply element-wise to series bool
inverted := not mask // [true, true, false]

Out-of-bounds access causes a runtime error. Series-to-series operations require equal-length arrays.

Unit annotations

Types can carry a single unit suffix for dimensional tracking. The suffix is one identifier drawn from the built-in registry (length, time, mass, pressure, frequency, voltage, current, temperature, angle, data, count):

distance f64 m := 50.0
duration i64 ns := 1000000000
pressure f64 psi := 14.7

Only single-identifier units are accepted in source syntax. Compound units like m/s or m^2 are not spelled directly in declarations. They arise implicitly from arithmetic (see below).

Dimensional compatibility

The compiler enforces dimensional compatibility:

  • Addition/Subtraction: Operands must have compatible dimensions
  • Multiplication/Division: Always valid; the result’s dimensions combine
  • Exponentiation: A dimensioned base requires a literal integer exponent
distance f64 m := 10.0
elapsed f64 s := 2.0

// Division produces a length/time quantity (a velocity)
speed := distance / elapsed

// Exponentiation produces a squared-length quantity (an area)
area := distance ^ 2

The dimensions of speed and area are tracked by the compiler and checked against any further use, but they are not spelled in source code.

Type casting

Explicit casting converts between types.

x i32 := 42
y f64 := f64(x) // int to float

a f64 := 3.7
b i64 := i64(a) // truncates to 3

n i64 := 42
s str := str(n) // numeric to string: "42"

active := n > 0
level u8 := u8(active) // bool to int: 1
state str := str(active) // bool to string: "true"

Boolean conversions (bool(x)) are not supported. Use a comparison (x != 0) to derive a bool. Casting a string to a numeric or boolean is not supported either.

Casting rules

Table

Conversion Behavior
Widening (e.g., i16 to i64) Safe, sign/zero extend
Narrowing (e.g., i64 to i8) Truncates
Signed to unsigned Saturates at bounds
Float to integer Truncates toward zero, saturates on overflow
Integer overflow Two’s-complement wrapping
Numeric to string (e.g., str(42)) Decimal text (e.g., "42", "3.14")
bool to numeric (e.g., u8(b)) 1 or 0
bool to string (str(b)) "true" or "false"

Float values render without trailing zeros (str(1.0) returns "1"), and special values render as "NaN", "+Inf", "-Inf". Casting from str back to a numeric or bool type is not supported.

Arc requires explicit casts for mixed-type arithmetic. No implicit type promotion.

// Wrong: type error
x i32 := 42
y f64 := x + 1.0

// Right: explicit cast
x i32 := 42
y f64 := f64(x) + 1.0

Zero values

All types have default zero values:

Table

Type Zero value
integers 0
floats 0.0
bool false
str "" (empty string)
series [] (empty series)
channels zero value of element type (on first read)

String operations

Strings support the following operations:

msg := "Hello"
greet := msg + " World"  // concatenation
first := msg[0]          // indexing (returns u8)
sub := msg[1:4]          // slicing
length := len(msg)       // length in bytes
equal := msg == "Hello"  // equality (returns bool)

Table

Operation Supported
+ (concatenation) Yes
==, != (equality) Yes
[] (indexing) Yes
[:] (slicing) Yes
len() Yes
<, >, <=, >= No

To build strings from runtime values, use format strings with {expr} placeholders instead of repeated concatenation.