# 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))
```