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)``. .. highlight:: hy 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))