08 · Shared state
How do I share mutable state between functions?
With a store. Glyph has no mutable global variables — module
bindings are const. Shared state lives in a std/store: a
module-level const holding a value you read with get() and change
with set()/update(). The binding never moves; only the value
inside it does, through a method call — so every write is a literal
.set( or .update( you can grep for.
See it
Declare the store once at module scope. Every function in the module shares it — no
let threaded through main, no capturing closures:
import std/store { create }
import std/array
type Task = {
id: number,
title: string,
}
const tasks = create<Array<Task>>([])
const next_id = create(0)
fn add(title: string) -> Task {
next_id.update(fn(n: number) -> number {
return n + 1
})
let task = { id: next_id.get(), title: title }
tasks.update(fn(cur: Array<Task>) -> Array<Task> {
return array.push(cur, task)
})
return task
}
fn all() -> Array<Task> {
return tasks.get()
}
$ grep -rn 'tasks\.\(set\|update\)' src/ src/tasks.glyph:16: tasks.update(fn(cur... # every place the task list can change, # enumerated. nothing hides in an # ordinary `x = ...` assignment # somewhere else in the file.
Why a store, and not a mutable global
This is a deliberate design choice. Glyph keeps mut restricted to local
assignments and module bindings const, because a scattered set of writable
globals is exactly what makes state hard to reason about and hard to find. A
store needs neither rule loosened: the const s binding is immutable, and the
value inside changes only through set/update. So shared state
arrives as a library, not new syntax — no linear types, no weakened
mutation rules — and the mutation lives in exactly one audited place instead of
spread across your program.
One sharp edge, shared with TypeScript: an empty collection can't infer its element type,
so seed it with an explicit type argument — create<Array<Task>>([]).
A scalar store (create(0)) infers fine.
Where it stands
Shipping today
std/store with create, get, set, and update — the single, greppable home for shared mutable state.
On the way
Convenience over the same primitive (derived/computed stores, subscriptions) — layered on top without changing the language.