Types and Inference

ScarScript checks types at compile time. A declaration can include a type annotation, or the compiler can infer the type from its initializer.

Primitive types

ScarScript typeMeaning
intSigned integer
dec64-bit floating-point number
strString
booltrue or false
anyValue with a dynamically asserted type
voidNo return value; used for functions

Inference and annotations

val retries = 3 // inferred as int val price = 9.99 // inferred as dec val title = "Guide" // inferred as str val published = false // inferred as bool val count: int = 3 // explicit annotation val rate: dec = 3 // an integer literal can widen to dec

Integer literals may widen to dec in compatible contexts. An existing int variable does not automatically become a dec for assignment:

val whole = 3 val fraction: dec = 3 // allowed: the initializer is an integer literal // val other: dec = whole // not an implicit int-variable conversion

Collection types

Arrays use T[]; maps use map[K: V]:

val ids: int[] = [10, 20, 30] val labels: map[str: int] = {"first": 1, "second": 2}

Provide a type annotation for empty collections:

val emptyIds: int[] = [] val emptyLabels: map[str: int] = {}

Array and map values can be iterated with for:

for id in ids { print(id) } for name, score in labels { print("{name}: {score}") }

Assignment and mutability

val and const bindings cannot be reassigned. Use mut for a binding whose value changes:

mut total: int = 0 total = total + 1

The checker reports incompatible assignments, unknown names, and invalid function arguments as compile-time errors.

Multiple return values

Functions may return more than one value. The return types are written as a tuple, and a call can bind the results to multiple declarations:

func divide(a: int, b: int) (int, bool) { if b == 0 { return 0, false } return a / b, true } val quotient, ok = divide(10, 2)

Tuple types are for function return values; they are not general-purpose tuple variables.