Topaz Docs

Topaz Language Syntax

Welcome to the official Topaz syntax reference! This document provides a comprehensive overview of the fundamental grammar and syntactic constructs that make up the Topaz language. Topaz is engineered with an emphasis on unambiguous clarity, extreme efficiency, and a LISP-inspired S-expression structure, making it both powerful for developers and exceptionally well-suited for AI tools and applications.

Core Syntactic Philosophy

Before diving into the specifics, understanding these core principles will help you grasp the essence of Topaz syntax:

  • S-Expression Based: Like many dialects of Lisp and Scheme, all Topaz code is written as S-expressions (Symbolic Expressions). An S-expression is either an atom (a fundamental data value like a number or symbol) or a list of S-expressions enclosed in parentheses (). This uniform, tree-like structure simplifies parsing, makes the language highly regular, and enables powerful metaprogramming capabilities.
  • Expression-Oriented: In Topaz, almost everything is an expression that evaluates to a value. This contributes to the language's conciseness and functional nature.
  • Minimalism and Consistency: The syntax is designed with a small set of core rules that are applied consistently throughout the language.
  • Static Typing with Strong Inference: While Topaz is statically typed for safety and performance, explicit type annotations are often unnecessary due to its powerful type inference system. (See Data Types for more).
  • Immutability by Default: Data structures are primarily immutable, promoting safer and more predictable code, especially in concurrent environments.
  • Functional Programming Principles: Topaz embraces and encourages functional programming paradigms, leveraging pure functions and higher-order processes.

Fundamental Elements

1. S-Expressions

The basic syntactic unit in Topaz.

;; Atoms:
42                     ;; An Integer number
3.14159                ;; A Floating-point number
"Hello, Topaz"         ;; A String
:my-symbol             ;; A Symbol
is-ready?              ;; An Identifier (can also be an atom)
#true                  ;; Boolean true literal
#false                 ;; Boolean false literal
NULL_SIG               ;; The special Null Signal value

;; Lists (which are also S-expressions):
(+ 10 20)              ;; A simple operation: operator followed by arguments
($ x 100)              ;; A definition: special form, identifier, expression
(λ (a b) (+ a b))      ;; A lambda (anonymous process) definition

The first element of a list is typically an operator (a built-in operation or a user-defined process) or a special form (like $ or λ). The remaining elements are its arguments.

2. Comments

Comments are ignored by the Topaz interpreter/compiler and are used for human-readable annotations. Topaz uses double semicolons ;; for single-line comments. Everything from ;; to the end of the line is a comment.

;; This is a full-line comment.
($ pi 3.14159) ;; This comment follows an expression on the same line.

3. Identifiers

Identifiers are names used for variables, constants, processes, parameters, etc. They typically start with a letter or certain allowed symbols and can contain letters, numbers, and some special characters (e.g., -, ?, !). Conventions will be detailed further in style guides.

$my-variable 10$ process? (λ (x) (> x 0))
$ update-state! (λ (s) (;;... 
                    ))

Core Syntactic Forms

These are the primary constructs used to build Topaz programs.

1. Definitions: $

The $ special form binds a value (the result of an expression) to an identifier in the current scope. Syntax: ($ IDENTIFIER EXPRESSION)

  • IDENTIFIER: The name to define.
  • EXPRESSION: Any Topaz expression. Its evaluated result is bound to IDENTIFIER.

Examples:

($ age 30)
($ message "Welcome to Topaz")
($ sum (+ 15 27)) ;; sum is bound to 42

;; Defining a named process (function)
($ add-numbers
  (λ (x y) 
    (+ x y)
  )
)

2. Operations (Process/Function Calls)

Calling a process (user-defined or built-in) uses prefix notation. Syntax: (OPERATOR ARGUMENT_1 ARGUMENT_2 ... ARGUMENT_N)

  • OPERATOR: An identifier that evaluates to a process, or a built-in operator symbol.
  • ARGUMENT_n: Expressions that are evaluated before the operator is applied to them.

Examples:

(+ 1 2 3)                   ;; Evaluates to 6
(CONCAT "Topaz " "is " "fun!") ;; Evaluates to "Topaz is fun!"
(> 10 5)                    ;; Evaluates to 1 (true in boolean contexts)

;; Using the 'add-numbers' process defined above
(add-numbers 100 200)       ;; Evaluates to 300

3. Data Literals

Topaz has direct syntactic representations for its core data types. For a comprehensive guide, see the Data Types page.

  • Numbers: 123, -10, 3.14, 0.0
  • Strings: "A string", "" (empty string) * Booleans: #true (true) and #false (false) are the official boolean literals.
    ($ is-enabled #true)
    ($ has-errors #false)
    
  • Symbols: Prefixed with a colon (e.g., :active, :error-code) or quoted (e.g., 'my-symbol). Used for unique identifiers or enumerated-like values.
    ($ current-status :pending)
    
  • Vectors (Ordered Lists): Enclosed in square brackets [].
    ($ empty-vec [])
    ($ primes [2 3 5 7 11])
    ($ mixed-data [10 "label" :option-a])
    
  • Maps (Key-Value Pairs): Start with (# and then alternating keys and values, enclosed in ).
    ($ empty-map (#))
    ($ point (# :x 10 :y 20))
    ($ config (# "host" "localhost" "port" 8080 :retries 3))
    
  • NULL_SIG: A special literal representing the absence of a value.
    ($ no-result NULL_SIG)
    

4. Conditional Branching: IF

The IF special form provides conditional evaluation. Syntax: (IF CONDITION_EXPR TRUE_EXPR FALSE_EXPR)

  • CONDITION_EXPR: Evaluated. #true means the condition is true; #false or NULL_SIG means false.
  • TRUE_EXPR: Evaluated if CONDITION_EXPR is true.
  • FALSE_EXPR: Evaluated if CONDITION_EXPR is false. (Omitting FALSE_EXPR results in NULL_SIG if the condition is false).

Examples:

($ user-age 25)
($ access-level (IF (>= user-age 18) 
                   :adult 
                   :minor)) ;; access-level becomes :adult

($ temperature 15)
($ weather-advice (IF (< temperature 0)
                     "Wear a very warm coat!"
                     (IF (< temperature 15)
                        "A light jacket should be fine."
                        "Enjoy the pleasant weather!"
                     )
                  ))

5. Anonymous Processes (Lambdas): λ

The λ (lambda) special form creates an anonymous process (function). Syntax: (λ (PARAM_1 ... PARAM_N) BODY_EXPR_1 ... BODY_EXPR_N)

  • (PARAM_1 ... PARAM_N): A list of parameter identifiers. Use () for no parameters.
  • BODY_EXPR_n: One or more expressions forming the process body. The value of the last expression is the return value.

Examples:

;; A process that squares a number
(λ (n) (* n n))

;; Using $ to give a name to a lambda-defined process
($ square (λ (n) (* n n)))
(square 7) ;; Evaluates to 49

($ create-greeter 
  (λ (greeting)
    (λ (name) (string:concat greeting ", " name "!"))
  )
)
($ hello-greeter (create-greeter "Hello"))
(hello-greeter "Topaz Developer") ;; Evaluates to "Hello, Topaz Developer!"

6. User-Defined Types: DEFINE-TYPE

The DEFINE-TYPE special form creates structured data types (similar to structs or records). Syntax: (DEFINE-TYPE TypeName (# :fieldName1 FieldType1 :fieldName2 FieldType2 ...))

Examples:

;; Define a Point type with x and y coordinates
(DEFINE-TYPE Point (# :x Float :y Float))

;; Create instances using map literals that match the type structure
($ origin (# :x 0.0 :y 0.0))
($ point1 (# :x 10.5 :y -5.0))

;; Define a Person type with multiple field types
(DEFINE-TYPE Person (# :name String :age Integer :active Boolean))
($ user (# :name "Alice" :age 30 :active #true))

7. Enumerated Types: DEFINE-ENUM

The DEFINE-ENUM special form creates enumerated types with a fixed set of symbol values. Syntax: (DEFINE-ENUM EnumName :Value1 :Value2 :Value3 ...)

Examples:

;; Define a color enumeration
(DEFINE-ENUM Color :RED :GREEN :BLUE)

;; Define a status enumeration
(DEFINE-ENUM Status :PENDING :COMPLETED :FAILED :CANCELLED)

;; Use enumeration values
($ my-color :RED)
($ task-status :PENDING)

8. Generic Types (Type Parameters): λ [TypeParams]

Generic processes can work with multiple types by declaring type parameters. Syntax: (λ [TypeParam1 TypeParam2 ...] (param1: Type1 param2: Type2 ...) body-expr ...)

Examples:

;; A generic identity function that works with any type T
($ identity
  (λ [T] (value: T)
    value
  )
)

;; A generic function to get the first element of a vector
($ first-element
  (λ [E] (vec: (Vector E))
    (vector:first vec)
  )
)

;; Using generic functions
($ num-result (identity 42))           ;; T is inferred as Integer
($ str-result (identity "hello"))      ;; T is inferred as String
($ first-num (first-element [1 2 3]))  ;; E is inferred as Integer

9. Module System

9.1. Module Definition: MODULE

The MODULE special form defines a module and specifies which symbols to export. Syntax:

(MODULE module-name
  (EXPORT identifier1 identifier2 ...)
  
  ;; ... module body with definitions ...
)

Example (math.tpz):

(MODULE math
  (EXPORT PI add square)

  ($ PI 3.14159)
  ($ add (λ (a b) (+ a b)))
  ($ square (λ (n) (* n n)))
  ($ private-helper (λ () ...)) ;; Not exported, internal use only
)

9.2. Module Import: IMPORT

The IMPORT special form brings functionality from other modules into the current scope. Syntax:

  • (IMPORT module-name (identifier1 identifier2 ...)): Import specific symbols
  • (IMPORT module-name :as alias): Import entire module with alias (recommended)

Examples:

;; Import specific symbols from math module
(IMPORT math (add PI))
(io:print (core:to-string (+ (add 5 10) PI)))

;; Import math module with alias (recommended approach)
(IMPORT math :as m)
(io:print (core:to-string (m:add (m:square 5) m:PI)))

10. Macro System: DEFMACRO

The DEFMACRO special form enables compile-time code transformation using quasiquote mechanisms. Syntax: (DEFMACRO macro-name (param1 param2 ...) template-body)

Key Elements:

  • ` (backtick/quasiquote): Defines a code template where most content is not evaluated
  • , (comma/unquote): Within quasiquote, evaluates the expression and inserts the result
  • ,@ (comma-at/unquote-splicing): Evaluates a list and splices its contents into the template

Examples:

;; Define a 'when' macro that executes body only if condition is true
(DEFMACRO when (condition body-expressions...)
  `(IF ,condition
     (BEGIN ,@body-expressions)
     NULL_SIG
   )
)

;; Use the 'when' macro
($ x 10)
(when (> x 5)
  (io:print "x is greater than 5")
  (io:print "This also gets executed")
)

;; Define a 'unless' macro (opposite of when)
(DEFMACRO unless (condition body-expressions...)
  `(IF ,condition
     NULL_SIG
     (BEGIN ,@body-expressions)
   )
)

Standard Library and Naming Conventions

With the introduction of the module system, Topaz follows these naming conventions:

Core Module

The core module contains essential language operations and is automatically imported in all files:

  • +, -, *, /: Arithmetic operations
  • =, <, >, <=, >=: Comparison operations
  • IF, $, λ: Special forms
  • core:to-string: Type conversion functions

Module-Qualified Functions

Standard library functions use module prefixes:

  • (io:print ...): Input/output operations
  • (string:concat ...): String manipulation
  • (vector:map ...): Vector operations
  • (result:ok ...), (result:err ...): Result type constructors
  • (concurrent:spawn ...): Concurrency operations

Example Usage:

(IMPORT string :as str)
(IMPORT vector :as vec)

($ numbers [1 2 3 4 5])
($ doubled (vec:map (λ (n) (* n 2)) numbers))
($ result-string (str:concat "Doubled: " (core:to-string doubled)))
(io:print result-string)

Future Language Extensions

This reference covers Topaz v1.0 syntax. Future versions will include:

  • Advanced Pattern Matching: MATCH expressions for deconstructing complex data types
  • Type Classes/Interfaces: For defining shared behavior across types
  • Async/Await Primitives: For asynchronous programming patterns
  • FFI (Foreign Function Interface): For interoperability with other languages

Stay updated by checking our Guides and the main Topaz documentation page.