Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Keywords Reference

Every keyword in Compact, organized by purpose. Use this as a lookup when you’re unsure what a keyword does or whether it’s the right tool.

Docs: Compact Keywords


Intuition First

Compact has fewer keywords than TypeScript, no class, function, interface, let, var, null, this, while. What remains is lean and purposeful.

The keywords fall into four groups:

  1. Declaration keywords, define things: circuit, struct, enum, ledger, witness, module, type, new type
  2. Expression keywords, operate on values: as, assert, disclose, default, map, fold, pad, slice
  3. Control keywords, manage flow: if, else, for, return, const
  4. Module keywords, organize code: export, import, include, pragma, prefix, from

A few TypeScript keywords are reserved for future use (await, class, interface, let, null, etc.) and cannot be used as identifiers. Identifiers starting with __compact are reserved for the compiler.


Module and Visibility

KeywordWhat it doesExample
exportMakes a binding visible outside its scope. At top level, marks entry points callable from TypeScript.export circuit f(): T { }
moduleDefines a named namespace. Contains program elements.module M { export circuit f() {} }
importBrings exported bindings from a module into scope. Also imports the built-in stdlib.import M; / import CompactStandardLibrary;
fromUsed in selective import to name the source module.import { f } from M;
prefixAttaches a namespace prefix to all imported names.import Math prefix M$;
includeSplices the contents of another file inline at the current location.include "shared/types.compact";
pragmaDeclares a constraint on compiler or language version.pragma language_version >= 0.22;

Declaration Keywords

Types and Data Structures

KeywordWhat it doesExample
structDeclares a named record type with typed fields. Nominal typing.struct Point { x: Field, y: Field }
enumDeclares a named sum type. First variant is the default.enum State { UNSET, SET }
typeDeclares a structural type alias, fully interchangeable with the underlying type.type Hash = Bytes<32>;
new typeDeclares a nominal type alias, distinct from the underlying type. Requires explicit cast.new type UserId = Bytes<32>;
OpaqueDeclares a foreign JavaScript value opaque to circuits. Currently "string" and "Uint8Array".Opaque<"string">
BooleanThe boolean type. Values: true and false.const flag: Boolean = true;
FieldUnsigned integer up to the ZK field order. Comparisons only via == and !=.const f: Field = 42;
UintUnsigned integer. Sized (Uint<n>) or bounded (Uint<0..n>).Uint<64>, Uint<0..256>
BytesFixed-length byte vector. Requires size argument.Bytes<32>
VectorHomogeneous fixed-length sequence. Shorthand for same-type tuple.Vector<4, Field>

Ledger and Witnesses

KeywordWhat it doesExample
ledgerDeclares a field in the on-chain public state.ledger count: Counter;
export ledgerMakes a ledger field readable from TypeScript.export ledger owner: Bytes<32>;
sealed ledgerMakes a ledger field writeable only during initialization.sealed ledger config: Uint<32>;
witnessDeclares a private-input callback. Body is in TypeScript.witness secretKey(): Bytes<32>;
constructorDefines the initialization function, called once on deployment.constructor(v: Field) { }

Circuits

KeywordWhat it doesExample
circuitDefines a named circuit, compiles to a ZK circuit.circuit add(a, b): Field { }
export circuitMakes a circuit callable from TypeScript (entry point).export circuit mint(): [] { }
pureAsserts a circuit has no side effects, no ledger reads/writes, no witness calls.pure circuit hash(v: T): Bytes<32> { }
contractReserved for declaring external contract types. Not fully implemented in 1.0.

Expression Keywords

Operations on Values

KeywordWhat it doesExample
asType cast. Widens, narrows, or converts between compatible types.x as Field, bytes as UserId
assertRuntime guard. Halts the circuit with an error message if the condition is false.assert(balance >= amount, "Insufficient")
discloseCompile-time annotation. Declares that witness data is intentionally going public.disclose(witness())
defaultProduces the default value of a type.default<Bytes<32>>
padPads a string literal with zero bytes to a fixed length. Produces Bytes<n>.pad(32, "midnight:example")
mapHigher-order transformation over a vector or tuple.map((x) => x + 1, v)
foldHigher-order accumulation over a vector or tuple.fold((acc, x) => acc + x, 0, v)
sliceExtracts a contiguous sub-vector of a given size from a larger vector.slice<4>(v, start)

Literals and Special Forms

KeywordWhat it doesExample
trueBoolean true value.const flag = true;
falseBoolean false value. Default value of Boolean.const flag: Boolean = false;

Control Flow

KeywordWhat it doesExample
ifConditional branching. One-armed (if (cond) { }) or two-armed (if (cond) { } else { }).if (state == SET) { }
elseThe alternative branch of a two-armed if.if (a) { } else { }
forBounded iteration. Over a numeric range or a vector/tuple.for (const i of 0..10) { }
ofUsed in for loop to name the iteration variable.for (const x of vec) { }
returnExits a circuit or constructor and returns a value. Cannot be used inside a for body.return x;
constDeclares an immutable local variable binding.const x = 42;

Reserved for Future Use

These TypeScript/JavaScript keywords are reserved, they cannot be used as identifiers in Compact 1.0 but may have meaning in future versions:

await, break, case, catch, class, continue, debugger, delete, do, extends, finally, function, implements, in, instanceof, interface, let, null, package, private, protected, public, static, super, switch, this, throw, try, typeof, var, void, while, with, yield

Practical impact: If you have a TypeScript background and instinctively reach for let, const, or var, reach for const in Compact. If you reach for interface or class, use struct. If you reach for null, use none<T>() or default<T>().


Compiler-Reserved Prefix

Any identifier beginning with __compact is reserved for the compiler. Using one is a static error:

const __compact_internal = 1;  // error: reserved prefix

Quick Lookup by Task

TaskKeyword
Define a circuitcircuit
Make it callable from DAppexport circuit
Make a circuit side-effect freepure circuit
Declare on-chain stateledger
Make state readable from DAppexport ledger
Make state write-oncesealed ledger
Provide private inputwitness
Initialize on deployconstructor
Define a record typestruct
Define a sum typeenum
Create a distinct typenew type
Group code in a namespacemodule
Bring in another moduleimport
Mark something publicexport
Declare a versionpragma
Guard at runtimeassert
Cast a typeas
Declare disclosuredisclose
Default valuedefault
Transform a vectormap
Accumulate a vectorfold

Common Mistakes

  1. Using type when you need new type. type UserId = Bytes<32> is structural, Bytes<32> and UserId are interchangeable. Use new type UserId = Bytes<32> if you want them to be distinct.

  2. Using let instead of const. Compact has no let. All local variables are declared with const and are immutable after binding.

  3. Using null instead of none<T>(). There’s no null in Compact. Optional values use Maybe<T>: none<T>() or some<T>(v).

  4. Using class instead of struct. Compact has no class. Use struct for record types.

  5. Forgetting pure when you want to document purity. pure is both documentation and a compiler-enforced assertion. If your circuit has no side effects, mark it pure, the compiler will catch if you accidentally add one later.