# Predefined LFE functions

The following more or less standard lisp functions are predefined:

## Operators

### Arithmetic

``````(<arith_op> expr ...)
``````

The standard arithmetic operators, `+` `-` `*` and `/` can take multiple arguments the same as their standard Lisp counterparts. This is still experimental and implemented using macros. They do, however, behave like normal functions and evaluate ALL their arguments before doing the arithmetic operations.

Examples:

``````> (- 43 1)
42
> (* 21 2)
42
``````

### Comparison

``````(<comp_op> expr ...)
``````

The standard comparison operators, `>`, `>=`, `<`, `=<`, `==`, `/=`, `=:=`, and `=/=` can take multiple arguments the same as their standard Lisp counterparts. This is still experimental and implemented using macros. They do, however, behave like normal functions and evaluate ALL their arguments before doing the comparison operations.

Examples:

``````> (> 1 42)
false
> (< 42 43)
true
``````

## Association list functions

These are the same as found in Common Lisp.

### `acons`

``````(acons key value list)
``````

`acons` constructs a new association list by adding the pair `(key . datum)` to the old `list`.

Example:

``````> (acons 'x 'y 'a)
((x . y) . a)
``````

### `pairlis`

``````(pairlis keys values {{list}})
``````

`pairlis` takes two lists and makes an association list that associates elements of the first list to corresponding elements of the second list.

Example:

``````> (pairlis '(one two) '(1 2) '((three . 3) (four . 19)))
((one . 1) (two . 2) (three . 3) (four . 19))
``````

### `assoc`

``````(assoc key list)
``````

Searches the association list `list`. The value returned is the first pair in the `list` such that the `car` of the pair equals the `key` passed to `assoc`. or `()` If there is no such pair in the `list`, an empty list `()` is returned.

Examples:

``````> (assoc 'r '((a . b) (c . d) (r . x) (s . y) (r . z)))
(r . x)
> (assoc 'goo '((foo . bar) (zoo . goo)))
()
> (assoc '2 '((1 a b c) (2 b c d) (-7 x y z)))
(2 b c d)
>
``````

### `assoc-if`

``````(assoc-if test list)
``````

Searches the association list `list`. The value is the first pair in the `list` such that the `car` of the pair satisfies the test, or `()` if there is no such pair in the `list`.

Examples:

``````> (assoc-if #'is_atom/1 '(("a" . "b") (3 . 4) (r . x) (s . y) (r . z)))
(r . x)
> (assoc-if #'is_integer/1 '(("a" . "b") (3 . 4) (r . x) (s . y) (r . z)))
(3 . 4)
> (assoc-if #'is_list/1 '(("a" . "b") (3 . 4) (r . x) (s . y) (r . z)))
("a" 98)
> (assoc-if #'is_float/1 '(("a" . "b") (3 . 4) (r . x) (s . y) (r . z)))
()
``````

### `assoc-if-not`

``````(assoc-if-not test list)
``````

Searches the association list `list`. The value is the first pair in the `list` such that the `car` of the pair satisfies the test, or `()` if there is no such pair in the `list`.

Examples:

``````> (assoc-if-not #'is_float/1 '(("a" . "b") (3 . 4) (r . x) (s . y) (r . z)))
("a" 98)
> (assoc-if-not #'is_list/1 '(("a" . "b") (3 . 4) (r . x) (s . y) (r . z)))
(3 . 4)
``````

### `rassoc`

``````(rassoc value list)
``````

`rassoc` is the reverse form of `assoc`; it searches for a pair whose `cdr` satisfies the `test`, rather than the `car`.

Examples:

``````> (rassoc 'a '(("a" . "b") (r . 4) (3 . x) (s . y) (r . z)))
()
> (rassoc '4 '(("a" . "b") (r . 4) (3 . x) (s . y) (r . z)))
(r . 4)
> (rassoc 'z '(("a" . "b") (r . 4) (3 . x) (s . y) (r . z)))
(r . z)
``````

### `rassoc-if`

``````(rassoc-if test list)
``````

`rassoc` is the reverse form of `assoc`; it searches for a pair whose `cdr` satisfies the `test`, rather than the `car`.

Examples:

``````> (rassoc-if #'is_atom/1 '(("a" . "b") (r . 4) (3 . x) (s . y) (r . z)))
(3 . x)
> (rassoc-if
(lambda (x)
(== x 'y))
'(("a" . "b") (r . 4) (3 . x) (s . y) (r . z)))
(s . y)
``````

### `rassoc-if-not`

``````(rassoc-if-not test list)
``````

`rassoc` is the reverse form of `assoc`; it searches for a pair whose `cdr` satisfies the `test`, rather than the `car`.

Example:

``````> (rassoc-if-not
(lambda (x)
(or (is_list x) (is_integer x)))
'(("a" . "b") (r . 4) (3 . x) (s . y) (r . z)))
(3 . x)
``````

## Substitution of expressions

These are the same as found in Common Lisp.

### `subst`

``````(subst new old tree)
``````

`(subst new old tree)` makes a copy of `tree`, substituting `new` for every subtree or leaf of `tree` (whether the subtree or leaf is a `car` or a `cdr` of its parent) such that `old` and the subtree or leaf are equal to `new`. It returns the modified copy of `tree`. The original `tree` is unchanged.

Examples:

``````> (subst 'tempest 'hurricane
'(shakespeare wrote (the hurricane)))
(shakespeare wrote (the tempest))
> (subst 'tempest 'hurricane
'(thoughts:
(shakespeare wrote (the hurricane))
(hurricane (on (a (teacozy))))))
(thoughts: (shakespeare wrote (the tempest)) (tempest (on (a (teacozy)))))
> (subst 'foo '() '(shakespeare wrote (twelfth night)))
(shakespeare wrote (twelfth night . foo) . foo)
``````

### `subst-if`

``````(subst-if new test tree)
``````

`(subst new old tree)` makes a copy of `tree`, substituting `new` for every subtree or leaf of `tree` (whether the subtree or leaf is a `car` or a `cdr` of its parent) such that `old` and the subtree or leaf satisfy the test. It returns the modified copy of `tree`. The original `tree` is unchanged.

Example:

``````> (subst-if
'(a . cons)
(lambda (x)
(== x '(old . pair)))
'((old . spice) ((old . shoes) old . pair) (old . pair)))
((old . spice) ((old . shoes) a . cons) (a . cons))
``````

### `subst-if-not`

``````(subst-if-not new test tree)
``````

`(subst new old tree)` makes a copy of `tree`, substituting `new` for every subtree or leaf of `tree` (whether the subtree or leaf is a `car` or a `cdr` of its parent) such that `old` and the subtree or leaf satisfy the test. It returns the modified copy of `tree`. The original `tree` is unchanged.

Examples:

``````> (subst-if-not
'(a . cons)
(lambda (x)
(== x '(old . pair)))
'((old . spice) ((old . shoes) old . pair) (old . pair)))
(a . cons)
> (subst-if-not
'(a . cons)
(lambda (x)
(/= x '(old . pair)))
'((old . spice) ((old . shoes) old . pair) (old . pair)))
((old . spice) ((old . shoes) a . cons) (a . cons))
``````

### `subls`

``````(sublis list tree)
``````

`sublis` makes substitutions for objects in a `tree` (a structure of `cons`es). The first argument to `sublis` is an association `list`. The second argument is the `tree` in which substitutions are to be made, as with `subst`. `sublis` looks at all subtrees and leaves of the `tree`; if a subtree or leaf appears as a key in the association `list` (that is, the key and the subtree or leaf satisfy the test), it is replaced by the object with which it is associated. This operation is non-destructive. In effect, `sublis` can perform several `subst` operations simultaneously.

Examples:

``````> (sublis '((x . 100) (z . zprime))
'(plus x (minus g z x p) 4 . x))
(plus 100 (minus g zprime 100 p) 4 . 100)
> (sublis '(((+ x y) . (- x y)) ((- x y) . (+ x y)))
'(* (/ (+ x y) (+ x p)) (- x y)))
(* (/ (- x y) (+ x p)) (+ x y))
``````

## Expansion macros

``````(macroexpand-1 expr {{environment}})
``````

If `expr` is a macro call, does one round of expansion, otherwise returns `expr`.

``````(macroexpand expr {{environment}})
``````

Returns the expansion returned by calling macroexpand-1 repeatedly, starting with `expr`, until the result is no longer a macro call.

``````(macroexpand-all expr {{environment}})
``````

Returns the expansion from the expression where all macro calls have been expanded with `macroexpand`.

NOTE: When no explicit environment is given to the macroexpand functions, then only the default built-in macros will be expanded. Inside macros and in the shell, the variable `\$ENV` is bound to the current macro environment.

## Evaluation

``````(eval expr {{environment}})
``````

Evaluate the expression `expr`. Note that only the pre-defined Lisp functions, erlang BIFs, and exported functions can be called. Also no local variables can be accessed. To access local variables, the `expr` to be evaluated can be wrapped in a `let` defining these.

For example, if the data we wish to evaluate is in the variable `expr` and it assumes there is a local variable `foo` which it needs to access, then we could evaluate it by calling:

``````(eval `(let ((foo ,foo)) ,expr))
``````