Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Parameters in Depth

Surface Parameters: Typed Pairs

func’s :args list accepts strictly alternating type-name pairs: :type name :type name. This is by design — the surface language keeps parameter syntax simple and uniform.

(func greet
  :args (:string name :number age)
  :returns :string
  :body (template name " is " age " years old"))

Default Values

Use default in the parameter list to provide fallback values with type checking:

(func greet
  :args (:string name (default :string greeting "Hello"))
  :returns :string
  :body (template greeting ", " name "!"))
function greet(name, greeting = "Hello") {
  if (typeof name !== "string")
    throw new TypeError("greet: arg 'name' expected string, got " + typeof name);
  if (typeof greeting !== "string")
    throw new TypeError("greet: arg 'greeting' expected string, got " + typeof greeting);
  return `${greeting}, ${name}!`;
}

The type check fires on the final value — after JavaScript applies the default. So if the caller omits greeting, it defaults to "Hello", and the :string check passes.

Rest Parameters

Use rest to collect remaining arguments:

(func log-all
  :args (:string level (rest :any messages))
  :body (console:log level messages))
function logAll(level, ...messages) {
  if (typeof level !== "string")
    throw new TypeError("log-all: arg 'level' expected string, got " + typeof level);
  console.log(level, messages);
}

Destructured Parameters

func and fn accept destructuring patterns — an (object ...) or (array ...) list in :args — with per-field type annotations. This lets you type each destructured field individually:

(func connect
  :args ((object :string host :number port (default :boolean ssl true)))
  :body (open-connection host port ssl))

(connect (obj :host "localhost" :port 5432))
function connect({host, port, ssl = true}) {
  if (typeof host !== "string")
    throw new TypeError("connect: arg 'host' expected string, got " + typeof host);
  if (typeof port !== "number" || Number.isNaN(port))
    throw new TypeError("connect: arg 'port' expected number, got " + typeof port);
  if (typeof ssl !== "boolean")
    throw new TypeError("connect: arg 'ssl' expected boolean, got " + typeof ssl);
  openConnection(host, port, ssl);
}

This is the idiomatic “named parameters” pattern — the caller passes (obj :key value ...) and the function destructures with typed fields. Full coverage in Chapter 15, including nested patterns and the interaction with multi-clause dispatch.