aboutsummaryrefslogtreecommitdiff
path: root/doc/propspecs.rst
diff options
context:
space:
mode:
authorSean Whitton <spwhitton@spwhitton.name>2021-03-11 18:54:46 -0700
committerSean Whitton <spwhitton@spwhitton.name>2021-03-11 18:54:46 -0700
commit156a8196d754262b3c7e43a1c3f0073fed14a722 (patch)
tree38c1cadc430988f720286a1f5bda20dac85498a6 /doc/propspecs.rst
parentd38f9f862688eea931e833e50495f8c0f1c7c05d (diff)
downloadconsfigurator-156a8196d754262b3c7e43a1c3f0073fed14a722.tar.gz
update propspecs specification
Signed-off-by: Sean Whitton <spwhitton@spwhitton.name>
Diffstat (limited to 'doc/propspecs.rst')
-rw-r--r--doc/propspecs.rst97
1 files changed, 64 insertions, 33 deletions
diff --git a/doc/propspecs.rst b/doc/propspecs.rst
index 618909f..36160bb 100644
--- a/doc/propspecs.rst
+++ b/doc/propspecs.rst
@@ -1,16 +1,25 @@
Property application specifications ("propspecs")
=================================================
+If you understand the difference between propspecs and unevaluated propspecs
+well enough to be able to read and understand most of the uses of
+``DEFPROPLIST`` in Consfigurator's own source, then you can probably get away
+without working through this section of the manual. You can build your own
+propspecs by taking uses of ``DEFPROPLIST`` in Consfigurator's own source as
+models. What follows is mainly for those who want to implement new property
+combinators, though normal usage of Consfigurator should not require doing
+that.
+
Purposes
--------
Property application specifications are a domain-specific language which
enables
-- combining properties to make new properties, e.g. with ``DEFPROPLIST``; and
+1. combining properties to make new properties, e.g. with ``DEFPROPLIST``; and
-- representing the properties which are to be applied to a host in a form
- which can be serialised using the Lisp printer.
+2. representing the properties which are to be applied to a host in a form
+ which can be serialised using the Lisp printer.
Definitions
-----------
@@ -19,34 +28,53 @@ An *atomic property application* ("propapp") is a list satisfying the lambda
list ``(PROPERTY &rest ARGS)`` where ``PROPERTY`` is a symbol naming a
property and ``ARGS`` satisfies that property's lambda list. A *property
combinator* is a function which takes at least one propapp as one of its
-arguments and returns a single propapp, or a macro which takes at least one
-form which evaluates to a propapp as one of its arguments, and returns a form
-which evaluates to a single propapp. A *property application specification*
-("propspec") is
-
-i. a readably printable Lisp form;
-ii. containing propapps combined using property combinators;
-iii. containing no free variables except as bound by macro property
- combinators, i.e., such that its evaluation is not affected by any
- dynamic or lexical context;
-iv. associated with a list of ASDF systems, and such that
-v. evaluating the propspec produces an atomic property application which, when
- those ASDF systems are loaded, applies the propapps in accordance with the
- combinators.
-
-An *unevaluated property application specification* ("unevaluated propspec")
-is a list of Lisp forms which can be converted into a property application
-specification by
+arguments and returns a single propapp, or a macro which takes at least
+propapp as one of its arguments and returns an expression which yields a
+single propapp (in the return values of property combinators, often
+``PROPERTY`` will be a gensym). A *property application specification* is
+
+i. a readably printable Lisp expression, **P**, known as a *property
+ application specification expression*, which contains
+
+ a. propapps combined using property combinators; but
+
+ b. no free variables except as bound by macro property combinators, i.e.,
+ such that the evaluation of **P** would not be affected by any dynamic
+ or lexical context; where
+
+ c. evaluating **P** means an operation equivalent to quoting each propapp
+ occurring in **P**, and then passing the whole thing as the only
+ argument to ``EVAL``; and
+
+ii. a list of ASDF systems **S**; such that
+
+iii. evaluating **P** yields a propapp ``(PROPERTY &rest ARGS)``; such that
+
+iv. when each of **S** are loaded, calling ``PROPERTY`` with ``ARGS`` will
+ apply each of the propapps occurring in **P** in accordance with the
+ combinators occuring in **P**.
+
+We do not always cleanly distinguish between property application
+specifications and property application specification expressions, and the
+abbreviation "propspec" refers to both. It is usually clear from the context
+which is meant. Within Lisp they are easy to distinguish because property
+application specifications are CLOS objects, whereas property application
+specification expressions are just conses.
+
+An *unevaluated property application specification expression* ("unevaluated
+propspec") is a list of Lisp forms which can be converted into a property
+application specification expression by
i. replacing each argument in each propapp with the result of evaluating that
argument in the dynamic and lexical contexts in which the unevaluated
- propspec occurs.
+ propspec occurs; and
+
ii. wrapping a single property combinator which takes a variable number of
- arguments around the resulting list of Lisp forms, usually ``SEQUENCE`` or
- ``ALL-OF``.
+ arguments around the resulting list of Lisp forms, usually ``PROPSEQ`` or
+ ``EPROPSEQ``.
-That is, the arguments to propapps in an unevaluated propspecs are forms which
-will produce the arguments to the property, rather than those arguments
+That is, the arguments to propapps in unevaluated propspecs are forms which
+will produce the arguments to the properties, rather than those arguments
themselves. There is one special case: if the symbol naming the property ends
with the character ``.``, then the propapp is replaced with a new one
according to the following rules (the "dotted propapp rules"):
@@ -61,24 +89,27 @@ ii. the first argument is not evaluated if it is a list whose first element is
iii. the last argument is treated as an embedded unevaluated propspec, and is
recursively converted into a propspec according to the usual evaluation
- rules, where the surrounding combinator is ``ALL-OF``.
+ rules, where the surrounding combinator is ``EPROPSEQ``.
+
+The dotted propapp rules are implemented by ``DEFPROP`` and ``DEFPROPLIST``,
+which define a macro with the dotted name which performs the replacement.
Available combinators
---------------------
-``ALL-OF``
-~~~~~~~~~~
+``PROPSEQ``
+~~~~~~~~~~~
Function. Applies each of the propapps passed as arguments without stopping
if any of them signal a failed change. Semantically, the propapps are ordered
with respect to their ``:HOSTATTRS`` subroutines, but not with respect to
their ``:APPLY`` subroutines.
-``SEQUENCE``
+``EPROPSEQ``
~~~~~~~~~~~~
Function. Applies each of the propapps passed as arguments, stopping and
-signalling a failed change if any of the proapps signal a failed change.
+signalling a failed change if any of the propapps signal a failed change.
Semantically, each propapp implicitly depends upon the preceding propapps.
``UNAPPLY``
@@ -105,8 +136,8 @@ The elements of unevaluated propspecs are typically arguments to macros, such
that the context of evaluation for forms which produce the arguments to the
propapps is the context in which the call to the containing macro appears.
The single property combinator which will be wrapped around the list of forms
-depends on the macro. ``DEFHOST`` uses ``ALL-OF``, while ``DEFPROPLIST`` uses
-``SEQUENCE``.
+depends on the macro. ``DEFHOST`` uses ``PROPSEQ``, while ``DEFPROPLIST``
+uses ``EPROPSEQ``.
The dotted propapp rules are intended to make applications of properties like
``DEPLOYS``, ``DEPLOYS-THESE`` and ``CHROOT:DEBOOTSTRAPPED``, which take