The method-combination-utilities Reference Manual

Table of Contents

Next: , Previous: , Up: (dir)   [Contents][Index]

The method-combination-utilities Reference Manual

This is the method-combination-utilities Reference Manual, generated automatically by Declt version 2.3 "Robert April" on Wed Mar 14 04:18:32 2018 GMT+0.


Next: , Previous: , Up: Top   [Contents][Index]

1 Introduction

Method combinations are one of the more obscure bits of Common Lisp. I think they're pretty fantastic and should be understood and used by more developers. This library is an attempt to provide some tools to aid in defining new method combinations as well as a few simple combinations that may be generally useful.

(METHOD-COMBINATION-EXPAND form)

This macro is to method combinations what MACROEXPAND is to macros. Given a function call form, it'll expand to the form used to call the methods.

For example, given:

(defgeneric print-slots (object)
  (:method-combination basic progn t)
  (:method progn ((object superclass)) ...)
  (:method progn ((object subclass)) ...))

(pprint (method-combination-expand (print-slots subclass-instance)))

the result should look something like:

(PROGN (CALL-METHOD #<STANDARD-METHOD PRINT-SLOTS PROGN (SUBCLASS)>)
       (CALL-METHOD #<STANDARD-METHOD PRINT-SLOTS PROGN (SUPERCLASS)>))

This can be extremely helpful both for users of method combinations and developers of them.

Definition Helpers

(CALL-METHODS methods)

This is FLETed (or expanded in-line) in almost all method combinations, including every DEFINE-METHOD-COMBINATION example in the spec. The name isn't the best, but it has a strong tradition.

This function just returns a list of CALL-METHOD forms, one for each method passed in. EG:

(call-methods '(1 2 3))
=> ((CALL-METHOD 1) (CALL-METHOD 2) (CALL-METHOD 3))

(COMBINE-STANDARD-METHODS primary-methods &optional around-methods before-methods after-methods)

In a lot of custom method combinations there is some attempt to keep the behavior of the STANDARD method combination. This function manages that portion of the method combination so other components can be layered on top.

This example converts the 55-line WRAPPING-STANDARD method combination from arnesi into a much cleaner 17-line version.

(define-method-combination wrapping-standard
    (&key (wrap-around-order :most-specific-last)
          (around-order :most-specific-first)
          (before-order :most-specific-first)
          (wrapping-order :most-specific-last)
          (primary-order :most-specific-first)
          (after-order :most-specific-last))
  ((wrap-around (:wrap-around) :order wrap-around-order)
   (around (:around) :order around-order)
   (before (:before) :order before-order)
   (wrapping (:wrapping) :order wrapping-order)
   (primary () :order primary-order :required t)
   (after (:after) :order after-order))
  "Same semantics as standard method combination but allows \"wrapping\"
   methods. Ordering of methods:

  (wrap-around
    (around
      (before)
      (wrapping
        (primary))
      (after)))

  :wrap-around and :wrapping methods can use call-next-method."
  ;; :WRAP-AROUND is similar to :AROUND and :WRAPPING is similar to primary, so
  ;; each pair can be concatenated and then we can just apply the standard
  ;; combination.
  (combine-standard-methods (append wrapping primary)
                            (append wrap-around around)
                            before
                            after))

(WRAP-PRIMARY-FORM primary-form &optional around-methods before-methods after-methods)

This is similar to COMBINE-STANDARD-METHODS, but it takes an already-computed primary form, rather than a list of primary methods. This is because it's fairly common to have some custom behavior for the primary methods and then combine it with the usual :AROUND/:BEFORE/:AFTER methods.

This example is simplified from pretty much the entire nisp-standard-combination.lisp file from the nisp project. Note that (based on the pathname), this combination (or at least the version I linked to) is probably obsolete.

(define-method-combination nisp-standard (&key hook)
  ((defaulting (:defaulting) :order :most-specific-last)
   (meta-around (:meta-around))
   (around (:around))
   (before (:before))
   (primary () :required t)
   (after (:after) :order :most-specific-last))
  "This behaves similarly to `STANDARD`, but wraps the whole thing with
  :DEFAULTING (most-recent-last) and :META-AROUND methods. Also, if a HOOK is
   passed, the primary methods are treated as in the BASIC combination, with
   HOOK as the operator.

  (defaulting
    (meta-around
      (around
        (before)
        (primary)
        (after))))"
  (wrap-primary-form (if hook
                         `(,hook ,@(call-methods primary))
                         `(call-method ,(first primary) ,(rest primary)))
                     (append defaulting meta-around around)
                     before
                     after))

Method Combinations

(PRIMARY)

The PRIMARY method combination is a stripped-down version of the STANDARD method combination that only allows primary methods. Taken from ISLISP’s NIL method combination (but renamed because CLs with package locks don't like it) after it was suggested by Pascal Costanza.

(LAX)

The LAX method combination is intended for use in cases where you are handling your qualifiers in a custom method class and don't really need a custom method combination, but you need the STANDARD method combination to quietly ignore your special qualifiers. (a la Closer’s Filtered Functions)

(BASIC operator &optional identity-with-one-argument-p order)

The intent of the BASIC method combination is to obviate the need for the short form of DEFINE-METHOD-COMBINATION. With this method combination, you have the same functionality but without having to define the method combination separately from where it's used.

Of course, I've never actually seen any code that uses the short form of DEFINE-METHOD-COMBINATION (and I've looked). However, since all the (non-STANDARD) built-in method combinations behave as if they were created using the short form, this also acts as a proposal for any updates to Common Lisp – rather than having ten built-in combinations (four of which I have never seen used), have only two: STANDARD and BASIC, and eliminate the short form of DEFINE-METHOD-COMBINATION.

For example, the built-in + combination can be replicated with (basic + t).

(APPEND/NCONC &optional order)

Using either the built-in APPEND or NCONC combinations (or those functions as the operator for the BASIC combination) misses something important. NCONC is largely a non-consing optimization of APPEND (if you are somehow using the method combination to make circular structures or something, then the built-in NCONC is probably a better bet). If you use the built-in combinations, then every method on your function needs to share the same qualifier, say, APPEND. If you later decide that it is safe to use NCONC, then you need to change the combination on the generic function and change all of your methods – and hope that no users of your library have added additional APPEND methods to the function.

The APPEND/NCONC combination, however, allows the use of either qualifier. Methods that return a list safe to be RPLACDed can use the NCONC qualifier, while those that don't can use APPEND. If all but the last applicable primary method (most- or least-specific, depending on the ORDER parameter) use the NCONC qualifier, than the results will be concatenated with NCONC, otherwise it will use APPEND.

This allows the optimization to be added on a case-by-case basis and the gains to be had where possible, without tying users to your specific implementation de


Next: , Previous: , Up: Top   [Contents][Index]

2 Systems

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


Previous: , Up: Systems   [Contents][Index]

2.1 method-combination-utilities

Author

Greg Pfeil <greg@technomadic.org>

License

MIT

Description

Various method combinations and utilities to make it easy to create new method combinations.

Long Description

See README.md

Dependency

closer-mop

Source

method-combination-utilities.asd (file)

Components

Next: , Previous: , Up: Top   [Contents][Index]

3 Files

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


Previous: , Up: Files   [Contents][Index]

3.1 Lisp


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.1 method-combination-utilities.asd

Location

/home/quickbuilder/quicklisp/dists/quicklisp/software/method-combination-utilities-20141106-git/method-combination-utilities.asd

Systems

method-combination-utilities (system)

Packages

method-combination-utilities.system


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.2 method-combination-utilities/package.lisp

Parent

method-combination-utilities (system)

Location

package.lisp

Packages

method-combination-utilities


Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.3 method-combination-utilities/definition-helpers.lisp

Dependency

package.lisp (file)

Parent

method-combination-utilities (system)

Location

definition-helpers.lisp

Exported Definitions

Next: , Previous: , Up: Lisp files   [Contents][Index]

3.1.4 method-combination-utilities/method-combinations.lisp

Dependency

package.lisp (file)

Parent

method-combination-utilities (system)

Location

method-combinations.lisp

Exported Definitions

Previous: , Up: Lisp files   [Contents][Index]

3.1.5 method-combination-utilities/method-combination-expand.lisp

Dependency

package.lisp (file)

Parent

method-combination-utilities (system)

Location

method-combination-expand.lisp

Exported Definitions

method-combination-expand (macro)

Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

4 Packages

Packages are listed by definition order.


Next: , Previous: , Up: Packages   [Contents][Index]

4.1 method-combination-utilities.system

Source

/home/quickbuilder/quicklisp/dists/quicklisp/software/method-combination-utilities-20141106-git/method-combination-utilities.asd

Use List

Previous: , Up: Packages   [Contents][Index]

4.2 method-combination-utilities

Source

package.lisp (file)

Use List
Exported Definitions
Internal Definitions

Next: , Previous: , Up: Top   [Contents][Index]

5 Definitions

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


Next: , Previous: , Up: Definitions   [Contents][Index]

5.1 Exported definitions


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.1 Macros

Macro: method-combination-expand FORM

Given a function call form, this returns the method-combination form that would be generated in the process of satisfying that call. This is only expected to work for functions whose method-combination was created using the long form of DEFINE-METHOD-COMBINATION.

Package

method-combination-utilities

Source

method-combination-expand.lisp (file)


Next: , Previous: , Up: Exported definitions   [Contents][Index]

5.1.2 Functions

Function: call-methods METHODS

It’s rare to see a method combination that doesn’t define this method, so might as well pull it into this utilities package. CALL-METHODS returns a list of CALL-METHOD forms; one for each method in METHODS

Package

method-combination-utilities

Source

definition-helpers.lisp (file)

Function: combine-standard-methods PRIMARY-METHODS &optional AROUND-METHODS BEFORE-METHODS AFTER-METHODS

It is fairly common practice to take the STANDARD method combination and wrap it with additional qualified methods. This encapsulates the standard behavior as much as possible to make wrapping simpler. Each argument should be a list of methods to be handled the way the corresponding methods are in the STANDARD method combination. It assumes all the lists are ordered properly already. See the LAX method combination in this package for an example.

Package

method-combination-utilities

Source

definition-helpers.lisp (file)

Function: wrap-primary-form PRIMARY-FORM &optional AROUND-METHODS BEFORE-METHODS AFTER-METHODS

This is similar to COMBINE-STANDARD-METHODS, but it takes an already- generated primary form rather than a list of primary methods. This is because it is fairly common for a method combination to deal with primary methods in some specialized way, then combine them with normal :AROUND/:BEFORE/:AFTER methods. See the BASIC and APPEND/NCONC combinations in this package for examples.

Package

method-combination-utilities

Source

definition-helpers.lisp (file)


Previous: , Up: Exported definitions   [Contents][Index]

5.1.3 Method combinations

Long Method Combination: append/nconc ()

This is an improvement on the built-in APPEND method combination, which uses the short form of DEFINE-METHOD-COMBINATION. This allows either ‘NCONC‘ or ‘APPEND‘ to be used as a qualifier depending on whether or not the method returns a list where the last cons can be modified. If all but the last primary methods specify ‘NCONC‘, then ‘NCONC‘ will be used, otherwise, ‘APPEND‘.

Package

method-combination-utilities

Source

method-combinations.lisp (file)

Long Method Combination: basic ()

This combination removes the need for the built-in combinations (other than STANDARD) and the short form of DEFINE-METHOD-COMBINATION.

Differences from old built-in usage:
* specify as ’(basic progn t :most-specific-last) instead of
’(progn :most-specific-last)
* can specify an arbitrary operator without having to first DEFINE-METHOD-COMBINATION
* IDENTITY-WITH-ONE-ARGUMENT[-P] is now specified at usage rather than definition
* :BEFORE and :AFTER methods are allowed.

Package

method-combination-utilities

Source

method-combinations.lisp (file)

Long Method Combination: lax ()

This combination allows (and ignores) additional method qualifiers after any of the ‘STANDARD‘ qualifiers. It is useful if you are handling your qualifiers in a custom method class.

Package

method-combination-utilities

Source

method-combinations.lisp (file)

Long Method Combination: primary ()

This simple method combination requires that no methods have any qualifiers. Methods are treated exactly like primary methods in the STANDARD method combination.

Package

method-combination-utilities

Source

method-combinations.lisp (file)


Previous: , Up: Definitions   [Contents][Index]

5.2 Internal definitions


Previous: , Up: Internal definitions   [Contents][Index]

5.2.1 Functions

Function: method-combination-expander-function METHOD-COMBINATION
Package

method-combination-utilities

Source

method-combination-expand.lisp (file)

Function: method-combination-expansion-form EXPANDER GF MC METHODS
Package

method-combination-utilities

Source

method-combination-expand.lisp (file)


Previous: , Up: Top   [Contents][Index]

Appendix A Indexes


Next: , Previous: , Up: Indexes   [Contents][Index]

A.1 Concepts

Jump to:   F   L   M  
Index Entry  Section

F
File, Lisp, method-combination-utilities.asd: The method-combination-utilities<dot>asd file
File, Lisp, method-combination-utilities/definition-helpers.lisp: The method-combination-utilities/definition-helpers<dot>lisp file
File, Lisp, method-combination-utilities/method-combination-expand.lisp: The method-combination-utilities/method-combination-expand<dot>lisp file
File, Lisp, method-combination-utilities/method-combinations.lisp: The method-combination-utilities/method-combinations<dot>lisp file
File, Lisp, method-combination-utilities/package.lisp: The method-combination-utilities/package<dot>lisp file

L
Lisp File, method-combination-utilities.asd: The method-combination-utilities<dot>asd file
Lisp File, method-combination-utilities/definition-helpers.lisp: The method-combination-utilities/definition-helpers<dot>lisp file
Lisp File, method-combination-utilities/method-combination-expand.lisp: The method-combination-utilities/method-combination-expand<dot>lisp file
Lisp File, method-combination-utilities/method-combinations.lisp: The method-combination-utilities/method-combinations<dot>lisp file
Lisp File, method-combination-utilities/package.lisp: The method-combination-utilities/package<dot>lisp file

M
method-combination-utilities.asd: The method-combination-utilities<dot>asd file
method-combination-utilities/definition-helpers.lisp: The method-combination-utilities/definition-helpers<dot>lisp file
method-combination-utilities/method-combination-expand.lisp: The method-combination-utilities/method-combination-expand<dot>lisp file
method-combination-utilities/method-combinations.lisp: The method-combination-utilities/method-combinations<dot>lisp file
method-combination-utilities/package.lisp: The method-combination-utilities/package<dot>lisp file

Jump to:   F   L   M  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.2 Functions

Jump to:   C   F   M   W  
Index Entry  Section

C
call-methods: Exported functions
combine-standard-methods: Exported functions

F
Function, call-methods: Exported functions
Function, combine-standard-methods: Exported functions
Function, method-combination-expander-function: Internal functions
Function, method-combination-expansion-form: Internal functions
Function, wrap-primary-form: Exported functions

M
Macro, method-combination-expand: Exported macros
method-combination-expand: Exported macros
method-combination-expander-function: Internal functions
method-combination-expansion-form: Internal functions

W
wrap-primary-form: Exported functions

Jump to:   C   F   M   W  

Next: , Previous: , Up: Indexes   [Contents][Index]

A.3 Variables


Previous: , Up: Indexes   [Contents][Index]

A.4 Data types

Jump to:   A   B   L   M   P   S  
Index Entry  Section

A
append/nconc: Exported method combinations

B
basic: Exported method combinations

L
lax: Exported method combinations
Long Method Combination, append/nconc: Exported method combinations
Long Method Combination, basic: Exported method combinations
Long Method Combination, lax: Exported method combinations
Long Method Combination, primary: Exported method combinations

M
Method Combination, Long, append/nconc: Exported method combinations
Method Combination, Long, basic: Exported method combinations
Method Combination, Long, lax: Exported method combinations
Method Combination, Long, primary: Exported method combinations
method-combination-utilities: The method-combination-utilities system
method-combination-utilities: The method-combination-utilities package
method-combination-utilities.system: The method-combination-utilities<dot>system package

P
Package, method-combination-utilities: The method-combination-utilities package
Package, method-combination-utilities.system: The method-combination-utilities<dot>system package
primary: Exported method combinations

S
System, method-combination-utilities: The method-combination-utilities system

Jump to:   A   B   L   M   P   S