A symbol can have two values: a compile-time value and a run-time value.

Run-time values are functions, numbers, strings and other objects. Compile-time values are special forms, macros and compiler macros.

When a symbol is referenced in the first position of a form, its compile-time value is considered before its run-time value. In any other position only the run-time value is considered.


do is a special form equivalent to a {...} block in other languages. It has a compile-time value but no run-time value:

user > (do (print-line 1) (print-line 1))
it: null
user > do
Undefined variable: lisp:do

+ is a function. It has a no compile-time value but only a run-time value:

user > (+ 3 4)
it: 7
user > +
it: #<Function Name="Kiezel.Runtime.Add">
user > (map + '(1 2) '(3 4))
it: (4 6)

or is a special form and a function. It has a compile-time value and a run-time value:

user > (or (number? (do (print-line 123) 123))
           (string? (do (print-line "abc") "abc")))
it: true
user > or
it: #<Function Name="Kiezel.Runtime.LogicalOr">
user > (map or '(true false) '(true true))
it: (true true)

Functions with special forms

Depending on the actual arguments, calls to the following functions can be made faster by some Dynamic Language Runtime trickery.

attr elt set-attr set-elt

Special forms with functions

Only special forms can implement the short-circuiting behaviour of these functions, but the equivalent functions are nice to have.

and if or

Compiler Macros

Kiezellisp compiler macros are similar to Common Lisp compiler macros. Use a compiler macro to optimize special cases of a function call.

user > (defun ++ (&rest numbers)
           (apply + numbers))
it: ++
user > (define-compiler-macro ++ (&rest numbers &whole original-form)
           (if (and (= (length numbers) 2)
                    (number? (second numbers))
                    (= (second numbers) 1))
               `(inc ,(first numbers))
it: ++
user > (macroexpand '(++ a b c))
it: (++ a b c)
user > (macroexpand '(++ a 1))
it: (inc a)


The special forms def, defun, defun*, defconstant, defonce, defmulti and defmethod set a symbol's run-time value while erasing its compile-time value.

The special forms defmacro and define-symbol-macro set a symbol's compile-time value while erasing its run-time value.

The special form define-compiler-macro sets a symbol's compile-time value and requires its current run-time value to be a function.