This is the nytpu.lisp-utils Reference Manual, version 0.0.0, generated automatically by Declt version 4.0 beta 2 "William Riker" on Fri Sep 15 06:10:31 2023 GMT+0.
The main system appears first, followed by any subsystem dependency.
nytpu.lisp-utils
A collection of miscellaneous standalone utility packages.
nytpu <alex@nytpu.com>
(GIT https://git.sr.ht/~nytpu/nytpu.lisp-utils)
MPL-2.0
0.0.0
bind.lisp
(file).
dbc.lisp
(file).
shorthand-lambdas.lisp
(file).
comment-sexps.lisp
(file).
nytpu.lisp-utils.lisp
(file).
Files are sorted by type and then listed depth-first from the systems components trees.
nytpu.lisp-utils/nytpu.lisp-utils.asd
nytpu.lisp-utils/bind.lisp
nytpu.lisp-utils/dbc.lisp
nytpu.lisp-utils/shorthand-lambdas.lisp
nytpu.lisp-utils/comment-sexps.lisp
nytpu.lisp-utils/nytpu.lisp-utils.lisp
nytpu.lisp-utils/nytpu.lisp-utils.asd
nytpu.lisp-utils
(system).
nytpu.lisp-utils/bind.lisp
nytpu.lisp-utils
(system).
bind
.
bind
(macro).
analyze-declarations
(function).
find-binding-run
(function).
get-binding-declarations
(function).
get-binding-names
(function).
get-name-declarations
(function).
match-binding-kind
(function).
separate-declarations
(function).
transform-binding
(function).
transform-bindings
(function).
with-last
(macro).
nytpu.lisp-utils/dbc.lisp
nytpu.lisp-utils
(system).
dbc
.
*check-contracts*
(special variable).
contract-failure
(condition).
defmethod-contract
(macro).
defun-contract
(macro).
form
(reader method).
func
(reader method).
lambda-contract
(macro).
postcondition-failure
(condition).
precondition-failure
(condition).
typecheck
(macro).
with-contracts-disabled
(macro).
with-contracts-enabled
(macro).
with-postconditions
(macro).
expand-contracts
(function).
make-contract-body
(function).
nytpu.lisp-utils/shorthand-lambdas.lisp
nytpu.lisp-utils
(system).
enable-shorthand-lambdas
(function).
shorthand-lambda-reader
(function).
add-new-arg
(function).
replace-shorthand
(function).
nytpu.lisp-utils/comment-sexps.lisp
nytpu.lisp-utils
(system).
commented-sexp-reader
(function).
enable-comment-sexps
(function).
nytpu.lisp-utils/nytpu.lisp-utils.lisp
shorthand-lambdas.lisp
(file).
comment-sexps.lisp
(file).
nytpu.lisp-utils
(system).
enable-syntaxes
(function).
Packages are listed by definition order.
bind
common-lisp
.
bind
(macro).
analyze-declarations
(function).
find-binding-run
(function).
get-binding-declarations
(function).
get-binding-names
(function).
get-name-declarations
(function).
match-binding-kind
(function).
separate-declarations
(function).
transform-binding
(function).
transform-bindings
(function).
with-last
(macro).
dbc
Design by Contract for Common Lisp
common-lisp
.
*check-contracts*
(special variable).
contract-failure
(condition).
defmethod-contract
(macro).
defun-contract
(macro).
form
(generic reader).
func
(generic reader).
lambda-contract
(macro).
postcondition-failure
(condition).
precondition-failure
(condition).
typecheck
(macro).
with-contracts-disabled
(macro).
with-contracts-enabled
(macro).
with-postconditions
(macro).
expand-contracts
(function).
make-contract-body
(function).
comment-sexps
common-lisp
.
commented-sexp-reader
(function).
enable-comment-sexps
(function).
shorthand-lambdas
common-lisp
.
enable-shorthand-lambdas
(function).
shorthand-lambda-reader
(function).
add-new-arg
(function).
replace-shorthand
(function).
Definitions are sorted by export status, category, package, and then by lexicographic order.
If NIL, disable contract checking. Disabling may substantially improve performance, but at expense of safety.
Flexible lexical binding macro. Same structure as a LET/LET*, but allows
destructuring and multiple values, binding local functions like LABELS, and
calling arbitrary WITH-<> functions. Each later binding is nested in the scope
of earlier bindings, behaving like LET*.
The main syntax of BIND is identical to LET*, with symbols on their own or
alone in parentheses being bound to NIL, and symbols with a form are bound to
the result of that form. However, if a binding has multiple symbols in a row
with a final form, each symbol be bound to a multiple return value, as in
MULTIPLE-VALUE-BIND. Symbols wrapped in a list will have the result of form be
destructuted as in DESTRUCTURING-BIND. S-exps beginning with :WITH will be
wrapped around the BODY unmodified (other than the leading :WITH being
removed), to allow for using arbitrary binding-creating macros like
WITH-OPEN-FILE. S-exps beginning with :λ or :LAMBDA will be treated like
LABELS and the :λ should be followed by a name, lambda list, and body of the
lambda.
To hopefully slightly improve efficiency, BIND automatically condenses "runs"
of null/normal bindings into one LET*, and runs of lambdas into one LABELS.
All other bindings expand to repeatedly nested MULTIPLE-VALUE-BIND,
DESTRUCTURING-BIND, etc.; and those will break up what otherwise would’ve been
one LET* into multiple statements.
*Standard* DECLARE statements (i.e. specified in the CLHS) are handled
properly, and declarations referencing variables defined in the BIND are
"hoisted" to the correct scope where the variables are actually declared in
the macroexpansion—no matter what order they’re declared in or if they’re
consolidated into one declare statement. Note that nonstandard declarations
may or may not function properly.
Example usage:
(bind (; traditional LET-style bindings
a (b) ; null bindings that are bound to NIL
(c 1)
(d 2)
; multiple value bindings
(e f (values 3 4))
; later bindings can depend on earlier bindings, like LET*
(g h i (values (1+ f) 6 7))
; list destructuring
((j (k) l) ’(8 (9) 10))
; using arbitrary binding-creating macros
(:with with-output-to-string (str))
; binding lambdas
(:λ foo ()
(values (1+ l) (+ 2 l)))
(:lambda bar (&rest vals)
(format str "~{~a, ~}~{~a~^, ~}" vals (multiple-value-list (foo)))))
(bar a b c d e f g h i j k))
=> "NIL, NIL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12"
Here is a full description of the syntax:
; Full use of BIND. all BINDINGs will be visible in BODY
binding-form = ( "bind" ( binding* ) declaration* body* )
binding = null-binding | normal-binding | mv-binding | ds-binding | lambda-binding | accessors-binding | with-binding
; binds to NIL, as in a normal LET
null-binding = symbol | ( symbol )
; binds symbol to the result of evaluating FORM, as in a normal LET
normal-binding = ( symbol form )
; expands to (multiple-value-bind (symbol symbol+) form ...)
mv-binding = ( symbol symbol+ form )
; expands to (destructuring-bind (ds-lambda-list) form ...)
ds-binding = ( ( ds-lambda-list ) form )
; expands to (labels ((name (lambda-list) body*)) ...)
lamdba-binding = ( { ":lambda" | ":λ" } name ( lambda-list ) body* )
; expands to (with-accessors (accessor+) instance ...)
; note that unlike in WITH-ACCESSORS, accessor+ can actually be just one
; symbol rather than a (symbol accessor) pair, in which case it will be
; expanded to the full (symbol accessor) form like WITH-SLOTS does
accessors-binding = ( ":accessors" accessor+ instance )
; expands to (function-name params* ...)
; allows for use of arbitrary binding-creating macros.
with-binding = ( ":with" function-name params* )
Notes on the description of the grammar:
- () are literal parenthesis, not grouping
- {} are grouping operators
- + is one or more operator
- * is zero or more operator
- | is alternation operator
- quotes indicates literal text
- ... in comments indicates that the remainder of the body and other bindings
will be placed there.
- symbol means a symbol that could be bound with LET in the same context
- form means any evaluatable form
- lambda-list means a standard lambda list
- ds-lambda-list means a destructuring lambda list as described in the CLHS
- params means to any acceptable parameters to the given function-name
Heavily inspired by:
- Scott L. Burson’s "New Let":
https://gitlab.common-lisp.net/misc-extensions/devel/-/blob/master/src/new-let.lisp
- Ron Garret’s BINDING-BLOCK:
https://github.com/rongarret/ergolib/blob/master/core/binding-block.lisp
(readers will note that it’s basically just features from the above macros but
in a syntax I personally prefer, and also not shadowing stuff from COMMON-LISP).
Equivalent to DEFMETHOD, but accept a contract & documentation block. Note that this defines contracts for ONLY this implementation of the generic method—to use Ada 2012 terms, the contracts defined here are Pre and Post, not Pre’Class and Post’Class.
Equivalent to DEFUN, but accept a contract & documentation block (as described by MAKE-CONTRACT-BODY).
Equivalent to a LAMBDA, but accept a contract & documentation block.
Equivalent to CHECK-TYPE but return T instead of NIL when no error.
Given an expression EXPR and a body, evaluate EXPR and bind it to the %
variable. Run the POSTCONDITION expressions in the scope of the % variable and
ensure none of them return NIL; raising CONTRACT-FAILURE if they do. If all
postconditions succeed, return %.
Each individual contract is wrapped in a SKIP-CONTRACT restart, and all the
postconditions are wrapped in a SKIP-POSTCONDITIONS restart.
Supports multiple values, if the expression returns multiple then % will be
bound to a list as from MULTIPLE-VALUES-LIST. The original multiple values as
from VALUES-LIST will be returned after the postconditions.
(with-postconditions
(numberfier "1")
(typep % ’number)
(= % 1))
Read a commented s-expression: just read a form, discard it, and return no values.
Enable the #; reader macro character to comment a full s-expression. If COPY-READTABLE is T, then *READTABLE* will be copied with COPY-READTABLE before adding the reader macro.
When enabled, prefixing any form (s-expression or atom) with #; will comment it out. Note that the form must be valid according to the reader (albiet with *READ-SUPPRESS* true), but is otherwise not parsed in any way.
Enable the ^ reader macro character for shorthand lambdas in the current readtable. If COPY-READTABLE is T, then *READTABLE* will be copied with COPY-READTABLE before adding the reader macro.
When enabled, prefixing a form with ^ will implicitly wrap it in a LAMBDA, i.e. ^(...) → (lambda () ...). Inside that form, an $ symbol will insert a new argument. A symbol of format $number will (re)use that argument (arguments are one-indexed). A numbered argument must be either one past the newest argument which introduces a new argument, or an existing argument.
Examples:
(^(+ $ $) 2 2)
; → 4
(mapcar ^(+ $1 $1) ’(1 2 3 4)) and (mapcar ^(+ $ $1) ’(1 2 3 4))
; → (2 4 6 8)
(^(list $ $ ’c $ $2 $1) ’a ’b ’d)
; → (a b c d b a)
Enable all syntax extensions in the NYTPU.LISP-UTILS system, currently: SHORTHAND-LAMBDAS and COMMENT-SEXPS
Read a shorthand lambda: read one s-expression, wrap it in a lambda, and replace the arguments determined by $ and $num
dbc
.
contract-failure
)) ¶dbc
.
contract-failure
)) ¶Raised when a contract fails
dbc
.
error
.
The executing form that failed
(quote "(no contract form available)")
:form
form
.
This slot is read-only.
(quote nil)
:%contract-type
Raised when a postcondition fails
Raised when a precondition fails
Run BODY with the given variables bound to all but the last item in the list and the last item in the list.
Return an alist associating variable names with a declaration acting on that variable name, and a list of "free" declarations that don’t affect any variable.
Given a list of contract forms in CONTRACT-LIST, return a list of forms
designed to raise a CONTRACT-FAILURE error if the form returns NIL when
executed. TYPE is used to describe what kind of contract failed (i.e.
"precondition" or "postcondition"). Also wraps each contract in a
SKIP-CONTRACT restart.
Does not respect *CHECK-CONTRACTS*, you should wrap the forms returned by EXPAND-CONTRACTS in a (WHEN *CHECK-CONTRACTS* ...) form.
Given a KIND as from MATCH-BINDING-KIND and a list of BINDINGS, return a list of bindings that are a consecutive run of KIND operated on with TRANSFORM-BINDING; and then returns the remaining bindings after that consecutive run. If the first value is NIL—i.e. there are no consecutive bindings—then the second value will simply be BINDINGS.
Given a list of variable names as from GET-BINDING-NAMES and an alist of declarations as from ANALYZE-DECLARATIONS, return a list of declarations that apply to members of that run, mutated into proper declaration form (i.e. the variable name is appended) and a list of the plain original alist pairs from DECLS.
Given a single transformed binding as from TRANSFORM-BINDINGS, return a list of all variable names declared in that binding. **Does not support :WITH-BINDING** and always returns NIL, those are considered opaque macros and are not analyzed.
Given a variable name and an alist of declarations, return all pairs from the alist whose CAR is EQL to NAME.
Generate the body of a function given a contracts form and a list of body
forms. Tries to generate efficient code by not evaluating stuff such as
WITH-POSTCONDITIONS unless it’s necessary.
The contracts form is akin to an association list, but using lists rather than
dotted pairs for the items in it. It can contain any (including none) of the
following:
- ":pre" followed by a list of precondition forms, typically used to verify
parameters and state are as expected. Preconditions all have a
SKIP-CONDITION restart around them, and the precondition block has a
SKIP-PRECONDITIONS restart.
- ":post" followed by a list of postcondition forms. Equivalent to wrapping
all the body forms in a WITH-POSTCONDITIONS macro.
- ":documentation" followed by a docstring. Equivalent to the standard
function docstring.
- ":declarations" followed by a list of DECLARE expressions
Given a single BINDING, return the kind of binding it is as a keyword (see formal grammar in BIND’s docstring).
Given a FORM, list of existing arguments, and optionally the length of EXISTING-ARGS, parse if FORM is a dollar sign shorthand argument ($ or $x). Recursively applies itself to any sublists in FORM and returns *all* accumulated arguments and the proper length.
Returns three values:
- A new GENSYM’d symbol if it is a shorthand argument or FORM itself otherwise.
- The EXISTING-ARGS list, with the GENSYM’d symbol added on front if it is a shorthand argument.
- The length of the returned list whether or not it had a symbol added.
Given a list of body forms, return all the declarations in the order they’re given and the remaining body forms.
Given a BINDING and optionally its precomputed KIND, transform it to the "native" form taken by that BINDING’s lower-level macro, e.g. the parameters to LET* or LABELS.
Given a list of bindigns as given to BIND, transform them with TRANSFORM-BINDING and condense runs as necessary, then return the list in reverse order with each sublist prefixed by their kind as from MATCH-BINDING-KIND.
Jump to: | A B C D E F G L M R S T W |
---|
Jump to: | A B C D E F G L M R S T W |
---|
Jump to: | %
*
F S |
---|
Jump to: | %
*
F S |
---|
Jump to: | B C D F N P S |
---|
Jump to: | B C D F N P S |
---|