Skip to content

Syntax Overview

ExtensionOutputDescription
.purus.jsStandard JavaScript
.cpurus.cjsCommonJS module
.mpurus.mjsES Module
-- This is a line comment
--- This is a
block comment ---

Strings use triple slashes ///:

const greeting be ///Hello, World///
EscapeResult
\nNewline
\tTab
\\Backslash
\//
\[[ (literal bracket)
\]] (literal bracket)

Use [expr] inside a string to embed expressions:

const name be ///Alice///
const age be 30
const msg be ///Hello, [name]! You are [age] years old.///

Compiles to:

const name = "Alice";
const age = 30;
const msg = `Hello, ${name}! You are ${age} years old.`;

You can use any expression inside the brackets:

const x be 10
const result be ///[x] times 2 is [x mul 2]///

Compiles to:

const x = 10;
const result = `${x} times 2 is ${x * 2}`;

To include a literal [ or ] in a string, use the escape sequences \[ and \].

const i be 42
const f be 3.14
const a be true
const b be false
const c be null
const d be nil -- alias for null
const e be undefined

Purus has two separators with distinct roles:

SeparatorUsageJS Output
;Function arguments, function parameters, destructuring,
,Array elements, object properties,

Both compile to , in JavaScript, but they serve different purposes in Purus:

Use ; to separate function arguments when calling functions and parameters in function declarations:

-- Function parameters
fn add a; b
return a add b
-- Function arguments
add[1; 2]
console.log[///hello///; ///world///]
Math.max[1; 2; 3]
-- Destructuring
const [a; b; c] be arr
const object[name; age] be person

Use , to separate array elements and object properties:

-- Arrays
const arr be [1, 2, 3]
-- Objects
const obj be [name be ///Alice///, age be 30]

Since Purus uses [] for both function calls and arrays, the two separators help distinguish between them:

-- `;` makes this a function call with 3 arguments
fn[a; b; c] -- fn(a, b, c)
-- `,` makes this an array with 3 elements
[a, b, c] -- [a, b, c]
-- Nested calls use `;` to separate arguments
outer[inner[x]; y] -- outer(inner(x), y)
const arr be [1, 2, 3]
const arr2 be [1; 2; 3] -- semicolons also work
const empty be []
const inclusive be [0..5] -- [0, 1, 2, 3, 4, 5]
const exclusive be [0...5] -- [0, 1, 2, 3, 4]

Extract a portion of an array using \ prefix with .. (inclusive) or ... (exclusive):

const numbers be [0, 1, 2, 3, 4, 5, 6]
const middle be numbers[\2..5] -- [2, 3, 4, 5]
const partial be numbers[\2...5] -- [2, 3, 4]

Compiles to:

const middle = numbers.slice(2, 5 + 1);
const partial = numbers.slice(2, 5);

Replace a portion of an array by assigning to a slice:

numbers[\2..4] be [///a///; ///b///; ///c///]
-- numbers is now [0, 1, "a", "b", "c", 5, 6]

Compiles to:

numbers.splice(2, 4 - 2 + 1, "a", "b", "c");

Extract values from arrays into variables:

const weather be [///Sunny///; ///Rainy///]
const [today; tomorrow] be weather
-- Swap variables
[today; tomorrow] be [tomorrow; today]

Compiles to:

const [today, tomorrow] = weather;
[today, tomorrow] = [tomorrow, today];
const obj be [name be ///Alice///, age be 30]
const empty-obj be [be] -- empty object

Use object[...] to destructure properties from an object:

const person be [name be ///Alice///, age be 30]
const object[name; age] be person

Compiles to:

const person = { name: "Alice", age: 30 };
const { name, age } = person;

Purus uses [] for everything — function calls, arrays, objects, and grouping. No () or {}.

Use \ inside brackets to access array indices or object properties by expression:

const val be arr[\0] -- arr[0]
const item be obj[\key] -- obj[key]
const x be matrix[\i][\j] -- matrix[i][j]

This \ prefix distinguishes computed access from function calls:

SyntaxMeaningJS Output
f[x]Function callf(x)
arr[\x]Computed accessarr[x]
arr[\2..4]Slicearr.slice(2,5)

Use \. for optional chaining (JS ?.):

const name be user\.name -- user?.name
const val be obj\.method[1; 2] -- obj?.method(1, 2)

Brackets [...] can span multiple lines. Newlines and indentation between items are ignored:

const items be [
1;
2;
3
]
const config be [
host be ///localhost///,
port be 8080
]
fetch[url].then[
fn response
return response.json[]
].catch[
fn err
console.error[err]
]

Blocks are defined by indentation (2 spaces recommended):

if x gt 0
console.log[///positive///]
else
console.log[///non-positive///]

Identifiers can contain hyphens (-) and underscores (_), which are both converted to underscores in JavaScript output:

const my-variable be 42
-- compiles to: const my_variable = 42;
const my_variable2 be 43
-- compiles to: const my_variable2 = 43;

Hyphens and underscores are interchangeable — my-var and my_var refer to the same JavaScript variable (my_var). If you need to work with JS libraries that use underscores, you can use either form in Purus.

Purus replaces many JavaScript symbols with words. Here is a quick reference for common JavaScript patterns and their Purus equivalents:

JavaScript uses backticks and ${} for template literals. Purus uses /// strings with []:

-- JavaScript: `Hello, ${name}! You are ${age} years old.`
const msg be ///Hello, [name]! You are [age] years old.///
-- JavaScript: `${a} + ${b} = ${a + b}`
const result be ///[a] + [b] = [a add b]///
const msg = `Hello, ${name}! You are ${age} years old.`;
const result = `${a} + ${b} = ${a + b}`;

JavaScript’s ?? operator becomes coal in Purus:

-- JavaScript: const port = config.port ?? 3000;
const port be config.port coal 3000
-- JavaScript: const name = user?.name ?? "Anonymous";
const name be user\.name coal ///Anonymous///
const port = config.port ?? 3000;
const name = user?.name ?? "Anonymous";

JavaScript’s ternary condition ? a : b becomes if condition then a else b:

-- JavaScript: const label = count > 0 ? "items" : "empty";
const label be if count gt 0 then ///items/// else ///empty///
const label = count > 0 ? "items" : "empty";

JavaScript’s ?. becomes \. in Purus:

-- JavaScript: user?.address?.city
user\.address\.city
-- JavaScript: arr?.[0]
arr\.[\0]
user?.address?.city;
arr?.[0];

JavaScript’s === becomes eq (or is), and !== becomes neq (or not eq):

-- JavaScript: if (x === 0) {}
if x eq 0
-- ...
-- JavaScript: if (x !== null) {}
if x neq null
-- ...
if (x === 0) {}
if (x !== null) {}

JavaScript’s => arrow functions become fnto (expression body) or fn with indented block:

-- JavaScript: const double = (x) => x * 2;
const double be fn x to x mul 2
-- JavaScript: const greet = (name) => { console.log(name); };
const greet be fn name
console.log[name]
const double = (x) => x * 2;
const greet = (name) => {
console.log(name);
};