Functions

Function types

Unlike other Lisps, macros and language axioms are functions in Antilisp. The difference between a typical function and a special function like (if) is the execution mode. The execution mode of a function is a symbol that specifies if and how arguments should be evaluated. The available values are:

Symbol

What it does

Example

function

Evaluate arguments and call the function with them

(+), (list)

macro

Evaluate the result of the computation

(def), (defclass)

no-eval

Do not evaluate the arguments at all

(if), (and), (or)

no-expand

Do not expand macros and do not evaluate arguments

(quote), (quasiquote)

The execution mode of a function cannot be changed because functions are immutable. However, you can create a modified version of a function with (with-exec-mode).

This can be very useful when debugging macros. Here is an example with the (incr) macro, used to increment a variable:

; this macro has a bug and won't work
(defmacro (incr x)
  `(set-symbol ,x (+ ,x 1)))
(define counter 0)
(incr counter)
(print counter)  ; still 0

; print the code that would be generated by (incr counter)
(print ((with-exec-mode 'function incr) 'counter))
; returns: (set-symbol counter (+ counter 1))
; the bug: (set-symbol) wants a quoted symbol as its first argument

; fixed implementation:
(defmacro (incr x)
  `(set-symbol ',x (+ ,x 1))`)
(incr counter)
(print counter)  # 1

Rest arguments

Functions can accept any number of arguments using a rest parameter:

; f will accept 2 or more parameters:
(def (f x y . args)
  (print x)
  (print y)
  (print args))

Applying arguments

Sometimes, you may need to call a function with a list of arguments. This is where you can use (apply):

(apply print '(5))
; 5
(def (my-sum lst)
  (apply + lst))