Pointers

Astra pointers let you hold a reference to a variable and read or update its value indirectly — even from inside a function. Two built-in functions handle everything: adr() and val().

FunctionUsageWhat it does
adr(x)p = adr(x)Returns a pointer (address) to variable x
val(p)val(p)Reads the current value at the address p points to
adr(p, v)adr(p, 42)Writes value v to the address p points to

adr() — Get an Address

Call adr(variable) with one argument to get a pointer to that variable. Store it in another variable to use later.

pointer-basic.astra
counter = 5 pc = adr(counter) \\ pc now points to counter
variable
counter
5
pointer
pc
adr(counter)

val() — Read a Value

Call val(pointer) to read the current value of the variable the pointer refers to.

val.astra
counter = 5 pc = adr(counter) write val(pc) \\ 5 counter = 99 write val(pc) \\ 99 ← reflects the updated value
💡 val(p) always reads the current value — if the original variable changes, val(p) reflects that immediately.

adr() — Write a Value

Call adr(pointer, newValue) with two arguments to update the variable the pointer points to. This changes the original variable directly.

write-ptr.astra
counter = 5 pc = adr(counter) write counter \\ 5 adr(pc, 42) write counter \\ 42 ← original variable updated! write val(pc) \\ 42
⚠️ adr(p, value) modifies the original variable in-place — not a copy. Changes are visible everywhere that variable is used.

Pointers in Functions

By default, Astra passes values to functions by copy. To let a function modify the caller's variable, pass a pointer and use adr() / val() inside.

Without pointer — copy only

#f addTen(n) n = n + 10 write n \\ 15 #ef x = 5 addTen(x) write x \\ 5 ← unchanged

With pointer — updates original

#f addTen(p) adr(p, val(p) + 10) #ef x = 5 px = adr(x) addTen(px) write x \\ 15 ← updated!

Recursive example — decrement counter

decrement.astra
#f decrementAndPrint(p, n) if (n > 0) adr(p, val(p) - 1) write "counter:" write val(p) decrementAndPrint(p, n - 1) ; #ef counter = 5 pc = adr(counter) write "Start:" write counter \\ 5 decrementAndPrint(pc, 5) write "End:" write counter \\ 0

Output:

Start: 5 counter: 4 counter: 3 counter: 2 counter: 1 counter: 0 End: 0

Common Patterns

Swap two variables

swap.astra
#f swap(pa, pb) temp = val(pa) adr(pa, val(pb)) adr(pb, temp) #ef a = 10 b = 20 pa = adr(a) pb = adr(b) swap(pa, pb) write a \\ 20 write b \\ 10

Accumulate into a variable

accumulate.astra
#f addTo(p, amount) adr(p, val(p) + amount) #ef total = 0 pt = adr(total) addTo(pt, 10) addTo(pt, 25) addTo(pt, 5) write total \\ 40

Conditional update

#f setIfGreater(p, newVal) if newVal > val(p) adr(p, newVal) ; #ef max = 0 pm = adr(max) setIfGreater(pm, 15) setIfGreater(pm, 8) setIfGreater(pm, 22) setIfGreater(pm, 10) write max \\ 22
ℹ️ Pointers in Astra are safe — they always refer to a named variable in the current program. There is no raw memory access or pointer arithmetic.