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