Property combinators
====================

API reference
-------------

Property combinators
~~~~~~~~~~~~~~~~~~~~

Macro: ``DEFINE-FUNCTION-PROPERTY-COMBINATOR``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(define-function-property-combinator name args &body body)``

Define a function property combinator NAME with lambda list ARGS.

Usage notes:

- If you need to read individual arguments to propapps passed as arguments to
  NAME, call PROPAPP-ARGS to access them.  For passing a whole list of args on
  to a property subroutine, just take the cdr of the propapp.

  For an example showing both techniques at work, see POSTFIX:MAPPED-FILE.

Macro: ``DEFINE-CHOOSING-PROPERTY-COMBINATOR``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(define-choosing-property-combinator name lambda-list &key type choose)``

Fn. prop. combinator: ``ESEQPROPS``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(eseqprops &rest propapps)``

Fn. prop. combinator: ``ESEQPROPS-UNTIL``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(eseqprops-until condition &rest propapps)``

Like ESEQPROPS, but if CONDITION is signalled, handle it simply by skipping
remaining elements of PROPAPPS.  CONDITION usually names a subclass of
FAILED-CHANGE.

Fn. prop. combinator: ``SEQPROPS``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(seqprops &rest propapps)``

Fn. prop. combinator: ``SILENT-SEQPROPS``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(silent-seqprops &rest propapps)``

Macro: ``UNAPPLY``
^^^^^^^^^^^^^^^^^^

``(unapply form)``

Where FORM is a programmatic application of a property (i.e. an application
of a property directly inside an :APPLY or :UNAPPLY subroutine), unapply the
property instead of applying it.

Fn. prop. combinator: ``UNAPPLIED``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(unapplied propapp)``

Fn. prop. combinator: ``REAPPLIED``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(reapplied propapp)``

Fn. prop. combinator: ``DESC``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(desc desc propapp)``

Macro: ``ON-CHANGE``
^^^^^^^^^^^^^^^^^^^^

``(on-change propapp &body on-change)``

If applying or unapplying PROPAPP makes a change, also apply each of the
propapps ON-CHANGE in order.

Macro: ``ON-APPLY-CHANGE``
^^^^^^^^^^^^^^^^^^^^^^^^^^

``(on-apply-change propapp &body on-change)``

If applying PROPAPP makes a change, also apply each of the propapps ON-CHANGE
in order.

Macro: ``AS``
^^^^^^^^^^^^^

``(as user &body properties)``

Apply PROPERTIES as USER by reconnecting with the :AS connection type.
Note that the :AS connection type requires root, so as a special case, this
macro just expands to ESEQPROPS if USER is the literal string "root"
(without evaluation).  This makes it possible to use this macro to annotate
applications of properties which are normally applied by non-root, to make it
explicit that in this case they're being applied as root, e.g. that they will
affect /root and not /home.

Macro: ``WITH-FLAGFILE``
^^^^^^^^^^^^^^^^^^^^^^^^

``(with-flagfile flagfile &body propapps)``

Apply PROPAPPS unless FLAGFILE exists on the remote; after applying, create
FLAGFILE.
Useful to ensure that something is done just once.  Has the semantics that if
FLAGFILE exists, PROPAPPS are assumed to all be already applied.

Fn. prop. combinator: ``WITH-UNAPPLY``
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

``(with-unapply &rest propapps)``

As ESEQPROPS, except that if :UNAPPLY appears in PROPAPPS, then return a
property which applies the elements of PROPAPPS prior to :UNAPPLY, but which
when unapplied ignores the elements of PROPAPPS prior to :UNAPPLY, and instead
applies the elements of PROPAPPS appearing after :UNAPPLY.

Analogously to how DEFPROPLIST/DEFPROPSPEC allow you to define a property
which works by calling other properties, this combinator allows you to define
an :UNAPPLY subroutine for a property which works by calling other properties.

Macro: ``WITH-HOMEDIR``
^^^^^^^^^^^^^^^^^^^^^^^

``(with-homedir &key &body propapps)``

Apply PROPAPPS with a different home and initial working directory, either
DIR or the home directory of USER.
