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 |
|
macro |
Evaluate the result of the computation |
|
no-eval |
Do not evaluate the arguments at all |
|
no-expand |
Do not expand macros and do not evaluate arguments |
|
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))