Skip to main content


Chialisp's syntax is based on Lisp, but there are some differences. This is a primer on the structure of expressions. Everything in the language shares the same S-expression syntax, including operators and functions.


You can use one or more semicolons to denote that the rest of the line is a comment, and should be ignored when running the program.

;;; This is a comment.

(+ 3 2) ; This is also a comment.

Here are a few conventions for the number of semicolons to use:

  • 1 semicolon when right-aligned with code.
  • 2 semicolons when block-aligned with code.
  • 3 semicolons when top-level.


An atom is a big endian array of bytes. Atoms can be interpreted as either an integer or a raw byte string, depending on the operator.

They are immutable, so any time an operator performs a calculation, it is creating a new atom for the result rather than reusing the original. This ensures that Chialisp is stateless and doesn't allow for side effects.

Although an atom is represented in the same way regardless of the data stored in it, it can be written and displayed in the following ways to make it more meaningful to the reader:

  • Decimal (e.g. 100)
  • Hexadecimal (e.g. 0xFF)
  • String (e.g. "xyz" or 'xyz')
  • Symbol (e.g. hello)

When interpreting atoms as integers, it's important to remember that they are signed. In order to represent a positive integer, the most significant bit may not be set. Because of this, positive integers have a 0 byte prepended to them, in case the most significant bit in the next byte is set.


The value 0 or () is referred to as nil.

It can mean a few different things depending on the context:

  • Zero
  • False
  • Empty list
  • Empty bytes
  • List terminator

Boolean Values

Some operators treat atoms as booleans.

While every atom is considered to be true other than nil, the value is internally represented as 1.

Cons Pairs


Keep in mind that this is the syntax of the language itself. If you try to write a value as shown below, the language will interpret the first argument as an operator and throw an error.

Chances are, you want to use the list operator or quote the value with q instead, to prevent it from being interpreted as an operator.

A cons pair is a set of two values. A cons pair value looks like this:

(first . rest)

Because a value can be a cons pair itself, you can nest them in a chain:

(1 . (2 . (3 . ())))

When a chain of cons pairs ends in nil, it forms a proper list.

This is the preferred way of writing the same thing, in list form:

(1 2 3)

List Termination

A proper list is terminated with nil, but if you are using cons pairs as a struct of values rather than a list, you can choose not to terminate it with nil.

Here is an example of a struct with three values:

(1 2 . 3)

Which is equivalent to the following:

(1 . (2 . 3))


As previously mentioned, if you want to write a value using the syntax shown above, rather than a call to an operator, you need to use the quote operator. This treats an expression as a value rather than a program, preventing execution.

Here is an example quotation of a list:

(q . (1 2 3))

Which is equivalent to the following Chialisp code:

(list 1 2 3)

Because quotation prevents execution, any operators or constants used within will be left in the form they are written in rather than being replaced.


Usually for things such as modules and functions, you will only need a list of parameters. However, more advanced behavior is possible for destructuring those arguments. In fact, you can write a named list, cons pair, or single atom in whatever structure you need, and it will automatically destructure the environment into the constants provided.

This will capture the entire environment:

(mod environment

This will destructure an improper list:

(mod (first second . third)

And finally, this will unwrap a list within the list:

(mod (first (second third))

Include Files

You can write a set of utility functions, constants, and macros inside of a file to be included when needed in your Chialisp programs. This is known as an include file.

They are structured as a list of definitions, like this:

(defconstant ONE_HUNDRED 100)

(defun do-something-special ()