With LispBM comes a small library of dynamically loadable functions and macros. These functions occupy flash memory (if on an embedded platform) but only use heap if they are actually used by the application. Providing dynamically loadable operations is a way to save space while offering more sweet functionality.
LispBM can be built with varying amount of included dynamic loadable functionality. It is up to the LispBM integrator to decide what is included. As an integrator you can also decide to roll your entirely own set of dynamically loadable operations.
The inclusion of dynamically loadable functionality from this library is determined when LispBM is compiled using the following flags:
The flags should be given to the compiler as -Dx for example -DLBM_USE_DYN_FUNS.
Compute the absolute value
| Example | Result |
|
|
|
|
|
|
|
|
|
|
Filter a list from unwanted elements as decided by a predicate
| Example | Result |
|
|
|
|
foldl walks through a list, left to right, while
accumulating a result from applying a function to the element at hand
and the result of its previous step. foldl takes an initial value used
as the that is combined with the leftmost value of the list in the first
iteration.
| Example | Result |
|
|
foldl has an advantage over foldr in that
it is implemented in a tail-recursive and constant-storage way.
Funnily enough, foldl using function cons
and initial value nil converts a list to a snoc-list.
| Example | Result |
|
|
Now we are going off on a tangent, but car and
cdr switches roles with each other when operating on a
snoc-list.
| Example | Result |
|
|
|
|
|
|
foldr walks through a list, right to left, while
combining value and prev result step by step. An initial value is
provided and here used in the first, rightmost, operation.
foldr has a disadvantage compared to foldl
as I don't think it is possible to give foldr a
constant-space and tail-recursive implementation. One can make
foldr tail-recursive by writing it in continuation passing
style (CPS). The CPS version of foldr will run without building upon the
return stack, but instead it will construct and expand upon a
continuation object each iteration. This continuation object will grow
at the same rate as the call-stack otherwise would but it would grow in
heap usage.
| Example | Result |
|
|
Much less amusingly compared to foldl,
foldr of cons with initial value
nil is the identity function on proper lists.
| Example | Result |
|
|
iota takes one number as argument and generates a list
of values up to (not including) the given number.
| Example | Result |
|
|
second extracts the second element from a list.
| Example | Result |
|
|
|
|
compare strings according to alphabetical order ascending.
| Example | Result |
|
|
|
|
compare strings according to alphabetical order descending.
| Example | Result |
|
|
|
|
str-merge is an alternative name for the
str-join operations. It is kept around for backwards
compatibility.
| Example | Result |
|
|
third extracts the third element from a list.
| Example | Result |
|
|
|
|
defun is a macro that provides a shorthand form for
defining a named function. (defun name args body) is
expanded into (define name (lambda args body)).
| Example | Result |
|
|
|
|
defunret is like defun but you are allowed
to return at any point in the function body.
| Example | Result |
|
|
|
|
defmacro is a macro that provides a shorthand form for
defining macros. (defmacro name args body) expands into
(define name (macro args body)).
| Example | Result |
|
|
|
|
loopfor has the form
(loopfor it start cond update body) and implements a for
loop as familiar from for example C.
it is the iterator, start is what it is
initialized to, cond is the condition that has the be true
for the loop to continue running, update is how to update
the iterator after each iteration and body is the code to execute each
iteration. The iterator can be accessed from within body.
| Example | Result |
|
|
loopwhile has the form
(loopwhile cond body) and implements a while loop as
familiar from for example C.
cond is the condition that has the be true for the loop
to continue running and body is the code to execute each
iteration.
| Example | Result |
|
|
looprange has the form
(looprange it start end body) and implements a loop over a
range similar to python's for i in range(n).
Iterate it from start to end
and evaluate body for each iteration. The iterator it can
be accessed from within body.
| Example | Result |
|
|
| Example | Result |
|
|
loopforeach has the form
(loopforeach it lst body) and implements a loop over the
elements of a list similar to python's for e in ....
Iterate over every element in the list lst and evaluate
body for each iteration. The iterator it can
be accessed from within body.
| Example | Result |
|
|
loopwhile-thd is like loopwhile but the
thread runs in its own thread asynchronously. The form of a
loopwhile-thd is
(loopwhile-thd stack cond body).
A While-loop that starts in a new thread. The argument
stack is the stack-size of the thread, cond is
the condition that has the be true for the loop to continue running and
body is the code to execute each iteration. The difference
from the regular loopwhile is that the evaluator will continue running
the code after this one before this one finishes, as this loop is
evaluated in a new thread.
The following examples assumes that your LispBM integration has a way
to print.
Example that forever prints "Hello World" every two seconds:
(loopwhile-thd 100 t {
(print "Hello World")
(sleep 2)
})
The above is equivalent to the following code
(spawn 100 (fn () (loopwhile t {
(print "Hello World")
(sleep 2)
})))
It is possible to give the thread a name and/or a stack size. That gives the following combinations of possibilities:
No name and default stack size
(loopwhile-thd () t {
(print "Hello World1")
(sleep 2)
})
No name and stack size 100
(loopwhile-thd 100 t {
(print "Hello World2")
(sleep 2)
})
Name ThdTest and default stack size
(loopwhile-thd "ThdTest" t {
(print "Hello World3"
) (sleep 2)
})
Name ThdTest2 and stack size 100
(loopwhile-thd ("ThdTest2" 100) t {
(print "Hello World4")
(sleep 2)
})
Convert a list to an array
| Example | Result |
|
|
|
|
Convert an array to a list
| Example | Result |
|
|
|
|
Array predicate is true for arrays.
| Example | Result |
|
|
|
|
|
|
|
|
defstruct defines a datastructure with named fields
similar to a struct in C. defstruct takes two
arguments, a struct name and a list of fields
(defstruct name list-of-fields).
Structs are implemented as arrays of lisp values and offer constant time lookup of each of its fields. The struct itself does not occupy heap cells, but the values stored in the fields may.
As structs are allocated from array memory (lbm_memory), there is a potential for causing memory fragmentation.
The example below creates a structure type called my-struct with
three fields called a, b and
c.
| Example | Result |
|
|
Now instances of my-struct can be created using
make-my-struct.
| Example | Result |
|
|
when a struct is defined using defstruct a number of
functions for manipulation of that kind of struct is automatically
generated.
name.name.name and field
x.This will be more clear by showing with my-struct as
example.
| Example | Result |
|
|
|
|
|
|
my-struct? is a predicate that is true for instances of
my.struct.
| Example | Result |
|
|
|
|
|
|
my-struct-x with 2 arguments is a setter. with just the
struct instance as argument it is a getter.
| Example | Result |
|
|
|
|
|
|
This document was generated by LispBM version 0.34.2