author |
Steve Losh <steve@stevelosh.com> |
date |
Tue, 30 Apr 2019 17:06:11 -0400 |
parents |
de9d10a9b4b5 |
children |
e844dad54ef3 |
# Documentation for `cl-losh`
This library is my own personal utility belt.
Everything I write in here is MIT licensed, so you're free to use it if
you want. But I make no guarantees about backwards compatibility -- I might
change and break things at any time. Use this at your own risk.
[TOC]
## Package `LOSH`
This package exports all of the symbols in the other packages.
If you just want to get everything you can `:use` this one and be done with
it. Otherwise you can `:use` only the ones you need.
## Package `LOSH.ARRAYS`
Utilities related to arrays.
### `BISECT-LEFT` (function)
(BISECT-LEFT PREDICATE VECTOR TARGET)
Bisect `vector` based on `(predicate el target)` and return the LEFT element.
`vector` must be sorted (with `predicate`) before this function is called
(this is not checked).
You can think of this function as partitioning the elements into two halves:
those that satisfy `(predicate el target)` and those that don't, and then
selecting the element on the LEFT side of the split:
satisfying not statisfying
#(.......... ...............)
^
|
result
Two values will be returned: the element and its index. If no element
satisfies the predicate `nil` will be returned for both values.
Examples:
; index
; 0 1 2 3 4 5 val index
(bisect #'< #(1 3 5 7 7 9) 5) ; => 3, 1
(bisect #'<= #(1 3 5 7 7 9) 5) ; => 5, 2
(bisect #'<= #(1 3 5 7 7 9) 7) ; => 7, 4
(bisect #'< #(1 3 5 7 7 9) 1) ; => nil, nil
(bisect #'> #(9 8 8 8 1 0) 5) ; => 8, 3
### `BISECT-RIGHT` (function)
(BISECT-RIGHT PREDICATE VECTOR TARGET)
Bisect `vector` based on `(predicate el target)` and return the RIGHT element.
`vector` must be sorted (with `predicate`) before this function is called
(this is not checked).
You can think of this function as partitioning the elements into two halves:
those that satisfy `(predicate el target)` and those that don't, and then
selecting the element on the RIGHT side of the split:
satisfying not statisfying
#(.......... ...............)
^
|
result
Two values will be returned: the element and its index. If every element
satisfies the predicate `nil` will be returned for both values.
Examples:
; index
; 0 1 2 3 4 5 val index
(rbisect #'< #(1 3 5 7 7 9) 5) ; => 5, 2
(rbisect #'<= #(1 3 5 7 7 9) 5) ; => 7, 3
(rbisect #'<= #(1 3 5 7 7 9) 7) ; => 9, 5
(rbisect #'< #(1 3 5 7 7 9) 10) ; => nil, nil
(rbisect #'> #(9 8 8 8 1 0) 5) ; => 1, 4
### `DO-ARRAY` (macro)
(DO-ARRAY (VALUE ARRAY)
&BODY
BODY)
Perform `body` once for each element in `array` using `value` for the place.
`array` can be multidimensional.
`value` will be `symbol-macrolet`ed to the appropriate `aref`, so you can use
it as a place if you want.
Returns the array.
Example:
(let ((arr (vector 1 2 3)))
(do-array (x arr)
(setf x (1+ x))))
=> #(2 3 4)
### `FILL-MULTIDIMENSIONAL-ARRAY` (function)
(FILL-MULTIDIMENSIONAL-ARRAY ARRAY ITEM)
Fill `array` with `item`.
Unlike `fill`, this works on multidimensional arrays. It won't cons on SBCL,
but it may in other implementations.
### `FILL-MULTIDIMENSIONAL-ARRAY-FIXNUM` (function)
(FILL-MULTIDIMENSIONAL-ARRAY-FIXNUM ARRAY ITEM)
Fill `array` (which must be of type `(array FIXNUM *)`) with `item`.
Unlike `fill`, this works on multidimensional arrays. It won't cons on SBCL,
but it may in other implementations.
### `FILL-MULTIDIMENSIONAL-ARRAY-SINGLE-FLOAT` (function)
(FILL-MULTIDIMENSIONAL-ARRAY-SINGLE-FLOAT ARRAY ITEM)
Fill `array` (which must be of type `(array SINGLE-FLOAT *)`) with `item`.
Unlike `fill`, this works on multidimensional arrays. It won't cons on SBCL,
but it may in other implementations.
### `FILL-MULTIDIMENSIONAL-ARRAY-T` (function)
(FILL-MULTIDIMENSIONAL-ARRAY-T ARRAY ITEM)
Fill `array` (which must be of type `(array T *)`) with `item`.
Unlike `fill`, this works on multidimensional arrays. It won't cons on SBCL,
but it may in other implementations.
### `VECTOR-LAST` (function)
(VECTOR-LAST VECTOR)
Return the last element of `vector`, or `nil` if it is empty.
A second value is returned, which will be `t` if the vector was not empty and
`nil` if it was.
The vector's fill-pointer will be respected.
## Package `LOSH.BITS`
Utilities for low-level bit stuff.
### `+/16` (function)
(+/16 X Y)
Perform 16-bit signed addition of `x` and `y`.
Returns two values: the result and a boolean specifying whether
underflow/overflow occurred.
### `+/32` (function)
(+/32 X Y)
Perform 32-bit signed addition of `x` and `y`.
Returns two values: the result and a boolean specifying whether
underflow/overflow occurred.
### `+/64` (function)
(+/64 X Y)
Perform 64-bit signed addition of `x` and `y`.
Returns two values: the result and a boolean specifying whether
underflow/overflow occurred.
### `+/8` (function)
(+/8 X Y)
Perform 8-bit signed addition of `x` and `y`.
Returns two values: the result and a boolean specifying whether
underflow/overflow occurred.
### `-/16` (function)
(-/16 X Y)
Perform 16-bit signed subtraction of `x` and `y`.
Returns two values: the result and a boolean specifying whether
underflow/overflow occurred.
### `-/32` (function)
(-/32 X Y)
Perform 32-bit signed subtraction of `x` and `y`.
Returns two values: the result and a boolean specifying whether
underflow/overflow occurred.
### `-/64` (function)
(-/64 X Y)
Perform 64-bit signed subtraction of `x` and `y`.
Returns two values: the result and a boolean specifying whether
underflow/overflow occurred.
### `-/8` (function)
(-/8 X Y)
Perform 8-bit signed subtraction of `x` and `y`.
Returns two values: the result and a boolean specifying whether
underflow/overflow occurred.
## Package `LOSH.CHILI-DOGS`
Gotta go FAST.
### `DEFUN-INLINE` (macro)
(DEFUN-INLINE NAME
&BODY
BODY)
Like `defun`, but declaims `name` to be `inline`.
### `DEFUN-INLINEABLE` (macro)
(DEFUN-INLINEABLE NAME
&BODY
BODY)
Like `defun-inline`, but declaims `name` to be `notinline` afterword.
This is useful when you don't want to inline a function everywhere, but *do*
want to have the ability to inline it on demand with (declare (inline ...)).
## Package `LOSH.CLOS`
Utilities for working with CLOS.
### `DEFCLASS*` (macro)
(DEFCLASS* NAME-AND-OPTIONS DIRECT-SUPERCLASSES SLOTS &REST OPTIONS)
`defclass` without the tedium.
This is like `defclass`, but the `:initarg` and `:accessor` slot options will
automatically be filled in with sane values if they aren't given.
## Package `LOSH.CONTROL-FLOW`
Utilities for managing control flow.
### `-<>` (macro)
(-<> EXPR &REST FORMS)
Thread the given forms, with `<>` as a placeholder.
### `DO-RANGE` (macro)
(DO-RANGE RANGES
&BODY
BODY)
Perform `body` on the given `ranges`.
Each range in `ranges` should be of the form `(variable from below)`. During
iteration `body` will be executed with `variable` bound to successive values
in the range [`from`, `below`).
If multiple ranges are given they will be iterated in a nested fashion.
Example:
(do-range ((x 0 3)
(y 10 12))
(pr x y))
; =>
; 0 10
; 0 11
; 1 10
; 1 11
; 2 10
; 2 11
### `DO-REPEAT` (macro)
(DO-REPEAT N
&BODY
BODY)
Perform `body` `n` times.
### `GATHERING` (macro)
(GATHERING
&BODY
BODY)
Run `body` to gather some things and return a fresh list of them.
`body` will be executed with the symbol `gather` bound to a function of one
argument. Once `body` has finished, a list of everything `gather` was called
on will be returned.
It's handy for pulling results out of code that executes procedurally and
doesn't return anything, like `maphash` or Alexandria's `map-permutations`.
The `gather` function can be passed to other functions, but should not be
retained once the `gathering` form has returned (it would be useless to do so
anyway).
Examples:
(gathering
(dotimes (i 5)
(gather i))
=>
(0 1 2 3 4)
(gathering
(mapc #'gather '(1 2 3))
(mapc #'gather '(a b)))
=>
(1 2 3 a b)
### `GATHERING-VECTOR` (macro)
(GATHERING-VECTOR OPTIONS
&BODY
BODY)
Run `body` to gather some things and return a fresh vector of them.
`body` will be executed with the symbol `gather` bound to a function of one
argument. Once `body` has finished, a vector of everything `gather` was
called on will be returned. This vector will be adjustable and have a fill
pointer.
It's handy for pulling results out of code that executes procedurally and
doesn't return anything, like `maphash` or Alexandria's `map-permutations`.
The `gather` function can be passed to other functions, but should not be
retained once the `gathering` form has returned (it would be useless to do so
anyway).
Examples:
(gathering-vector ()
(dotimes (i 5)
(gather i))
=>
#(0 1 2 3 4)
(gathering-vector ()
(mapc #'gather '(1 2 3))
(mapc #'gather '(a b)))
=>
#(1 2 3 a b)
### `IF-FOUND` (macro)
(IF-FOUND (VAR LOOKUP-EXPR) THEN ELSE)
Perform `then` or `else` depending on the results of `lookup-expr`.
`lookup-expr` should be an expression that returns two values, the first being
the result and the second indicating whether the lookup was successful. The
standard `gethash` is an example of a function that behaves like this.
If the lookup was successful, `then` will be executed with `var` bound to the
result, and its value returned.
Otherwise `else` will be executed and returned, without any extra bindings.
Example:
(multiple-value-bind (val found) (gethash :foo hash)
(if found
'yes
'no))
; becomes
(if-found (val (gethash :foo hash))
'yes
'no)
### `IF-LET` (macro)
(IF-LET BINDINGS
&BODY
BODY)
Bind `bindings` in parallel and execute `then` if all are true, or `else` otherwise.
`body` must be of the form `(...optional-declarations... then else)`.
This macro combines `if` and `let`. It takes a list of bindings and binds
them like `let` before executing the `then` branch of `body`, but if any
binding's value evaluate to `nil` the process stops there and the `else`
branch is immediately executed (with no bindings in effect).
If any `optional-declarations` are included they will only be in effect for
the `then` branch.
Examples:
(if-let ((a (progn (print :a) 1))
(b (progn (print :b) 2))
(c (progn (print :c) 3)))
(list a b c)
'nope)
; =>
:A
:B
:C
(1 2 3)
(if-let ((a (progn (print :a) 1))
(b (progn (print :b) nil))
(c (progn (print :c) 3)))
(list a b c)
'nope)
; =>
:A
:B
NOPE
### `IF-LET*` (macro)
(IF-LET* BINDINGS
&BODY
BODY)
Bind `bindings` sequentially and execute `then` if all are true, or `else` otherwise.
`body` must be of the form `(...optional-declarations... then else)`.
This macro combines `if` and `let*`. It takes a list of bindings and binds
them like `let*` before executing the `then` branch of `body`, but if any
binding's value evaluate to `nil` the process stops there and the `else`
branch is immediately executed (with no bindings in effect).
If any `optional-declarations` are included they will only be in effect for
the `then` branch.
Examples:
(if-let* ((a (progn (print :a) 1))
(b (progn (print :b) 2))
(c (progn (print :c) 3)))
(list a b c)
'nope)
; =>
:A
:B
:C
(1 2 3)
(if-let* ((a (progn (print :a) 1))
(b (progn (print :b) nil))
(c (progn (print :c) 3)))
(list a b c)
'nope)
; =>
:A
:B
NOPE
### `MULTIPLE-VALUE-BIND*` (macro)
(MULTIPLE-VALUE-BIND* BINDINGS
&BODY
BODY)
Bind each pair in `bindings` with `multiple-value-bind` sequentially.
Example:
(multiple-value-bind*
(((a b) (values 0 1))
((c) (values (1+ b)))
(list a b c))
; =>
; (0 1 2)
From https://github.com/phoe/m-m-v-b
### `NEST` (macro)
(NEST &REST FORMS)
Thread the given forms, putting each as the body of the previous.
Example:
(nest (multiple-value-bind (a b c) (foo))
(when (and a b c))
(multiple-value-bind (d e f) (bar))
(when (and d e f))
(do-something))
macroexpands to:
(multiple-value-bind (a b c) (foo)
(when (and a b c)
(multiple-value-bind (d e f) (bar)
(when (and d e f)
(do-something)))))
### `RECURSIVELY` (macro)
(RECURSIVELY BINDINGS
&BODY
BODY)
Execute `body` recursively, like Clojure's `loop`/`recur`.
`bindings` should contain a list of symbols and (optional) starting values.
In `body` the symbol `recur` will be bound to the function for recurring.
This macro doesn't perform an explicit tail-recursion check like Clojure's
`loop`. You know what you're doing, right?
Example:
(defun length (some-list)
(recursively ((list some-list)
(n 0))
(if (null list)
n
(recur (cdr list) (1+ n)))))
### `WHEN-FOUND` (macro)
(WHEN-FOUND (VAR LOOKUP-EXPR)
&BODY
BODY)
Perform `body` with `var` bound to the result of `lookup-expr`, when valid.
`lookup-expr` should be an expression that returns two values, the first being
the result (which will be bound to `var`) and the second indicating whether
the lookup was successful. The standard `gethash` is an example of a function
that behaves like this.
If the lookup was successful, `body` will be executed and its value returned.
Example:
(multiple-value-bind (val found) (gethash :foo hash)
(when found
body))
; becomes
(when-found (val (gethash :foo hash))
body)
### `WHEN-LET` (macro)
(WHEN-LET BINDINGS
&BODY
BODY)
Bind `bindings` in parallel and execute `body`, short-circuiting on `nil`.
This macro combines `when` and `let`. It takes a list of bindings and binds
them like `let` before executing `body`, but if any binding's value evaluates
to `nil` the process stops there and `nil` is immediately returned.
Examples:
(when-let ((a (progn (print :a) 1))
(b (progn (print :b) 2))
(c (progn (print :c) 3)))
(list a b c))
; =>
:A
:B
:C
(1 2 3)
(when-let ((a (progn (print :a) 1))
(b (progn (print :b) nil))
(c (progn (print :c) 3)))
(list a b c))
; =>
:A
:B
NIL
### `WHEN-LET*` (macro)
(WHEN-LET* BINDINGS
&BODY
BODY)
Bind `bindings` sequentially and execute `body`, short-circuiting on `nil`.
This macro combines `when` and `let*`. It takes a list of bindings and binds
them like `let` before executing `body`, but if any binding's value evaluates
to `nil` the process stops there and `nil` is immediately returned.
Examples:
(when-let* ((a (progn (print :a) 1))
(b (progn (print :b) 2))
(c (progn (print :c) 3)))
(list a b c))
; =>
:A
:B
:C
(1 2 3)
(when-let* ((a (progn (print :a) 1))
(b (progn (print :b) nil))
(c (progn (print :c) 3)))
(list a b c))
; =>
:A
:B
NIL
## Package `LOSH.DEBUGGING`
Utilities for figuring out what the hell is going on.
### `AESTHETIC-STRING` (function)
(AESTHETIC-STRING THING)
Return the string used to represent `thing` when printing aesthetically.
### `BITS` (function)
(BITS &OPTIONAL (N *) (SIZE 8) (STREAM T))
Print the bits of the `size`-bit two's complement integer `n` to `stream`.
Examples:
(bits 5 10)
=> 0000000101
(bits -5 10)
=> 1111111011
### `COMMENT` (macro)
(COMMENT
&BODY
BODY)
Do nothing with a bunch of forms.
Handy for block-commenting multiple expressions.
### `DIS` (macro)
(DIS
&BODY
BODY)
Disassemble the code generated for a `lambda` with `arglist` and `body`.
It will also spew compiler notes so you can see why the garbage box isn't
doing what you think it should be doing.
### `GIMME` (macro)
(GIMME N
&BODY
BODY)
### `HEX` (function)
(HEX &OPTIONAL (THING *) (STREAM T))
Print the `thing` to `stream` with numbers in base 16.
Examples:
(hex 255)
=> FF
(hex #(0 128))
=> #(0 80)
### `PHT` (function)
(PHT HASH-TABLE &OPTIONAL (STREAM T))
Synonym for `print-hash-table` for less typing at the REPL.
### `PR` (function)
(PR &REST ARGS)
Print `args` readably, separated by spaces and followed by a newline.
Returns the first argument, so you can just wrap it around a form without
interfering with the rest of the program.
This is what `print` should have been.
### `PRINT-HASH-TABLE` (function)
(PRINT-HASH-TABLE HASH-TABLE &OPTIONAL (STREAM T))
Print a pretty representation of `hash-table` to `stream.`
Respects `*print-length*` when printing the elements.
### `PRINT-HASH-TABLE-CONCISELY` (function)
(PRINT-HASH-TABLE-CONCISELY HASH-TABLE &OPTIONAL (STREAM T))
Print a concise representation of `hash-table` to `stream.`
Should respect `*print-length*` when printing the elements.
### `PRINT-TABLE` (function)
(PRINT-TABLE ROWS)
Print `rows` as a nicely-formatted table.
Each row should have the same number of colums.
Columns will be justified properly to fit the longest item in each one.
Example:
(print-table '((1 :red something)
(2 :green more)))
=>
1 | RED | SOMETHING
2 | GREEN | MORE
### `PRL` (macro)
(PRL &REST ARGS)
Print `args` labeled and readably.
Each argument form will be printed, then evaluated and the result printed.
One final newline will be printed after everything.
Returns the last result.
Examples:
(let ((i 1)
(l (list 1 2 3)))
(prl i (second l)))
; =>
i 1
(second l) 2
### `PROFILE` (macro)
(PROFILE
&BODY
BODY)
Profile `body` and dump the report to `lisp.prof`.
### `SHUT-UP` (macro)
(SHUT-UP
&BODY
BODY)
Run `body` with stdout and stderr redirected to the void.
### `START-PROFILING` (function)
(START-PROFILING &KEY CALL-COUNT-PACKAGES (MODE :CPU))
Start profiling performance. SBCL only.
`call-count-packages` should be a list of package designators. Functions in
these packages will have their call counts recorded via
`sb-sprof::profile-call-counts`.
### `STOP-PROFILING` (function)
(STOP-PROFILING &OPTIONAL (FILENAME lisp.prof))
Stop profiling performance and dump a report to `filename`. SBCL only.
### `STRUCTURAL-STRING` (function)
(STRUCTURAL-STRING THING)
Return the string used to represent `thing` when printing structurally.
## Package `LOSH.ELDRITCH-HORRORS`
Abandon all hope, ye who enter here.
### `DEFINE-WITH-MACRO` (macro)
(DEFINE-WITH-MACRO TYPE-AND-OPTIONS &REST SLOTS)
Define a with-`type` macro for the given `type` and `slots`.
This new macro wraps `with-accessors` so you don't have to type `type-`
a billion times.
The given `type` must be a symbol naming a struct or class. It must have the
appropriate accessors with names exactly of the form `type`-`slot`.
The defined macro will look something like this:
(define-with-macro foo a b)
=>
(defmacro with-foo ((foo &optional (a-symbol 'a) (b-symbol 'b))
&body body)
`(with-accessors ((,a-symbol foo-a) (,b-symbol foo-b))
,foo
,@body))
There's a lot of magic here, but it cuts down on boilerplate for simple things
quite a lot.
Example:
(defstruct foo x y)
(define-with-macro foo x y)
(defparameter *f* (make-foo :x 10 :y 20))
(defparameter *g* (make-foo :x 555 :y 999))
(with-foo (*f*)
(with-foo (*g* gx gy)
(print (list x y gx gy))))
=>
(10 20 555 999)
### `EVAL-DAMMIT` (macro)
(EVAL-DAMMIT
&BODY
BODY)
Just evaluate `body` all the time, jesus christ lisp.
## Package `LOSH.FUNCTIONS`
Utilities for working with higher-order functions.
## Package `LOSH.GNUPLOT`
Utilities for plotting data with gnuplot.
### `GNUPLOT` (function)
(GNUPLOT DATA &REST ARGS &KEY (X #'CAR) (Y #'CDR) (SPEW-OUTPUT NIL)
&ALLOW-OTHER-KEYS)
Plot `data` to `filename` with gnuplot.
This will (silently) quickload the `external-program` system to handle the
communication with gnuplot.
`data` should be a sequence of data points to plot.
`x` should be a function to pull the x-values from each item in data.
`y` should be a function to pull the y-values from each item in data.
See the docstring of `gnuplot-args` for other keyword arguments.
### `GNUPLOT-ARGS` (function)
(GNUPLOT-ARGS &KEY (OUTPUT :QT) (FILENAME plot.png) (STYLE :LINES)
(SIZE-X 1200) (SIZE-Y 800) (LABEL-X) (LABEL-Y)
(LINE-TITLE 'DATA) (LINE-WIDTH 4) (SMOOTH NIL) (AXIS-X NIL)
(AXIS-Y NIL) (MIN-X NIL) (MAX-X NIL) (MIN-Y NIL) (MAX-Y NIL)
(TICS-X NIL) (GRAPH-TITLE) (LOGSCALE-X NIL) (LOGSCALE-Y NIL)
(BOX-WIDTH NIL) &ALLOW-OTHER-KEYS)
Return the formatted command line arguments for the given gnuplot arguments.
You shouldn't call this function directly — it's exposed just so you can see
the list of possible gnuplot arguments all in one place.
### `GNUPLOT-EXPR` (macro)
(GNUPLOT-EXPR EXPR &REST ARGS)
Plot `expr` (an expression involving `x`) with gnuplot.
See the docstring of `gnuplot-args` for other keyword arguments.
### `GNUPLOT-FUNCTION` (function)
(GNUPLOT-FUNCTION FUNCTION &REST ARGS &KEY (START 0.0) (END 1.0) (STEP 0.1)
(INCLUDE-END NIL) &ALLOW-OTHER-KEYS)
Plot `function` over [`start`, `end`) by `step` with gnuplot.
If `include-end` is `t` the `end` value will also be plotted.
See the docstring of `gnuplot-args` for other keyword arguments.
### `GNUPLOT-HISTOGRAM` (function)
(GNUPLOT-HISTOGRAM DATA &KEY (BIN-WIDTH 1) SPEW-OUTPUT)
Plot `data` as a histogram with gnuplot.
`bin-width` should be the desired width of the bins. The bins will be
centered on multiples of this number, and data will be rounded to the nearest
bin.
## Package `LOSH.HASH-SETS`
Simple hash set implementation.
### `COPY-HASH-SET` (function)
(COPY-HASH-SET HSET)
Create a (shallow) copy of the given hash set.
Only the storage for the hash set itself will be copied -- the elements
themselves will not be copied.
### `HASH-SET` (struct)
Slots: `STORAGE`
### `HSET-CLEAR!` (function)
(HSET-CLEAR! HSET)
Remove all elements from `hset`.
Returns nothing.
### `HSET-CONTAINS-P` (function)
(HSET-CONTAINS-P HSET ELEMENT)
Return whether `hset` contains `element`.
### `HSET-COUNT` (function)
(HSET-COUNT HSET)
Return the number of elements in `hset`.
### `HSET-DIFFERENCE` (function)
(HSET-DIFFERENCE HSET &REST OTHERS)
Return a fresh hash set containing the difference of the given hash sets.
### `HSET-DIFFERENCE!` (function)
(HSET-DIFFERENCE! HSET &REST OTHERS)
Destructively update `hset` to contain the difference of itself with `others`.
### `HSET-ELEMENTS` (function)
(HSET-ELEMENTS HSET)
Return a fresh list containing the elements of `hset`.
### `HSET-EMPTY-P` (function)
(HSET-EMPTY-P HSET)
Return whether `hset` is empty.
### `HSET-FILTER` (function)
(HSET-FILTER HSET PREDICATE)
Return a fresh hash set containing elements of `hset` satisfying `predicate`.
### `HSET-FILTER!` (function)
(HSET-FILTER! HSET PREDICATE)
Destructively update `hset` to contain only elements satisfying `predicate`.
### `HSET-INSERT!` (function)
(HSET-INSERT! HSET &REST ELEMENTS)
Insert each element in `elements` into `hset`.
Returns nothing.
### `HSET-INTERSECTION` (function)
(HSET-INTERSECTION HSET &REST OTHERS)
Return a fresh hash set containing the intersection of the given hash sets.
### `HSET-INTERSECTION!` (function)
(HSET-INTERSECTION! HSET &REST OTHERS)
Destructively update `hset` to contain the intersection of itself with `others`.
### `HSET-MAP` (function)
(HSET-MAP HSET FUNCTION &KEY NEW-TEST)
Return a fresh hash set containing the results of calling `function` on elements of `hset`.
If `new-test` is given, the new hash set will use this as its `test`.
### `HSET-MAP!` (function)
(HSET-MAP! HSET FUNCTION &KEY NEW-TEST)
Destructively update `hset` by calling `function` on each element.
If `new-test` is given the hash set's `test` will be updated.
### `HSET-POP!` (function)
(HSET-POP! HSET)
Remove and return an arbitrarily-chosen element from `hset`.
An error will be signaled if the hash set is empty.
### `HSET-REDUCE` (function)
(HSET-REDUCE HSET FUNCTION &KEY (INITIAL-VALUE NIL IVP))
Reduce `function` over the elements of `hset`.
The order in which the elements are processed is undefined.
### `HSET-REMOVE!` (function)
(HSET-REMOVE! HSET &REST ELEMENTS)
Remove each element in `elements` from `hset`.
If an element is not in `hset`, it will be ignored.
Returns nothing.
### `HSET-UNION` (function)
(HSET-UNION HSET &REST OTHERS)
Return a fresh hash set containing the union of the given hash sets.
### `HSET-UNION!` (function)
(HSET-UNION! HSET &REST OTHERS)
Destructively update `hset` to contain the union of itself with `others`.
### `HSET=` (function)
(HSET= HSET &REST OTHERS)
Return whether all the given hash sets contain exactly the same elements.
All the hash sets are assumed to use the same `test` -- the consequences are
undefined if this is not the case.
### `MAKE-HASH-SET` (function)
(MAKE-HASH-SET &KEY (TEST 'EQL) (SIZE 16) (INITIAL-CONTENTS 'NIL))
Create a fresh hash set.
`size` should be a hint as to how many elements this set is expected to
contain.
`initial-contents` should be a sequence of initial elements for the set
(duplicates are fine).
## Package `LOSH.HASH-TABLES`
Utilities for operating on hash tables.
### `HASH-TABLE-CONTENTS` (function)
(HASH-TABLE-CONTENTS HASH-TABLE)
Return a fresh list of `(key value)` elements of `hash-table`.
### `MUTATE-HASH-VALUES` (function)
(MUTATE-HASH-VALUES FUNCTION HASH-TABLE)
Replace each value in `hash-table` with the result of calling `function` on it.
Returns the hash table.
## Package `LOSH.IO`
Utilities for input/output/reading/etc.
### `READ-ALL-FROM-FILE` (function)
(READ-ALL-FROM-FILE PATH)
Read all forms from the file at `path` and return them as a fresh list.
### `READ-ALL-FROM-STRING` (function)
(READ-ALL-FROM-STRING STRING)
Read all forms from `string` and return them as a fresh list.
## Package `LOSH.ITERATE`
Custom `iterate` drivers and clauses.
### `MACROEXPAND-ITERATE` (function)
(MACROEXPAND-ITERATE CLAUSE)
Macroexpand the given iterate clause/driver.
Example:
(macroexpand-iterate '(averaging (+ x 10) :into avg))
=>
(PROGN
(FOR #:COUNT630 :FROM 1)
(SUM (+ X 10) :INTO #:TOTAL631)
(FOR AVG = (/ #:TOTAL631 #:COUNT630)))
## Package `LOSH.LISTS`
Utilities for operating on lists.
### `SOMELIST` (function)
(SOMELIST PREDICATE LIST &REST MORE-LISTS)
Call `predicate` on successive sublists of `list`, returning the first true result.
`somelist` is to `some` as `maplist` is to `mapcar`.
## Package `LOSH.MATH`
Utilities related to math and numbers.
### `1/2TAU` (variable)
### `1/4TAU` (variable)
### `1/8TAU` (variable)
### `2/4TAU` (variable)
### `2/8TAU` (variable)
### `3/4TAU` (variable)
### `3/8TAU` (variable)
### `4/8TAU` (variable)
### `5/8TAU` (variable)
### `6/8TAU` (variable)
### `7/8TAU` (variable)
### `CLAMP` (function)
(CLAMP FROM TO VALUE)
Clamp `value` between `from` and `to`.
### `DEGREES` (function)
(DEGREES RADIANS)
Convert `radians` into degrees.
The result will be the same type as `tau` and `pi`.
### `DIGIT` (function)
(DIGIT POSITION INTEGER &OPTIONAL (BASE 10))
Return the value of the digit at `position` in `integer`.
Examples:
(digit 0 135) ; => 5
(digit 1 135) ; => 3
(digit 2 135) ; => 1
(digit 0 #xD4 16) ; => 4
(digit 1 #xD4 16) ; => 13
### `DIVIDESP` (function)
(DIVIDESP N DIVISOR)
Return whether `n` is evenly divisible by `divisor`.
The value returned will be the quotient when true, `nil` otherwise.
### `IN-RANGE-P` (function)
(IN-RANGE-P LOW VALUE HIGH)
Return whether `low` <= `value` < `high`.
### `LERP` (function)
(LERP FROM TO N)
Lerp together `from` and `to` by factor `n`.
You might want `precise-lerp` instead.
### `MAP-RANGE` (function)
(MAP-RANGE SOURCE-FROM SOURCE-TO DEST-FROM DEST-TO SOURCE-VAL)
Map `source-val` from the source range to the destination range.
Example:
; source dest value
(map-range 0.0 1.0 10.0 20.0 0.2)
=> 12.0
### `NORM` (function)
(NORM MIN MAX VAL)
Normalize `val` to a number between `0` and `1` (maybe).
If `val` is between `max` and `min`, the result will be a number between `0`
and `1`.
If `val` lies outside of the range, it'll be still be scaled and will end up
outside the 0/1 range.
### `PRECISE-LERP` (function)
(PRECISE-LERP FROM TO N)
Lerp together `from` and `to` by factor `n`, precisely.
Vanilla lerp does not guarantee `(lerp from to 0.0)` will return exactly
`from` due to floating-point errors. This version will return exactly `from`
when given a `n` of `0.0`, at the cost of an extra multiplication.
### `RADIANS` (function)
(RADIANS DEGREES)
Convert `degrees` into radians.
The result will be the same type as `tau` and `pi`.
### `SQUARE` (function)
(SQUARE X)
### `TAU` (variable)
### `TAU/2` (variable)
### `TAU/4` (variable)
### `TAU/8` (variable)
## Package `LOSH.MUTATION`
Utilities for mutating places in-place.
### `CALLF` (macro)
(CALLF &REST PLACE-FUNCTION-PAIRS)
Set each `place` to the result of calling `function` on its current value.
Examples:
(let ((x 10) (y 20))
(callf x #'1-
y #'1+)
(list x y))
=>
(9 21)
### `CLAMPF` (macro)
(CLAMPF PLACE FROM TO)
Clamp `place` between `from` and `to` in-place.
### `DIVF` (macro)
(DIVF PLACE &OPTIONAL DIVISOR)
Divide `place` by `divisor` in-place.
If `divisor` is not given, `place` will be set to `(/ 1 place)`.
### `MODF` (macro)
(MODF PLACE DIVISOR)
Modulo `place` by `divisor` in-place.
### `MULF` (macro)
(MULF PLACE FACTOR)
Multiply `place` by `factor` in-place.
### `NEGATEF` (macro)
(NEGATEF PLACE)
Negate the value of `place`.
### `NOTF` (macro)
(NOTF PLACE)
Set `place` to `(not place)` in-place.
### `REMAINDERF` (macro)
(REMAINDERF PLACE DIVISOR)
Remainder `place` by `divisor` in-place.
### `ZAPF` (macro)
(ZAPF &REST PLACE-EXPR-PAIRS)
Update each `place` by evaluating `expr` with `%` bound to the current value.
`zapf` works like `setf`, but when evaluating the value expressions the symbol
`%` will be bound to the current value of the place.
Examples:
(zapf foo (1+ %)
(car bar) (if (> % 10) :a :b))
## Package `LOSH.PRIORITY-QUEUES`
Jankass priority queue implementation.
### `MAKE-PRIORITY-QUEUE` (function)
(MAKE-PRIORITY-QUEUE &KEY (PRIORITY-PREDICATE #'<) (ELEMENT-TEST #'EQL))
Create and return a fresh priority queue.
`priority-predicate` is the comparison function used to compare priorities,
and should be a `<`-like predicate.
`element-test` should be the equality predicate for elements.
### `PQ-DEQUEUE` (function)
(PQ-DEQUEUE PQ)
Remove and return the element in `pq` with the lowest-numbered priority.
If `pq` is empty `nil` will be returned.
A second value is also returned, which will be `t` if an element was present
or `nil` if the priority queue was empty.
### `PQ-ENSURE` (function)
(PQ-ENSURE PQ ELEMENT PRIORITY)
Ensure `element` is in `pq` with `priority`.
If `element` is already in `pq` its priority will be set to `priority`.
Otherwise it will be inserted as if by calling `pq-insert`.
Returns `pq` (which may have been modified).
### `PQ-INSERT` (function)
(PQ-INSERT PQ ELEMENT PRIORITY)
Insert `element` into `pq` with `priority`.
Returns `pq` (which has been modified).
### `PRIORITY-QUEUE` (struct)
Slots: `CONTENTS`, `PREDICATE`, `TEST`
## Package `LOSH.QUEUES`
A simple queue implementation.
### `DEQUEUE` (function)
(DEQUEUE QUEUE)
Dequeue an item from `queue` and return it.
### `ENQUEUE` (function)
(ENQUEUE ITEM QUEUE)
Enqueue `item` in `queue`, returning the new size of the queue.
### `MAKE-QUEUE` (function)
(MAKE-QUEUE)
Allocate and return a fresh queue.
### `QUEUE` (struct)
Slots: `CONTENTS`, `LAST`, `SIZE`
### `QUEUE-APPEND` (function)
(QUEUE-APPEND QUEUE LIST)
Enqueue each element of `list` in `queue` and return the queue's final size.
### `QUEUE-CONTENTS` (function)
(QUEUE-CONTENTS VALUE INSTANCE)
### `QUEUE-EMPTY-P` (function)
(QUEUE-EMPTY-P QUEUE)
Return whether `queue` is empty.
### `QUEUE-SIZE` (function)
(QUEUE-SIZE VALUE INSTANCE)
## Package `LOSH.RANDOM`
Utilities related to randomness.
### `D` (function)
(D N SIDES &OPTIONAL (PLUS 0))
Roll some dice.
Examples:
(d 1 4) ; rolls 1d4
(d 2 8) ; rolls 2d8
(d 1 10 -1) ; rolls 1d10-1
### `RANDOM-AROUND` (function)
(RANDOM-AROUND VALUE SPREAD &OPTIONAL (GENERATOR #'RANDOM))
Return a random number within `spread` of `value` (inclusive).
### `RANDOM-ELT` (function)
(RANDOM-ELT SEQ &OPTIONAL (GENERATOR #'RANDOM))
Return a random element of `seq`, and whether one was available.
This will NOT be efficient for lists.
Examples:
(random-elt #(1 2 3))
=> 1
T
(random-elt nil)
=> nil
nil
### `RANDOM-GAUSSIAN` (function)
(RANDOM-GAUSSIAN MEAN STANDARD-DEVIATION &OPTIONAL (GENERATOR #'RANDOM))
Return a random float from a gaussian distribution. NOT THREAD-SAFE (yet)!
### `RANDOM-GAUSSIAN-INTEGER` (function)
(RANDOM-GAUSSIAN-INTEGER MEAN STANDARD-DEVIATION &OPTIONAL
(GENERATOR #'RANDOM))
Return a random integer from a gaussian distribution. NOT THREAD-SAFE (yet)!
### `RANDOM-RANGE` (function)
(RANDOM-RANGE MIN MAX &OPTIONAL (GENERATOR #'RANDOM))
Return a random number in [`min`, `max`).
### `RANDOM-RANGE-EXCLUSIVE` (function)
(RANDOM-RANGE-EXCLUSIVE MIN MAX &OPTIONAL (GENERATOR #'RANDOM))
Return a random number in (`min`, `max`).
### `RANDOM-RANGE-INCLUSIVE` (function)
(RANDOM-RANGE-INCLUSIVE MIN MAX &OPTIONAL (GENERATOR #'RANDOM))
Return a random number in [`min`, `max`].
### `RANDOMP` (function)
(RANDOMP &OPTIONAL (CHANCE 0.5) (GENERATOR #'RANDOM))
Return a random boolean with `chance` probability of `t`.
## Package `LOSH.SEQUENCES`
Utilities for operating on sequences.
### `DOSEQ` (macro)
(DOSEQ (VAR SEQUENCE)
&BODY
BODY)
Perform `body` with `var` bound to each element in `sequence` in turn.
It's like `cl:dolist`, but for all sequences.
### `DROP` (function)
(DROP N SEQ)
Return a fresh copy of the `seq` without the first `n` elements.
The result will be of the same type as `seq`.
If `seq` is shorter than `n` an empty sequence will be returned.
Example:
(drop 2 '(a b c))
=> (c)
(drop 4 #(1))
=> #()
From Serapeum.
### `DROP-WHILE` (function)
(DROP-WHILE PREDICATE SEQ)
Drop elements from `seq` as long as `predicate` remains true.
The result will be a fresh sequence of the same type as `seq`.
Example:
(drop-while #'evenp '(2 4 5 6 7 8))
; => (5 6 7 8)
(drop-while #'evenp #(2))
; => #(2)
### `ENUMERATE` (function)
(ENUMERATE SEQUENCE &KEY (START 0) (STEP 1) KEY)
Return an alist of `(n . element)` for each element of `sequence`.
`start` and `step` control the values generated for `n`, NOT which elements of
the sequence are enumerated.
Examples:
(enumerate '(a b c))
; => ((0 . A) (1 . B) (2 . C))
(enumerate '(a b c) :start 1)
; => ((1 . A) (2 . B) (3 . C))
(enumerate '(a b c) :key #'ensure-keyword)
; => ((0 . :A) (1 . :B) (2 . :C))
### `EXTREMA` (function)
(EXTREMA PREDICATE SEQUENCE)
Return the smallest and largest elements of `sequence` according to `predicate`.
`predicate` should be a strict ordering predicate (e.g. `<`).
Returns the smallest and largest elements in the sequence as two values,
respectively.
### `FREQUENCIES` (function)
(FREQUENCIES SEQUENCE &KEY (TEST 'EQL))
Return a hash table containing the frequencies of the items in `sequence`.
Uses `test` for the `:test` of the hash table.
Example:
(frequencies '(foo foo bar))
=> {foo 2
bar 1}
### `GROUP-BY` (function)
(GROUP-BY FUNCTION SEQUENCE &KEY (TEST #'EQL) (KEY #'IDENTITY))
Return a hash table of the elements of `sequence` grouped by `function`.
This function groups the elements of `sequence` into buckets. The bucket for
an element is determined by calling `function` on it.
The result is a hash table (with test `test`) whose keys are the bucket
identifiers and whose values are lists of the elements in each bucket. The
order of these lists is unspecified.
If `key` is given it will be called on each element before passing it to
`function` to produce the bucket identifier. This does not effect what is
stored in the lists.
Examples:
(defparameter *items* '((1 foo) (1 bar) (2 cats) (3 cats)))
(group-by #'first *items*)
; => { 1 ((1 foo) (1 bar))
; 2 ((2 cats))
; 3 ((3 cats)) }
(group-by #'second *items*)
; => { foo ((1 foo))
; bar ((1 bar))
; cats ((2 cats) (3 cats)) }
(group-by #'evenp *items* :key #'first)
; => { t ((2 cats))
; nil ((1 foo) (1 bar) (3 cats)) }
### `PREFIX-SUMS` (function)
(PREFIX-SUMS SEQUENCE)
Return a list of the prefix sums of the numbers in `sequence`.
Example:
(prefix-sums '(10 10 10 0 1))
=> (10 20 30 30 31)
### `PRODUCT` (function)
(PRODUCT SEQUENCE &KEY KEY)
Return the product of all elements of `sequence`.
If `key` is given, it will be called on each element to compute the
multiplicand.
Examples:
(product #(1 2 3))
; => 6
(product '("1" "2" "3") :key #'parse-integer)
; => 6
(product '("1" "2" "3") :key #'length)
; => 1
### `PROPORTIONS` (function)
(PROPORTIONS SEQUENCE &KEY (TEST 'EQL) (FLOAT T))
Return a hash table containing the proportions of the items in `sequence`.
Uses `test` for the `:test` of the hash table.
If `float` is `t` the hash table values will be coerced to floats, otherwise
they will be left as rationals.
Example:
(proportions '(foo foo bar))
=> {foo 0.66666
bar 0.33333}
(proportions '(foo foo bar) :float nil)
=> {foo 2/3
bar 1/3}
### `SUMMATION` (function)
(SUMMATION SEQUENCE &KEY KEY)
Return the sum of all elements of `sequence`.
If `key` is given, it will be called on each element to compute the addend.
This function's ugly name was chosen so it wouldn't clash with iterate's `sum`
symbol. Sorry.
Examples:
(sum #(1 2 3))
; => 6
(sum '("1" "2" "3") :key #'parse-integer)
; => 6
(sum '("1" "2" "3") :key #'length)
; => 3
### `TAKE` (function)
(TAKE N SEQ)
Return a fresh sequence of the first `n` elements of `seq`.
The result will be of the same type as `seq`.
If `seq` is shorter than `n` a shorter result will be returned.
Example:
(take 2 '(a b c))
=> (a b)
(take 4 #(1))
=> #(1)
From Serapeum.
### `TAKE-WHILE` (function)
(TAKE-WHILE PREDICATE SEQ)
Take elements from `seq` as long as `predicate` remains true.
The result will be a fresh sequence of the same type as `seq`.
Example:
(take-while #'evenp '(2 4 5 6 7 8))
; => (2 4)
(take-while #'evenp #(1))
; => #()
## Package `LOSH.WEIGHTLISTS`
A simple data structure for choosing random items with weighted probabilities.
### `MAKE-WEIGHTLIST` (function)
(MAKE-WEIGHTLIST WEIGHTS-AND-ITEMS)
Make a weightlist of the given items and weights.
`weights-and-items` should be an alist of `(weight . item)` pairs.
Weights can be any `real` numbers. Weights of zero are fine, as long as at
least one of the weights is nonzero (otherwise there's nothing to choose).
### `WEIGHTLIST` (struct)
Slots: `WEIGHTS`, `SUMS`, `ITEMS`, `TOTAL`
### `WEIGHTLIST-ITEMS` (function)
(WEIGHTLIST-ITEMS VALUE INSTANCE)
### `WEIGHTLIST-RANDOM` (function)
(WEIGHTLIST-RANDOM WEIGHTLIST)
Return a random item from the weightlist, taking the weights into account.
### `WEIGHTLIST-WEIGHTS` (function)
(WEIGHTLIST-WEIGHTS VALUE INSTANCE)