Generics
Generic declarations dispatch by argument types and, when needed, the expected result type.
Reference manual
A guide to Verona’s programmable compilation model, core language, bundled base package, native boundary, and build environment.
1 — Foundation
Verona has two cooperating compilation layers. The first is a metaprogramming layer: macros run at compile time, receive and return S-expressions, and can inspect, construct, combine, or generate the syntax that the next layer will compile. The second is the top-level-form compiler: it expands those forms, collects declarations, resolves signatures, and type-checks executable bodies.
This separation is deliberate. In the metaprogramming layer, a program is data: lists, identifiers, strings, and quoted templates. A macro can build a function, a protocol implementation, or a sequence of definitions without turning those declarations into runtime values.
source
→ reader syntax
→ compile-time macro evaluation
→ expanded top-level forms
→ declaration collection and type checking
→ native artifact
2 — Language
Verona programs are written as S-expressions. Names are case-sensitive, and ; begins a line comment. String and character literals are ASCII-only; strings are immutable NUL-terminated byte pointers. Named control characters include #\tab, #\newline, #\vertical_tab, #\form_feed, and #\return. A char automatically widens where an integer is expected.
| Verona type | Meaning |
|---|---|
bool | Boolean value. |
char | One ASCII code unit. |
i8…i64, u8…u64 | Fixed-width signed and unsigned integers. |
isize, usize | Target-width integers. |
f32, f64 | Floating-point values. |
(pointer T) | Pointer to T; pointee information remains in Verona’s type system. |
(array T N) | Fixed-size array. |
(function (T...) R) | Function signature and function-pointer shape. |
| Product and sum types | Nominal records and alternatives for structured data. |
| Opaque type | A type owned by another interface and usable only behind a pointer. |
void | No-value marker for a C-facing result, not a Verona value. |
unit, never | The sole unit value and a terminating control-flow result. |
(type point (product (x i32) (y i32)))
(type option (sum (none) (some i32)))
(function unwrap ((value option)) i32
(match value
((none) 0)
((some number) number)))let, do, and return bind, sequence, and return values.array-of and index create and access fixed arrays.field reads a product field; match destructures sums and tuples. In a match pattern, _ discards its value and cannot be referenced in the case expression.&, deref, assign, cast, and pointer-offset express memory access explicitly; places are read implicitly when used as values.Generic declarations dispatch by argument types and, when needed, the expected result type.
for binds type parameters for reusable typed functions.
Protocols describe operations and constrain polymorphic functions.
import, export, and :as organize dotted modules and qualified names.
type declares transparent aliases, opaque handles, products, and sums.function, constant, and variable introduce program definitions.external-function imports a C symbol; native-export exposes a compatible function to C.#+name to include it when a reader feature is available, or #-name when it is not.The selected target provides platform, architecture, pointer-width, endianness, and object-format reader features. Add project features with repeated --feature NAME options.
#+darwin
(external-function mach-task-self
"mach_task_self" () u32)3 — Bundled package
The explicit base module provides surface declaration macros and the public protocol layer. Add base/src to a target’s module path, import it, and use its qualified forms.
Application programs should use operations exported by a module such as base, rather than compiler-internal %… primitives. Numeric type conversion is always explicit: use base:convert where a conversion is intended.
(import base)
(base:function total
(for (a)
((base:numeric a)))
((left a) (right a))
a
(+ left right))
(base:function same
(for (a)
((base:equality a)))
((left a) (right a))
bool
(= left right))
base:numericSupplies +, -, *, and /.
base:equalitySupplies =, including booleans.
base:orderingSupplies <, <=, >, and >=.
All three numeric protocols cover i8…i64, u8…u64, f32, and f64.
4 — Compile-time layer
Macros are compile-time programs that construct Verona syntax. A macro returns one expression form when used in executable code, or a sequence of top-level definitions when used at the top level. Source locations are retained by the compiler and restored after expansion.
The declarations in the explicit base module are imported macros, not built-in evaluator functions. compiler:definition and compiler:fold-left form the narrow compiler-facing bridge: the first constructs a compiler definition, and the second constructs a nested binary call tree.
| Function | Signature | Purpose |
|---|---|---|
+ | (+ NUMBER...) | Bootstrap arithmetic for evaluator tests and simple bootstrap macros; not a general-purpose macro library. |
definitions | (definitions FORM...) | Return zero or more top-level S-expression forms. |
compiler:definition | (compiler:definition PRIMITIVE ARGUMENTS) | Build a compiler %… definition from its positional arguments. |
compiler:fold-left | (compiler:fold-left HEAD INITIAL FORMS) | Build nested binary calls headed by HEAD. |
symbol, symbol-name, symbol-concat | Identifier operations | Construct, inspect, and join identifiers. |
keyword, keyword-concat | Identifier operations | Construct identifiers for keyword-style conventions; they are not reserved source keywords. |
string-concat, string-length, substring | String operations | Construct and inspect strings. |
list, cons, car, cdr, append, length | List operations | Construct and inspect finite, proper S-expression lists. |
'FORM quotes an S-expression, `FORM quasiquotes a template, and ,FORM evaluates and inserts an S-expression inside that template.
(import base)
(base:macro generated-function (type)
`(base:function ,(keyword-concat (keyword "generated-") ,type)
() ,type 42))
5 — Native boundary
Verona lowers typed programs through LLVM to native artifacts. The LLVM layer implements Verona’s native-code pipeline; the language itself exposes a defined C ABI boundary for interoperating with existing native software.
Use external-function to import a C symbol and native-export to publish a compatible Verona function. Static and shared libraries receive a generated .h file beside the artifact.
| Value shape | C contract | Availability |
|---|---|---|
bool | _Bool | Parameters and results. |
char | uint8_t | Parameters and results. |
| Narrow signed and unsigned integers | int8_t/int16_t, uint8_t/uint16_t | C ABI sign or zero extension. |
| Other numbers | Matching fixed-width integer, float, or double | Parameters and results. |
| Pointers | C pointer | Includes pointers to aggregates, opaque handles, void, and compatible functions. |
| Arrays, products, and sums | Generated C-compatible wrapper or struct | By value when their contents are compatible. |
| Opaque types | Forward-declared struct Name | Pointer-only. |
| Function type | C function pointer | Only as (pointer (function (...) R)). |
void | void | Result of an imported C function only. |
(external-function strlen "strlen" ((pointer u8)) usize)
(function add ((left i32) (right i32)) i32
(+ left right))
(native-export add "verona_add")
Variadic APIs and APIs that need exact C-layout callback storage require dedicated bindings before they can be called safely.
6 — Package setup
Verona packages use two independent environment variables. VERONA_SOURCE_DIR identifies the absolute root directory containing Verona package sources. VERONA_LIBRARY_DIR identifies the absolute root directory containing installed Verona package artifacts.
export VERONA_SOURCE_DIR="$HOME/.local/src/verona"
export VERONA_LIBRARY_DIR="$HOME/.local/lib/verona"
These variables describe Verona package locations only. They do not configure C-library discovery; native libraries remain target-specific build inputs.
The bundled bootstrap tutorial checks both variables, explains any missing setup, and prints links to the Verona site and source repository. Run it from the repository root with make bootstrap.
7 — Build tools
verona --version
verona compile SOURCE [options]
verona build TARGET OUTPUT-DIRECTORY [--feature NAME]...compile builds one root source file. build finds verona.build in the current directory and writes the selected target beneath the output directory.
(executable app
(root app.main)
(module-path "src")
(optimize 2)
(library "sqlite3"))Build files are declarative data: Verona forms inside them are never expanded or evaluated.
| Option | Description |
|---|---|
--version, -V | Print the Verona release version. |
-o PATH, --output PATH | Set the artifact path. |
--emit object|executable|static-library|shared-library | Choose artifact kind; executable is the default. |
--target TRIPLE | Select a native target triple. |
--cpu CPU | Select a CPU; defaults to generic. |
--features FEATURES | Pass a target-feature string. |
--feature NAME | Enable a reader feature; repeatable. |
-l NAME, --library NAME | Link -lNAME; repeatable. |
-L PATH, --library-path PATH | Add a library-search path; repeatable. |
--framework NAME | Link a Darwin framework; repeatable and Darwin-only. |
An executable can receive the platform command line with a C-compatible entry declaration. argc includes the executable name; argv points to its NUL-terminated byte strings.
(function main ((argc i32) (argv (pointer (pointer u8)))) exit-code
(let ((first-argument (pointer u8)
(deref (pointer-offset argv 1))))
; parse first-argument when argc is at least 2
0))
verona.build clausesA build file contains one or more executable, static-library, or shared-library declarations. Every target requires exactly one (root module.name) clause.
| Clause | Description |
|---|---|
(root module.name) | Required root module. |
(module-path "PATH") | Add a module search path; repeatable. Defaults to the build file directory. |
(target native) | Use the native target; the default. |
(target "TRIPLE") | Use an explicit target triple. |
(optimize 0)…(optimize 3) | Set optimization; default is 0. |
(version "VERSION") | Declare a release version for the target. |
(features NAME...) | Set target reader features; may appear once. |
(library "NAME") | Link a native library; repeatable. |
(library-path "PATH") | Add a native library-search path; repeatable. |
(framework "NAME") | Link a Darwin framework; repeatable and Darwin-only. |