Permalink
Switch branches/tags
Nothing to show
Find file Copy path
Fetching contributors…
Cannot retrieve contributors at this time
2008 lines (1093 sloc) 40.9 KB

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-macroleted 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)