Special forms

A special form is a head the compiler handles itself. When a form’s head names one, the compiler emits bytecode for it directly, following the form’s own rules for which arguments are evaluated and when. Every other head in call position is a runtime call. Each page below gives the form’s symbol, syntax, behaviour, and examples; the surface names most programs write, if, when, set!, class, are macros that lower to these.

The compiler binds each special under its compile/ name, and the short name is how a program uses it. How (foo ...) decides between a special, a macro, and a call is in Name resolution and prefixes.

Definition and binding

Form

Does

var

Bind a name in the current scope, with an optional type, or several names by unpacking

define

The Scheme-layer spelling of var, or of def when the name position is a pair [NAME FORMALS ...]

define-global

Bind a name at the module from any depth; what global var and global def lower to

define-values

Bind the names of a pattern in the current scope; what var over a pattern lowers to

define-global-values

Bind the names of a pattern at the module; what global var over a pattern lowers to

function

A named function value that is not bound

lambda

An anonymous function value; formals, defaults, rest collectors, annotations, by-ref

let

Lexical bindings for a body; named let for loops

letrec

Lexical bindings that may refer to each other

setq

Store into an existing binding; the special under set!

setq-values

Store into several bindings by unpacking

bindq

Bind a name to a ref

refq

The ref of a variable; the special under &name

deref

Read through a ref

takeq

Read a binding and clear it

delq

Delete a binding

globals, vars

The module namespace; the current scope’s namespace, or an object’s __dict__

parameter, parameterize

Read a dynamic parameter; rebind parameters for a body

Control flow

Form

Does

begin

Run forms in order; the value is the last

cond

The first clause whose test is true; what layout if reads to

switch

Branch on equality against candidates

match

Destructure against patterns; see Match patterns

and, or

Short-circuit conjunction and disjunction

while

Loop while a test is true, with an else: clause

for-each

Loop over an iterable, with destructuring and an else: clause

break, continue

Leave a loop, with an optional value; start the next iteration

return

Leave a function; several values return a tuple, keywords a values

try

Handle exceptions, with else: and finally: clauses

raise

Raise an exception, or re-raise the current one

check-exception, load-exception, clear-exception

Internal forms that try expands into

Objects, attributes, and items

Form

Does

attr, set-attr, del-attr

Read, store, delete an attribute; obj.name reads as attr

ref-attr, take-attr, inplace-attr

A ref to an attribute; take and delete; update in place

item, set-item, del-item

Read, store, delete a subscript; obj[key] reads as item

ref-item, take-item, inplace-item

A ref to a subscript; take and delete; update in place

inplace

Update a variable in place; the special under incr! and decr!

call

Call a value; forces a runtime call past a same-named macro

call-attr

Call a method by name; (obj.method ...) reads to this

build-class

Build a class value without binding a name; what class lowers to

instance?, subclass?

Type tests; a tuple as the second operand tests several types

#str, format

String conversion; format with an optional bare format spec

#list, #tuple, #list-append

Build a list or tuple; append to a list

Operators

Form

Does

==, !=, equal?, not-equal?

Equality, chained over any number of operands

<, <=, >, >=

Ordering, chained

le?, ge?

Aliases for <= and >=

**

Exponentiation with an optional modulus

in, not-in, is, is-not

Membership and identity, each with a ?-suffixed alias

not, truth, nil?, repr, len, type, dir, vars, iter, next, divmod

The unary and inspection operators

Object operators

The arithmetic, bitwise, and unary operators, constant folding, and the comparison table

Pairs and quoting

Form

Does

cons, car, cdr

Build a pair chain; its first element; its rest

bracket-cons, bracket-proper

Build a bracket pair chain; a proper bracket list

quote

A form as data; 'form

quote-syntax

A form as data, keeping hygiene marks; #'form; what a transformer’s patterns and templates are quoted with

quasiquote, unquote, unquote-splicing

A template; `form, ,form, ,@form

quasiquote-syntax

A template keeping hygiene marks; #`form; what a procedural macro a template defines builds its output with

Block quote, block quasiquote

The reader shorthands 'head: and `head:, which quote an indented block as its #block: cons; #'head: and #`head: do the same keeping hygiene marks

Async, generators, and continuations

Form

Does

await

Await a held awaitable; bare (await) is a cooperative suspend

yield, yield-from

Generator and coroutine suspension; delegation

with, dyn-with

Context managers, lexical and dynamic-extent

dyn-wind

Before and after thunks around a body, rerun across continuation jumps

reset, shift

Delimited continuations

call/cc, let/cc, capture/cc

Undelimited continuations, from the Scheme form down to the raw capture

Modules

Form

Does

import

Import a module; [MODULE as: NAME] binds the leaf

import-from

Import names from a module, with aliases

import-all-from

Bind a module’s public names, at module level only

use

Import a feature with all its facets, a macro together with its runtime sibling

Macro definition and the compiler

Form

Does

syntax-rules, syntax-match

Template transformers, by rule list and by named spec

macro-rules, macro-match

Procedural transformers

special-rules, special-match

Transformers that receive the compiler and emit bytecode

bare-syntax

The arm used when a syntax name appears as a lone atom

gensym-thunk

The {...} thunk with inferred %1, %2 formals

apply-fence

Expand a fenced foreign literal through its handler

bytecode

Inject bytecode directly

Patterns and hygiene

Many specials declare their shape with koskari.matcher patterns, and a form that fits none of a special’s patterns fails with SyntaxMatchError at compile time. The transformer forms share one matcher and one hygiene model; see Macros and hygiene and koskari.hygiene.