The nytpu.lisp-utils Reference Manual

This is the nytpu.lisp-utils Reference Manual, version 0.0.0, generated automatically by Declt version 4.0 beta 2 "William Riker" on Mon Feb 26 17:27:42 2024 GMT+0.

Table of Contents


1 Introduction


2 Systems

The main system appears first, followed by any subsystem dependency.


2.1 nytpu.lisp-utils

A collection of miscellaneous standalone utility packages.

Author

nytpu <>

Home Page

https://git.sr.ht/~nytpu/nytpu.lisp-utils

Source Control

(GIT https://git.sr.ht/~nytpu/nytpu.lisp-utils)

License

MPL-2.0

Version

0.0.0

Source

nytpu.lisp-utils.asd.

Child Components

3 Files

Files are sorted by type and then listed depth-first from the systems components trees.


3.1 Lisp


3.1.1 nytpu.lisp-utils/nytpu.lisp-utils.asd

Source

nytpu.lisp-utils.asd.

Parent Component

nytpu.lisp-utils (system).

ASDF Systems

nytpu.lisp-utils.


3.1.2 nytpu.lisp-utils/bind.lisp

Source

nytpu.lisp-utils.asd.

Parent Component

nytpu.lisp-utils (system).

Packages

bind.

Public Interface

bind (macro).

Internals

3.1.3 nytpu.lisp-utils/dbc.lisp

Source

nytpu.lisp-utils.asd.

Parent Component

nytpu.lisp-utils (system).

Packages

dbc.

Public Interface
Internals

3.1.4 nytpu.lisp-utils/shorthand-lambdas.lisp

Source

nytpu.lisp-utils.asd.

Parent Component

nytpu.lisp-utils (system).

Packages

shorthand-lambdas.

Public Interface
Internals

3.1.5 nytpu.lisp-utils/comment-sexps.lisp

Source

nytpu.lisp-utils.asd.

Parent Component

nytpu.lisp-utils (system).

Packages

comment-sexps.

Public Interface

3.1.6 nytpu.lisp-utils/nytpu.lisp-utils.lisp

Dependencies
Source

nytpu.lisp-utils.asd.

Parent Component

nytpu.lisp-utils (system).

Packages

nytpu.lisp-utils.

Public Interface

enable-syntaxes (function).


4 Packages

Packages are listed by definition order.


4.1 comment-sexps

Source

comment-sexps.lisp.

Use List

common-lisp.

Public Interface

4.2 dbc

Design by Contract for Common Lisp

Source

dbc.lisp.

Use List

common-lisp.

Public Interface
Internals

4.3 bind

Source

bind.lisp.

Use List

common-lisp.

Public Interface

bind (macro).

Internals

4.4 nytpu.lisp-utils

Source

nytpu.lisp-utils.lisp.

Use List

common-lisp.

Public Interface

enable-syntaxes (function).


4.5 shorthand-lambdas

Source

shorthand-lambdas.lisp.

Use List

common-lisp.

Public Interface
Internals

5 Definitions

Definitions are sorted by export status, category, package, and then by lexicographic order.


5.1 Public Interface


5.1.1 Special variables

Special Variable: *check-contracts*

If NIL, disable contract checking. Disabling may substantially improve performance, but at expense of safety.

Package

dbc.

Source

dbc.lisp.


5.1.2 Macros

Macro: bind (bindings &body body)

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

Package

bind.

Source

bind.lisp.

Macro: defmethod-contract (name parameters contracts &body body)

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.

Package

dbc.

Source

dbc.lisp.

Macro: defun-contract (name parameters contracts &body body)

Equivalent to DEFUN, but accept a contract & documentation block (as described by MAKE-CONTRACT-BODY).

Package

dbc.

Source

dbc.lisp.

Macro: lambda-contract (parameters contracts &body body)

Equivalent to a LAMBDA, but accept a contract & documentation block.

Package

dbc.

Source

dbc.lisp.

Macro: typecheck (place typespec &optional description)

Equivalent to CHECK-TYPE but return T instead of NIL when no error.

Package

dbc.

Source

dbc.lisp.

Macro: with-contracts-disabled (&body body)
Package

dbc.

Source

dbc.lisp.

Macro: with-contracts-enabled (&body body)
Package

dbc.

Source

dbc.lisp.

Macro: with-postconditions (expr &body postcondition)

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

Package

dbc.

Source

dbc.lisp.


5.1.3 Ordinary functions

Function: commented-sexp-reader (stream char arg)

Read a commented s-expression: just read a form, discard it, and return no values.

Package

comment-sexps.

Source

comment-sexps.lisp.

Function: enable-comment-sexps (&optional copy-readtable)

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.

Package

comment-sexps.

Source

comment-sexps.lisp.

Function: enable-shorthand-lambdas (&optional copy-readtable)

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)

Package

shorthand-lambdas.

Source

shorthand-lambdas.lisp.

Function: enable-syntaxes ()

Enable all syntax extensions in the NYTPU.LISP-UTILS system, currently: SHORTHAND-LAMBDAS and COMMENT-SEXPS

Package

nytpu.lisp-utils.

Source

nytpu.lisp-utils.lisp.

Function: shorthand-lambda-reader (stream char)

Read a shorthand lambda: read one s-expression, wrap it in a lambda, and replace the arguments determined by $ and $num

Package

shorthand-lambdas.

Source

shorthand-lambdas.lisp.


5.1.4 Generic functions

Generic Reader: form (condition)
Package

dbc.

Methods
Reader Method: form ((condition contract-failure))
Source

dbc.lisp.

Target Slot

form.

Generic Reader: func (condition)
Package

dbc.

Methods
Reader Method: func ((condition contract-failure))
Source

dbc.lisp.

Target Slot

func.


5.1.5 Conditions

Condition: contract-failure

Raised when a contract fails

Package

dbc.

Source

dbc.lisp.

Direct superclasses

error.

Direct subclasses
Direct methods
Direct slots
Slot: form

The executing form that failed

Initform

(quote "(no contract form available)")

Initargs

:form

Readers

form.

Writers

This slot is read-only.

Slot: func
Initform

(quote nil)

Initargs

:func

Readers

func.

Writers

This slot is read-only.

Slot: %contract-type
Initform

(quote nil)

Initargs

:%contract-type

Condition: postcondition-failure

Raised when a postcondition fails

Package

dbc.

Source

dbc.lisp.

Direct superclasses

contract-failure.

Direct slots
Slot: %contract-type
Initform

(quote "postcondition")

Initargs

:%contract-type

Condition: precondition-failure

Raised when a precondition fails

Package

dbc.

Source

dbc.lisp.

Direct superclasses

contract-failure.

Direct slots
Slot: %contract-type
Initform

(quote "precondition")

Initargs

:%contract-type


5.2 Internals


5.2.1 Macros

Macro: with-last ((all-but-last last) list &body body)

Run BODY with the given variables bound to all but the last item in the list and the last item in the list.

Package

bind.

Source

bind.lisp.


5.2.2 Ordinary functions

Function: add-new-arg (args args-len)
Package

shorthand-lambdas.

Source

shorthand-lambdas.lisp.

Function: analyze-declarations (decls)

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.

Package

bind.

Source

bind.lisp.

Function: expand-contracts (contract-list &optional type condition)

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.

Package

dbc.

Source

dbc.lisp.

Function: find-binding-run (kind bindings)

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.

Package

bind.

Source

bind.lisp.

Function: get-binding-declarations (names decls)

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.

Package

bind.

Source

bind.lisp.

Function: get-binding-names (binding)

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.

Package

bind.

Source

bind.lisp.

Function: get-name-declarations (name decls)

Given a variable name and an alist of declarations, return all pairs from the alist whose CAR is EQL to NAME.

Package

bind.

Source

bind.lisp.

Function: make-contract-body (contracts body)

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

Package

dbc.

Source

dbc.lisp.

Function: match-binding-kind (binding)

Given a single BINDING, return the kind of binding it is as a keyword (see formal grammar in BIND’s docstring).

Package

bind.

Source

bind.lisp.

Function: replace-shorthand (form existing-args existing-args-len)

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.

Package

shorthand-lambdas.

Source

shorthand-lambdas.lisp.

Function: separate-declarations (body)

Given a list of body forms, return all the declarations in the order they’re given and the remaining body forms.

Package

bind.

Source

bind.lisp.

Function: transform-binding (binding &optional kind)

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.

Package

bind.

Source

bind.lisp.

Function: transform-bindings (bindings)

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.

Package

bind.

Source

bind.lisp.


Appendix A Indexes


A.1 Concepts


A.2 Functions

Jump to:   A   B   C   D   E   F   G   L   M   R   S   T   W  
Index Entry  Section

A
add-new-arg: Private ordinary functions
analyze-declarations: Private ordinary functions

B
bind: Public macros

C
commented-sexp-reader: Public ordinary functions

D
defmethod-contract: Public macros
defun-contract: Public macros

E
enable-comment-sexps: Public ordinary functions
enable-shorthand-lambdas: Public ordinary functions
enable-syntaxes: Public ordinary functions
expand-contracts: Private ordinary functions

F
find-binding-run: Private ordinary functions
form: Public generic functions
form: Public generic functions
func: Public generic functions
func: Public generic functions
Function, add-new-arg: Private ordinary functions
Function, analyze-declarations: Private ordinary functions
Function, commented-sexp-reader: Public ordinary functions
Function, enable-comment-sexps: Public ordinary functions
Function, enable-shorthand-lambdas: Public ordinary functions
Function, enable-syntaxes: Public ordinary functions
Function, expand-contracts: Private ordinary functions
Function, find-binding-run: Private ordinary functions
Function, get-binding-declarations: Private ordinary functions
Function, get-binding-names: Private ordinary functions
Function, get-name-declarations: Private ordinary functions
Function, make-contract-body: Private ordinary functions
Function, match-binding-kind: Private ordinary functions
Function, replace-shorthand: Private ordinary functions
Function, separate-declarations: Private ordinary functions
Function, shorthand-lambda-reader: Public ordinary functions
Function, transform-binding: Private ordinary functions
Function, transform-bindings: Private ordinary functions

G
Generic Function, form: Public generic functions
Generic Function, func: Public generic functions
get-binding-declarations: Private ordinary functions
get-binding-names: Private ordinary functions
get-name-declarations: Private ordinary functions

L
lambda-contract: Public macros

M
Macro, bind: Public macros
Macro, defmethod-contract: Public macros
Macro, defun-contract: Public macros
Macro, lambda-contract: Public macros
Macro, typecheck: Public macros
Macro, with-contracts-disabled: Public macros
Macro, with-contracts-enabled: Public macros
Macro, with-last: Private macros
Macro, with-postconditions: Public macros
make-contract-body: Private ordinary functions
match-binding-kind: Private ordinary functions
Method, form: Public generic functions
Method, func: Public generic functions

R
replace-shorthand: Private ordinary functions

S
separate-declarations: Private ordinary functions
shorthand-lambda-reader: Public ordinary functions

T
transform-binding: Private ordinary functions
transform-bindings: Private ordinary functions
typecheck: Public macros

W
with-contracts-disabled: Public macros
with-contracts-enabled: Public macros
with-last: Private macros
with-postconditions: Public macros


A.4 Data types

Jump to:   B   C   D   F   N   P   S  
Index Entry  Section

B
bind: The bind package
bind.lisp: The nytpu․lisp-utils/bind․lisp file

C
comment-sexps: The comment-sexps package
comment-sexps.lisp: The nytpu․lisp-utils/comment-sexps․lisp file
Condition, contract-failure: Public conditions
Condition, postcondition-failure: Public conditions
Condition, precondition-failure: Public conditions
contract-failure: Public conditions

D
dbc: The dbc package
dbc.lisp: The nytpu․lisp-utils/dbc․lisp file

F
File, bind.lisp: The nytpu․lisp-utils/bind․lisp file
File, comment-sexps.lisp: The nytpu․lisp-utils/comment-sexps․lisp file
File, dbc.lisp: The nytpu․lisp-utils/dbc․lisp file
File, nytpu.lisp-utils.asd: The nytpu․lisp-utils/nytpu․lisp-utils․asd file
File, nytpu.lisp-utils.lisp: The nytpu․lisp-utils/nytpu․lisp-utils․lisp file
File, shorthand-lambdas.lisp: The nytpu․lisp-utils/shorthand-lambdas․lisp file

N
nytpu.lisp-utils: The nytpu․lisp-utils system
nytpu.lisp-utils: The nytpu․lisp-utils package
nytpu.lisp-utils.asd: The nytpu․lisp-utils/nytpu․lisp-utils․asd file
nytpu.lisp-utils.lisp: The nytpu․lisp-utils/nytpu․lisp-utils․lisp file

P
Package, bind: The bind package
Package, comment-sexps: The comment-sexps package
Package, dbc: The dbc package
Package, nytpu.lisp-utils: The nytpu․lisp-utils package
Package, shorthand-lambdas: The shorthand-lambdas package
postcondition-failure: Public conditions
precondition-failure: Public conditions

S
shorthand-lambdas: The shorthand-lambdas package
shorthand-lambdas.lisp: The nytpu․lisp-utils/shorthand-lambdas․lisp file
System, nytpu.lisp-utils: The nytpu․lisp-utils system