Skip to main content

Variables & Types

This section covers variable declaration, type inspection, and core built-in types: primitives, arrays, maps, and classes.

Declaring Variables

memory — Temporary Variables

The memory keyword declares temporary variables that are wiped when the function finishes.

endpoint DeclareVar() -> (output U64):
memory n U64 // Initialized to zero
n = 10

memory m = 11 // Type inferred
memory x U64 = 12 // Explicit type

yield output n + m + x
tip

If no value is assigned, variables are initialized to their zero value (0 for integers, false for booleans).

storage — Efficient Pointers

The storage keyword creates a pointer to stored data, enabling efficient operations without transferring large structures to memory.

endpoint dynamic RegisterGuardian(new_guardian Identifier):
storage operator Operator // Declare pointer

observe operators <- GuardianRegistry.Logic.Operators:
operator = operators[Sender]

mutate operators <- GuardianRegistry.Logic.Operators:
append(operator.Guardians, new_guardian)
operators[Sender] = operator

Block Syntax (Syntax Grouping)

Both memory and storage declarations support block syntax to group multiple declarations:

memory:
count = 0
name = "Alice"
limit = 10

storage:
operator Operator
balance U64

const — Constants

Constants are defined at the module level with an explicit type and value:

const MAX_SUPPLY U64 = 1000000
const TOKEN_NAME String = "MyCoin"

typeof() — Type Inspection

Get a string description of any variable's type:

memory x = 42
memory t = typeof(x) // Returns "U64"

Primitive Types

TypeDescription
BoolBoolean (true/false)
BytesByte sequence
StringText string
Identifier32-byte identifier
U64Unsigned 64-bit integer
I64Signed 64-bit integer
U256Unsigned 256-bit integer

Type Conversion

Use typecast operators like U256(5) to convert between types:

From ↓ / To →BoolBytesStringIdentifierU64I64U256
Bool__str__.ToU64().ToI64().ToU256()
Bytes__bool____str____id__.ToU64().ToI64().ToU256()
String__bool__.ToBytes()__id__.ToU64().ToI64().ToU256()
Identifier__bool__.ToBytes()__str__.ToU256()
U64__bool__.ToBytes()__str__.ToI64().ToU256()
I64__bool__.ToBytes()__str__.ToU64().ToU256()
U256__bool__.ToBytes()__str____id__.ToU64().ToI64()

Arrays

Fixed-Length Arrays

Size determined at compile time. Cannot be changed later.

// Literal initialization
memory arr = [3]U64{1, 2, 3}

// Zero-value initialization
memory arr2 = make([3]U64) // [0, 0, 0]
arr2[2] = 4 // [0, 0, 4]

Fixed Array Methods

Method / FunctionReturnsDescription
len(arr)U64Returns the length of the array
arr[index]TypeAccess element at index (0-based)

Variable-Length Arrays (Varrays)

Dynamic arrays that can grow or shrink.

memory vrr []U64              // Empty varray
append(vrr, 1) // [1]
append(vrr, 2) // [1, 2]

memory last = popend(vrr) // Removes and returns 2

memory vrr2 = make([]U64, 2) // [0, 0]
memory joined = merge(vrr, vrr2)

Varray Methods

Method / FunctionReturnsDescription
len(vrr)U64Returns current length
vrr[index]TypeAccess element at index (0-based)
append(vrr, item)Add element to the end
popend(vrr)TypeRemove and return the last element
merge(vrr1, vrr2)[]TypeCombine two varrays into a new varray
make([]Type, size)[]TypeCreate varray with size zero-value elements
memory items []String
append(items, "first")
append(items, "second")

memory count = len(items) // 2
memory last = popend(items) // "second"
memory first = items[0] // "first"

Array vs Varray Comparison

FeatureArray [N]TypeVarray []Type
SizeFixed at compile timeDynamic
Syntax[3]U64[]U64
append✗ Not supported✓ Supported
popend✗ Not supported✓ Supported
merge✗ Not supported✓ Supported
Use caseKnown data (coordinates)Lists, queues, stacks

Maps

Key-value pairs where keys must be unique primitives.

// Initialize empty map
memory mp = make(Map[String]U64)
mp["key"] = 42

// Initialize with literals
memory mp2 = Map[String]U64{"No": 0, "Yes": 1}

// Operations
memory count = len(mp2) // 2
memory merged = merge(mp, mp2) // Combine maps
remove(merged, "No") // Delete key

Map Methods

Method / FunctionReturnsDescription
len(map)U64Returns the number of key-value pairs
map[key]ValueAccess value by key
map[key] = valueSet or update a key-value pair
map[key]?BoolCheck if key exists (membership test)
remove(map, key)Delete a key-value pair
merge(map1, map2)Map[K]VCombine two maps (second overwrites duplicates)
make(Map[K]V)Map[K]VCreate an empty map

Membership Check with ?

Use the ? operator to check if a key exists without accessing the value:

memory m = Map[String]U64{"hi": 42}
memory exists = m["hi"]? // true
memory missing = m["lo"]? // false

// Common pattern: check before access
if m["key"]?:
memory val = m["key"]

generate Keyword

Auto-initialize missing keys with their zero value, avoiding manual existence checks:

// Without generate (requires check)
if !counter[userId]?:
counter[userId] = 0
counter[userId]++

// With generate (single line)
generate counter[userId]++
tip

Use generate when you want to safely increment or modify a map value that may not exist yet. It automatically initializes missing keys to their zero value (0 for integers, "" for strings, etc.).


Classes

Group fields and methods into reusable structures.

class Person:
field name String
field age U64

method GetInfo() -> (info String):
info = f"{self.name} is {self.age}"

method mutate Birthday():
self.age += 1

Usage

memory person = Person{name: "Sam", age: 20}
person.Birthday()
memory info = person.GetInfo()
memory fields = len(person) // Number of fields

Built-in Class Operations

Method / FunctionReturnsDescription
len(instance)U64Returns the number of fields in the class
instance.fieldTypeAccess a field by name
instance.method()variesCall a method on the instance
note
  • Use mutate keyword for methods that modify self
  • Maximum 240 custom methods per class

Special Methods (Dunder Methods)

Override these methods to customize how your class behaves with operators and type conversions:

MethodPurposeTriggered BySignature
__eq__Equality comparisona == b(other T) -> (is_equal Bool)
__lt__Less than comparisona < b(other T) -> (is_less Bool)
__gt__Greater than comparisona > b(other T) -> (is_greater Bool)
__bool__Boolean conversionBool(instance)() -> (result Bool)
__str__String conversionString(instance)() -> (result String)
__len__Custom lengthlen(instance)() -> (result U64)
__id__Identifier conversionIdentifier(instance)() -> (result Identifier)
__join__Merge two instancesjoin(a, b)(other T) -> (joined T)
__event__Convert to eventemit() -> (ev EventType)
__except__Custom errorthrow() -> (err String)
class Person:
field name String
field age U64

method __eq__(other Person) -> (is_equal Bool):
is_equal = self.name == other.name && self.age == other.age
memory p1 = Person{name: "Sam", age: 20}
memory p2 = Person{name: "Sam", age: 20}
memory same = p1 == p2 // true (uses __eq__)

Example: String Conversion

class Token:
field symbol String
field amount U64

method __str__() -> (result String):
result = f"{self.amount} {self.symbol}"
memory t = Token{symbol: "MOI", amount: 100}
memory s = String(t) // "100 MOI"

Example: Boolean Conversion

class Balance:
field value U64

method __bool__() -> (result Bool):
result = self.value > 0
memory b = Balance{value: 0}
if !Bool(b):
// balance is empty