Function Namespace
rontolisp is a Lisp-2, following Common Lisp: functions and variables live in separate namespaces.
- A bare symbol evaluates as a variable. Evaluating
caralone is an error (The variable car is unboundin the interpreter; a compile error in the compilers). - A symbol in call position
(f args...)resolves in the function namespace only. A variable namedcarnever shadows the functioncar:(let ((car 5)) (car (list car 2)))returns5. - A function becomes a value through
#'name(reader syntax for(function name)),#'(lambda ...), or(symbol-function 'name). This works for built-in operators (#'+,#'car,#'1+,#'cadr), userdefuns, and lambdas. funcall/mapcar/reducealso accept a symbol naming a function (a function designator):(funcall 'car '(1 2))returns1. The compilers support this when the symbol is a quoted literal.defundefines into the function namespace and returns the function name.(setq f (lambda ...))binds a variable to a function value; call it with(funcall f ...), not(f ...).#'of a macro or special operator (e.g.#'if,#'defun) is an error.
Function values can be passed as arguments, returned from functions, and stored in data structures in all three execution modes.
Higher-order functions:
Closures (capture by reference):
Lambda as argument:
Built-in operators as first-class values:
Built-in operators like +, car, 1+ can be passed to higher-order functions via #':
Compiler restrictions. In the JVM/WASM compilers, #'name resolves against the
functions known at compile time (user defuns and built-in operators); #'mapcar,
#'reduce, #'apply and #'funcall themselves are not available as values (#'mapcan
and #'sort are). symbol-function requires a quoted symbol literal argument. In
--dynamic mode an unresolved #'name is deferred to the runtime eval environment like
any other unresolved reference. In compiled code apply/funcall dispatch by the actual
argument count against a fixed-arity wrapper synthesized for each built-in operator. The
naturally variadic operators -- +, -, *, /, list, min, max -- have variadic
wrappers, so (funcall #'+ 1 2 3), (apply #'list ...) and the like accept any argument
count. Every other multi-argument built-in keeps a fixed wrapper arity: #'cons,
#'append, #'gcd and the comparison chains (#'<, #'=, ...) are binary, so applying
them to a different count is unsupported on the compile path (matching the
Compiled eval limitations); use a user-defined function
or a lambda for other arities. The interpreter has no such restriction.