Source Forms & Syntax
Relevant source files
The following files were used as context for generating this wiki page:
Jazz is a functional programming language characterized by a syntax that blends influences from Elixir and Haskell. Its source forms are defined by strong, static typing and type inference for core expressions, utilizing dot-terminated top-level statements and brace-bodied module declarations. The language prioritizes readability and ease of understanding, specifically aiming to simplify type system concepts for beginners by avoiding category theory terminology in favor of standard typeclasses.
Sources: README.md:3-9, README.md:12-20
Lexical Structure and Parsing
The Jazz compiler (currently implemented in jazz-next/) follows a structured pipeline for transforming source text into an actionable Abstract Syntax Tree (AST). The process begins with a minimal lexer for tokenization before proceeding to surface parsing and eventual lowering into a core AST.
Compiler Pipeline Flow
The following diagram illustrates the progression from raw source forms to the analyzer-facing AST within the active jazz-next implementation.
The parsing stage handles surface syntax slices, including operators and expressions, which are then transitioned across the "parse-AST -> analyzer-AST" boundary via the lowering module.
Sources: jazz-next/README.md:12-21
Core Syntax Elements
Jazz syntax is built upon several foundational structures that govern how expressions and declarations are formed.
Terminated Forms and Bindings
Top-level forms in Jazz are terminated with a period (.). Variables and functions are defined using immutable bindings with an assignment operator (=).
- Expressions: Core expressions support strong, static typing and inference.
- Functions: Declared as lambdas assigned to names. They are curried by default and support partial application.
- Signatures: Explicit type signatures use the
::operator (e.g.,add10 :: Int -> Int.).
Sources: README.md:12-20, README.md:46-52
Operator Syntax
Operators in Jazz include standard arithmetic and functional utilities. A notable operator is $, a right-associative, zero-precedence function application operator used to minimize parentheses.
| Operator | Usage | Description |
|---|---|---|
:: | name :: Type | Type signature declaration |
= | name = expr | Immutable binding |
$ | f $ x | Function application (avoids parentheses) |
-> | \(x) -> expr | Lambda/Function abstraction |
! | print! "msg" | Denotes impure/effectful functions |
Sources: README.md:46-58, README.md:92-95
Modules and Scoping
Jazz organizes code into hierarchical modules using a brace-bodied declaration style.
Example module syntax:
module Person::Organs::Heart {
beat = # ...
}
Sources: README.md:19-20, README.md:126-130
Function and Purity Semantics
Jazz distinguishes between pure and impure functions at the syntax level.
- Implicit Purity: Functions are pure by default.
- Impure Notation: Functions that perform side effects (impure) must end with a
!suffix. - Calling Constraints: Impure functions cannot be called from within pure function bodies; this is enforced by a stub-v1 direct-call check in the
jazz-nextcompiler. - Lambda Syntax: Functions are defined using backslashes for parameters, e.g.,
\(i) -> mod(i, 2) == 0.
Sources: README.md:18-19, README.md:92-96
Summary of Source Forms
| Feature | Syntax Form | Status |
|---|---|---|
| Top-level Termination | Dot (.) | Implemented |
| Modules | module Name { ... } | Implemented |
| Lists | [1, 2, 3] | Implemented |
| Comments | // or # | Implemented/Referenced |
| Type Signatures | name :: Type. | Implemented |
| Lambda | \(args) -> body | Implemented |
Sources: README.md:12-20, README.md:46-52, README.md:126-130
The Jazz syntax is designed to be evolutionary, with the jazz-next/ directory serving as the canonical implementation target for new surface parser features and operator fixity rules.
Sources: jazz-next/README.md:3-8, scripts/check-spec-authority.sh:22-26