Special Forms¶
Special forms are pseudo-functions handled directly by the evaluator. They cannot be extended or altered.
Sequence Forms¶
There are three sequence special forms: begin
, and
and or
.
They all take a sequence of expressions and start to evaluate them,
one by one. They differ in how many of the expressions they evaluate,
what they return and what they return if no expressions are passed.
begin ...
and ...
or ...
begin¶
begin
evaluates all of the expressions and returns the value of
the last expression.
This is the normal block of code behaviour.
If no expressions are passed, begin
returns #<void>
.
and¶
and
evaluates all of the expressions unless an expression returns
#f
at which point and
also returns #f
. The remaining
expressions are not evaluated.
If all of the expression return a true value then and
returns
the value of the last expression.
If no expressions are passed, and
returns #t
.
or¶
or
evaluates all of the expressions until an expression returns a
true value and or
returns that value. The remaining expressions
are not evaluated.
If all of the expressions return #f
then or
returns #f
.
If no expressions are passed, or
returns #f
.
not¶
The not
special form is used to inverted the sense of a boolean.
There is a function variant, not/function, for where a function is required.
escape¶
The escape
special form is used to prevent the reader implementing
operators. The default reader escape character is \
.
escape e
\e
escape
continues evaluation with its argument.
For example, the infix operator +
expects numbers as arguments so
we might make a mis-type before escaping it:
Idio> apply + 1 2 3
...:^rt-parameter-type-error:bad parameter type: '#<PRIM apply>' a primitive is not a number
...
#<unspec>
Idio> apply \+ 1 2 3
6
quote¶
The quote
special form is used to prevent the evaluator evaluating
its argument. The default reader quote character is '
.
quote e
'e
quote
returns its argument unevaluated.
For example, any parenthesised list is considered a function call so we need to quote any literal lists:
Idio> printf "a list %s\n" (1 2 3)
...:^rt-function-error:cannot invoke constant type: detail (1)
...
Idio> printf "a list %s\n" '(1 2 3)
a list (1 2 3)
#<unspec>
quasiquote¶
The quasiquote
special form is the basis for expanding
templates.
#T{ ... }
function/name¶
The function/name
special form is used to return a function value,
commonly called a closure.
function/name name formals [docstr] body
name is the name to be associated with the function.
formals declares the parameters for the closure and arguments passed to the function are available through the named parameters within the body of the function.
formals takes several forms, see closure parameters and the extended forms in function*/name.
The optional docstr allows the user to describe their function. This text will be used in help output as well as used to generate documentation like this. It should take the form of reStructuredText targeting the Sphinx documentation system.
body is a single expression although commonly a block is used as a synonym for the begin sequence special form.
function/name
exists largely because debugging with anonymous
functions becomes difficult especially when that anonymity exists only
because of the deliberate enforcement of anonymity in the evaluator.
(define (foo a b) ...)
was rewritten to:
(define foo (function a b) ...)
but can now be rewritten to:
(define foo (function/name foo a b) ...)
which keeps the normal form and also ensures the name of the function value is carried through.
function¶
The function
special form is used to return a function value,
commonly called a closure.
function formals [docstr] body
function
only differs from function/name in the absence of a name. function
is a simple
wrapper to function/name
passing (gensym 'anon)
as the
function’s name.
function+¶
The function+
special form is used to extend the current
function’s argument frame. It appears when a function’s body is
rewritten to a normal form.
Users are not expected to use this special form.
if¶
The if
special form is the fundamental test and branch mechanism.
if condition consequent alternative
If the expression condition evaluates to true then evaluate consequent otherwise evaluate alternative.
Whichever of consequent or alternative is evaluated, its result is
the value returned by if
.
If condition evaluates to #f
and there is no alternative then
if
returns #<void>
.
cond¶
The cond
special form is an abstraction of the if Special Form. It is equivalent to many languages’ if
... elif ... elif ... else ...
.
cond clauses
clauses is a list of clauses where each clause can take the form:
(condition ...)
If the expression condition evaluates to true then evaluate … returning its value as the value from
cond
.(condition => f)
If the expression condition evaluates to true then call the function f with the result of condition and return the result of f as the value from
cond
.This is the anaphoric if expression, roughly equivalent to:
it := condition if it { f it }
where condition is evaluated and the result recorded. If the result was true then call f with the result as an argument.
(else ...)
Evaluate … returning its value as the value from
cond
.The
else
clause can only appear as the last clause
If no clauses satisfy and there is no else
clause, cond
returns #<void>
.
set!¶
The set!
special form modifies memory, hence the !
in the
name. It has an =
synonym and an =
reader operator.
set! var value
= var value
var = value
Note
Technically, set!
doesn’t modify any value but changes a
reference to point to a different value.
From a user perspective, the variable has a different value.
define-template¶
The define-template
special form is used to create templates.
define-infix-operator¶
The define-infix-operator
special form is used to create reader
operators.
define-postfix-operator¶
The define-postfix-operator
special form is used to create reader
operators.
define¶
The define
special form is used to create lexically scoped
references between symbols, symbolic names, aka identifiers, and
values. It has an :=
synonym and a :=
reader operator.
define var value
:= var value
var := value
The base form of define
is define var value
and
creates a reference from var to value.
A second form is for defining functions: define (name
formals) body
.
This is rewritten into the base form as: define name
(function/name name formals body)
thus creating a reference
from name to a function value.
:*¶
The :*
special form is used to create dynamically scoped
references between symbols, symbolic names, aka identifiers, and
values which will subsequently become environment variables when an
external command is executed. It has a :*
reader operator.
:* var value
var :* value
environ-let¶
The environ-let
special form is used to evaluate an expression in
the context of a dynamically scoped environment variable.
environ-let (var expr) body
environ-unset¶
The environ-unset
special form is used to evaluate an expression
in the context of the absence of a dynamically scoped environment
variable.
environ-unset var body
:~¶
The :~
special form is used to create dynamically scoped
references between symbols, symbolic names, aka identifiers, and
values. It has a :~
reader operator.
:~ var value
var :~ value
dynamic¶
The dynamic
special form is used to access dynamically scoped
variables.
There is normally no need to use this as the evaluator should figure our the variable is referencing a dynamic value and create the code accordingly.
dynamic-let¶
The dynamic-let
special form is used to evaluate an expression in
the context of a dynamically scoped variable.
dynamic-let (var expr) body
dynamic-unset¶
The dynamic-unset
special form is used to evaluate an expression
in the context of the absence of a dynamically scoped variable.
dynamic-unset var body
:$¶
The :$
special form is used to create lexically scoped references
between symbols, symbolic names, aka identifiers, and computed values.
It has a :$
reader operator.
:$ var getter
:$ var getter setter
:$ var #n setter
var :$ getter
var :$ getter setter
var :$ #n setter
Here, getter and setter are functions of no args and one arg, respectively, which retrieve or set some, usually, volatile value.
The value of variable SECONDS when evaluated returns the number of seconds the program has been running for. It has no associated setter so trying to give it a value is an error.
block¶
The block
special form is largely a synonym for the begin sequencing special form but it does create a new
lexical context.
Variables created within a block are not accessible outside the block.
Amongst other things this allows for the creation of privately scoped variables.
trap¶
The trap
special form is used to set in place a handler for a
condition type or types for the evaluation of some body.
trap condition handler body trap (conditions) handler body
Here, if a condition is raised during the execution of body that is one of the types in conditions or a descendent thereof then handler is run.
handler can choose to:
return a value on behalf of the erroring function by simply returning a value
can raise the condition to a previously established handler
See Condition Handlers for further information.
include¶
The include
special form is used by the evaluator to pause,
load
another file and then resume processing the current
file.
Note
The C defined include
special form uses the C
primitive load function not any redefinition.
The Idio defined include
special form simply opens the
file and evaluates each expression.
include filename
Last built at 2024-12-21T07:10:37Z+0000 from 62cca4c (dev) for Idio 0.3.b.6