Types & Values
Achronyme's type system and value representations.
Achronyme is dynamically typed. All values are represented as tagged 64-bit words with a 4-bit tag and 60-bit payload.
Types
| Type | Examples | Description |
|---|---|---|
| Int | 42, -7 | 60-bit signed integer (-2^59 to 2^59-1) |
| Bool | true, false | Boolean values |
| String | "hello" | UTF-8 strings (heap-allocated) |
| List | [1, 2, 3] | Ordered collections |
| Map | {"a": 1, "b": 2} | Key-value maps |
| Field | 0p42, 0pxFF, 0pb1010 | BN254 scalar field element |
| BigInt256 | 0i256xFF, 0i256d42 | 256-bit unsigned integer (VM only) |
| BigInt512 | 0i512xFF, 0i512d42 | 512-bit unsigned integer (VM only) |
| Function | fn(x) { x + 1 } | First-class functions and closures |
| Proof | result of prove { } | Groth16 or PlonK proof object |
| Nil | nil | Absence of value |
Integers
Integers are 60-bit signed values stored inline (no heap allocation). Range: -576460752303423488 to 576460752303423487.
let x = 42
let y = -7
let big = 100000000000
If an arithmetic operation overflows the i60 range, a runtime error is raised. Use 0p field literals when you need modular field arithmetic (e.g., 0p42).
Booleans
let yes = true
let no = false
In circuits, true maps to field element 1 and false maps to 0.
Strings
let greeting = "hello, world"
let empty = ""
Lists
let nums = [1, 2, 3]
let mixed = [1, "two", true]
let nested = [[1, 2], [3, 4]]
Maps
let person = {"name": "Alice", "age": 30}
Field Elements
BN254 scalar field elements for cryptographic operations. Montgomery form internally. Created using the 0p prefix, which works like 0x for hex:
let a = 0p42 // decimal field literal
let b = 0pxFF // hex field literal
let c = 0pb1010 // binary field literal
let d = 0p21888242871839275222246405745257275088548364400416034343698204186575808495617 // large decimal
let sum = a + b
let prod = a * b
let inv = 0p1 / a // modular inverse
Int and Field cannot be mixed in arithmetic. 0p3 + 5 is a runtime error — use 0p3 + 0p5 instead.
Field elements are essential for circuit programming — all circuit values are field elements under the hood.
BigInt (VM only)
Fixed-width unsigned integers for cryptographic operations. Two widths: 256-bit (4 limbs) and 512-bit (8 limbs). Non-modular arithmetic with overflow/underflow errors.
Literals
BigInt literals use the 0i prefix, followed by width and radix:
let a = 0i256xFF // 256-bit hex
let b = 0i256d255 // 256-bit decimal
let c = 0i256b11111111 // 256-bit binary
let d = 0i512x1234 // 512-bit hex
Constructor functions
let a = bigint256(42) // from integer
let b = bigint256("0xFF") // from hex string
let c = bigint512(100) // 512-bit from integer
Arithmetic
Standard operators work between BigInts of the same width:
let x = 0i256d10
let y = 0i256d20
let sum = x + y // 30
let diff = y - x // 10
let prod = x * y // 200
let q = y / x // 2
let r = 0i256d25 % 0i256d7 // 4
let p = 0i256d2 ^ 10 // 1024
Type safety
BigInt cannot be mixed with Int, Field, or a different BigInt width:
// All of these are runtime errors:
// bigint256(1) + 1 -- BigInt + Int
// bigint256(1) + 0p1 -- BigInt + Field
// bigint256(1) + bigint512(1) -- width mismatch
Bitwise operations
bit_and(a, b) // bitwise AND
bit_or(a, b) // bitwise OR
bit_xor(a, b) // bitwise XOR
bit_not(a) // bitwise NOT
bit_shl(a, n) // shift left (errors if bits overflow)
bit_shr(a, n) // shift right
let bits = to_bits(a) // list of 0/1 (LSB-first)
let val = from_bits(bits, 256) // reconstruct from bits
typeof
typeof() returns "BigInt256" or "BigInt512" for BigInt values.
Nil
let nothing = nil
nil represents the absence of a value. Functions without a return statement return nil.
Static Namespaces
Use Type::MEMBER syntax to access type-level constants:
// Integer bounds
print(Int::MAX) // 576460752303423487 (2^59 - 1)
print(Int::MIN) // -576460752303423488 (-2^59)
// Field constants
let zero = Field::ZERO
let one = Field::ONE
let order = Field::ORDER // BN254 Fr modulus as string
// BigInt constructor
let val = BigInt::from_bits(bits, 256)
See Methods & Static Namespaces for the full reference.
Variable Bindings
let x = 42 // immutable binding
mut y = 0 // mutable binding
y = y + 1 // reassignment (only for mut)
let creates an immutable binding. mut creates a mutable binding that can be reassigned.
Type Annotations
Achronyme supports optional type annotations on variable bindings and function signatures. In circuit mode, annotations enable compile-time type checking and constraint optimization. In VM mode, annotations are parsed and accepted but execution remains dynamic.
let x: Field = 0p42
let flag: Bool = true
mut counter: Field = 0p0
See Type Annotations for the full reference in circuit context.