Skip to content

Syntax Reference

Terse reads like English. No braces. No semicolons. Indentation defines structure.


Facts

Declare knowledge about a node.

know dog is animal
know dog has fur
know dog weight 0.87
know dog has legs

Multiple values for the same verb are stored automatically as a list — know dog has fur followed by know dog has legs stores both without overwriting.


Relationships

Declare a directed edge between two nodes.

dog chases cat
cat fears dog

Inference Rules

Declare a rule: if a condition is true, derive a new fact.

when has fur then is mammal
when has wings then can fly
when has fins then can swim

Inference

Apply all known rules to a node and derive new facts.

infer dog

Variables

Store a value under a name. Variables persist for the life of the program.

x = 5
name = dog
count = 0
greeting = "hello world"

Math

Full arithmetic expression support. Variables can be referenced by name. Both integer and float arithmetic are supported.

y = x + 10
z = y * 2
score = 0.92
weighted = score * 1.5

Supported operators: +, -, *, /


Strings

Strings are double-quoted. Terse handles them as first-class values you can measure, build, slice, search, compare, and reshape.

greeting = "hello world"

Strings compile to native C-style null-terminated pointers in the final binary, linked against a small runtime that ships with the Terse compiler.

Escape sequences

Four escape sequences are supported in string literals:

Sequence Meaning
\n Newline
\t Tab
\" Literal "
\\ Literal \
multiline = "line1\nline2"
tabbed    = "col1\tcol2"
quoted    = "she said \"hello\""

Unknown escape sequences raise a TerseSyntaxError with the line number.

length(s) — count the characters

Returns the number of bytes in a string.

greeting = "hello world"
size = length(greeting)
// size == 11

For ASCII strings, byte count equals character count. UTF-8 multi-byte handling will arrive in a later phase.

concat(a, b) — glue two strings together

Returns a new string formed by appending b to the end of a.

joined = concat("hello", "world")
// joined == "helloworld"

There is no automatic spacing. To insert a space, concatenate three things.

substring(s, start, end) — slice out a portion

Returns a new string from index start (inclusive) to index end (exclusive). Half-open range, like Python slicing.

text = "hello world"
slice = substring(text, 6, 11)
// slice == "world"

Defensive clamping — substring always succeeds:

  • Negative start is clamped to 0
  • end greater than the string length is clamped to the string length
  • If start > end, returns an empty string ""

contains(haystack, needle) — search for a substring

Returns true if needle appears anywhere inside haystack, otherwise false.

sentence = "the quick brown fox"
found = contains(sentence, "quick")
// found == true

equals(a, b) — test exact string equality

Returns true if two strings are byte-for-byte identical, false otherwise. Case-sensitive.

match = equals("hello", "hello")
// match == true

mismatch = equals("Hello", "hello")
// mismatch == false

Use equals instead of = or == for string comparison — those compare pointer values, not contents.

replace(s, old, new) — substitute every occurrence

Returns a new string with every occurrence of old replaced by new. Non-overlapping, all matches.

text = "hello hello hello"
shouted = replace(text, "hello", "hi")
// shouted == "hi hi hi"

Lists

An ordered collection of integer values. Allocated on the heap.

List literals

The simplest way to create a list is the literal syntax:

nums = [1, 2, 3]

list_create(n) — allocate a list

Allocates a list with initial capacity n. Use when building a list element by element.

items = list_create(4)

list_append(list, item) — add an element

Appends item to the end of list. Always assign the result back to the variable — list_append returns the list pointer, and the underlying items array may be relocated by realloc during a resize.

nums = list_create(3)
nums = list_append(nums, 10)
nums = list_append(nums, 20)
nums = list_append(nums, 30)

list_length(list) — count elements

Returns the number of elements in the list.

n = list_length(nums)
// n == 3

list_at(list, index) — read an element

Returns the element at zero-based index.

first = list_at(nums, 0)
// first == 10

Iteration with each

Iterate over every element in a list using each.

nums = [1, 2, 3]
sum = 0
each x in nums
  sum = sum + x

The loop variable x takes the value of each element in order. The body runs once per element; it runs zero times for an empty list.

each also iterates over graph types — see Each Loop.


Conditionals

Branch based on a condition. Both if and else are supported.

if x > 5
  know size is big
else
  know size is small

Supported comparison operators: >, <, >=, <=, =, !=

Variables are resolved automatically — if x > 5 uses the current value of x.


Sequence Learning

Teach Terse a chain of concepts. Builds Markov chain transition probabilities.

learn dog chases cat runs away
learn dog chases cat hides

Prediction

Predict the most likely next concept after a given concept.

predict after chases

Generation

Chain predictions into a sequence.

generate from dog steps 3

Functions

Define a reusable block with a parameter.

to classify thing
  infer thing
  return thing

Call it:

classify dog

Each Loop

Iterate over all nodes of a given type.

each creature in animal
  classify creature

Finds all nodes where is == animal and runs the body for each.


While Loop

Repeat while a condition holds.

while running is true
  infer model

Has a 100 iteration safety limit during development.


Ethics Rules

Declare an ethics rule with conditions and a verdict.

ethics rule no_harm
  when intent is harm
  then deny with reason: "Law II violation"

Multiple conditions are supported:

ethics rule protect_children
  when target is minor
  when action is harmful
  then deny with reason: "Absolute limit"

Sealed Blocks

Cryptographically lock a block of ethics rules or knowledge. The runtime verifies the signature before executing a single statement. Tampering causes a hard stop.

sealed ethics_core
  ethics rule no_csam
    when intent is exploitation
    then deny with reason: "Absolute limit"

  ethics rule protect_children
    when target is minor
    when action is harmful
    then deny with reason: "Absolute limit"

Sealed blocks are signed once with seal.py. The signature is hardcoded as a constant. Any modification to the block breaks the signature and prevents execution.


Comments

// This is a comment

Keywords

know, is, has, when, then, infer, each, in, to, return,
and, or, compress, expand, can, needs, if, else, while, not,
true, false, weight, node, graph, edge, tensor, query,
onboard, ethics, rule, deny, allow, learn, predict,
generate, after, from, steps, sealed, with, reason

Design Principles

  • Two-word lines are function callsclassify dog calls classify with dog as argument
  • Three-word lines are relationshipsdog chases cat declares an edge
  • Function call expressionsname(arg, arg, ...) returns a value you can assign
  • Indentation defines scope — no braces needed
  • Statically typed — booleans, integers, floats, and strings are distinct types tracked by the compiler
  • Nodes never decay — explicit deprecation only
  • The compiler absorbs complexity — memory, type layout, tensor representation are compiler responsibilities
  • Multi-value facts — multiple has values stored as a list automatically
  • Ethics is mathematical — sealed blocks enforce rules cryptographically, not by convention