The static-dispatch Reference Manual

Table of Contents

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

The static-dispatch Reference Manual

This is the static-dispatch Reference Manual, version 0.2.2, generated automatically by Declt version 2.4 patchlevel 1 "Will Decker" on Mon Jul 29 16:42:14 2019 GMT+0.


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

1 Introduction

STATIC-DISPATCH

Static dispatch is a library, inspired by inlined-generic-function, which allows standard Common Lisp generic function dispatch to be performed statically (at compile time) rather than dynamically (runtime). This is similar to what is known as "overloading" in languages such as C++ and Java.

The purpose of static dispatch is to provide an optimization in cases where the usual dynamic dispatch is too slow, and the dynamic features of generic functions, such as adding/removing methods at runtime are not required. An example of such a case is a generic equality comparison function. Currently generic functions are considered far too slow to implement generic arithmetic and comparison operations when used heavily in numeric code.

How it works

The shadowed DEFMETHOD macro stores the body of the method in a global variable which contains a hash-table mapping generic functions to their methods.

A compiler macro function is added to the generic function which determines the types of the arguments and replaces the function call form with the body of the most specific applicable method. If the types cannot be determined, or there isn't enough type information the generic function call is left as is. Thus in order to choose the appropriate method at compile-time rather than runtime, the types of the arguments either have to be declared using DECLARE or surrounded in a THE form.

Usage

The package STATIC-DISPATCH-CL is provided which contains all symbols in the COMMON-LISP package and the shadowed DEFMETHOD macro. This package should be used/imported instead of COMMON-LISP as besides exporting the shadowed DEFMETHOD symbol, it also exports all symbols shadowed by the CLOSER-COMMON-LISP package (from closer-mop) which are necessary for closer-mop to function correctly.

Generic functions and methods are defined as usual, using DEFGENERIC and DEFMETHOD. Generic functions are dispatched dynamically, and are identical to standard Common Lisp generic function, until the following declaration is in place:

  1. (INLINE <generic function name>)

In order for the appropriate method to be chosen directly the arguments to the generic function call form should be one of the following:

Otherwise no method is chosen and the generic function call form is left as is.

Both EQL and class specializers are supported. EQL methods will only be chosen statically if the argument is one of the following and is EQL to the specializer's value.

Note: Even if a variable is bound (by LET) to a value that is EQL to the specializer's value, it will not be chosen unless it has a TYPE (EQL ...) declaration.

CALL-NEXT-METHOD and NEXT-METHOD-P are supported fully. User-defined method combinations and :BEFORE, :AFTER :AROUND methods are not supported.

Note: In order for type and inline declarations to be made available, to the compiler macro, consistently across implementations the ENABLE-HOOK function has to be called at some point, see https://github.com/alex-gutev/cl-environments#documentation for more information.

Differences from INLINED-GENERIC-FUNCTION

Inlined-Generic-Function uses a custom generic function metaclass INLINED-GENERIC-FUNCTION which stores the method's body in order for it to be inlined by the compiler-macro. Whilst this approach is more robust than shadowing DEFMETHOD in order to store the method body in a hash-table in a global variable, as it will be able to inline methods added by other means besides DEFMETHOD, the metaclass is changed from the standard generic function metaclass which in turn prevents certain optimizations, of the dynamic generic function dispatch, from being performed by the compiler. This results in slower execution speed, as shown in [https://github.com/guicho271828/inlined-generic-function#user-content-result].

Static-Dispatch does not use a custom generic function metaclass thus generic functions are identical to standard common lisp generic functions, and hence the usual optimizations are performed, unless an INLINE declaration is in place. This only matters when generic functions are not inlined, however the goal of this library is to provide generic function inlining as an optimization for cases where it is known that standard dynamic dispatch is too slow, not to provide inlining by default.

In Static-Dispatch the generic function call form is directly replaced with the body of the most-specific applicable method, whereas in Inlined-Generic-Function the form is replaced with a MATCH form which contains a pattern-matching clause for each method that checks whether the types of the arguments match the method's specializer list and evaluates the body of the method. An advantage of the approach taken by Inlined-Generic-Function is that the method bodies can be inlined even if the arguments are more complicated expressions than variables and THE forms. However this relies on the compiler to remove the clauses corresponding to the non-applicable methods otherwise the result is that dynamic dispatch is still performed, however is performed inline and is potentially slower than the built-in dynamic dispatch of CLOS. SBCL is capable of removing branches, corresponding to non-applicable methods, however most other compilers (including CCL) are not.

Static-Dispatch can handle full lambda-lists with all lambda-list keywords. Inlined-Generic-Function cannot, as of yet (November 2018), handle lambda-lists containing anything but required arguments.

Static-Dispatch does not yet support before after, around methods and user-defined method combinations. All are supported by Inlined-Generic-Function.

Dependencies

Main Dependencies

closer-mop - Required to obtain information about generic-function methods, namely the argument precedence order and class precedence list.

cl-environments - Used to extract declaration information from environments, on any implementation. Requires that the ENABLE-HOOK function (exported from the STATIC-DISPATCH-CL package) is called.

Other Dependencies

agutil, alexandria, anaphora, trivia, iterate, cl-arrows.

Status

Supports class and EQL specializers.

Does not support user-defined method combinations, and before, after, around methods.

Tested on: CCL, SBCL, CLISP, ECL, CMUCL and ABCL.

Known Issues:


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 static-dispatch

Author

Alexander Gutev

License

MIT

Description

Static generic function dispatch for Common Lisp.

Version

0.2.2

Dependencies
Source

static-dispatch.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 static-dispatch.asd

Location

static-dispatch.asd

Systems

static-dispatch (system)


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

3.1.2 static-dispatch/package.lisp

Parent

static-dispatch (system)

Location

package.lisp

Packages

static-dispatch


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

3.1.3 static-dispatch/static-dispatch.lisp

Dependency

package.lisp (file)

Parent

static-dispatch (system)

Location

static-dispatch.lisp

Exported Definitions
Internal Definitions

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

4 Packages

Packages are listed by definition order.


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

4.1 static-dispatch

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


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

5.1.1 Macros

Macro: defgeneric NAME (&rest LAMBDA-LIST) &rest OPTIONS
Package

static-dispatch

Source

static-dispatch.lisp (file)

Macro: defmethod NAME &rest ARGS
Package

static-dispatch

Source

static-dispatch.lisp (file)


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

5.2 Internal definitions


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

5.2.1 Special variables

Special Variable: *current-gf*

The name of the generic function currently being inlined/statically dispatched.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Special Variable: *generic-function-table*

Hash table mapping generic functions to a list of methods.

Package

static-dispatch

Source

static-dispatch.lisp (file)


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

5.2.2 Functions

Function: applicable-methods METHODS TYPES

Returns a list of all methods in METHODS which are applicable to the types TYPES.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: block-name GF-NAME

Returns the name of the implicit block, surrounding a method of the generic function GF-NAME.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: enclose-in-type-declarations FORMS VARS TYPES

Encloses FORMS in a LOCALLY form which declares the types of VARS to be TYPES.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: ensure-gf-methods GF-NAME

Ensures that a method table for the generic function GF-NAME exists, in *GENERIC-FUNCTION-TABLE*.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: ensure-method-info GF-NAME SPECIALIZERS &key BODY LAMBDA-LIST REMOVE-ON-REDEFINE-P

Ensures that the method table, withing *GENERIC-FUNCTION-TABLE*, of the generic function GF-NAME contains a method with specializers SPECIALIZERS, lambda-list LAMBDA-LIST and body BODY. If the table does not contain a method for those specializers, a new ‘METHOD-INFO’ object is created.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: gf-compiler-macro WHOLE &optional ENV

Compiler macro function for statically dispatched generic functions.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: gf-method GF-NAME SPECIALIZERS

Returns the ‘METHOD-INFO’, of the method with specializer list SPECIALIZERS, of the generic function GF-NAME.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Writer

(setf gf-method) (function)

Function: (setf gf-method) VALUE GF-NAME SPECIALIZERS

Sets the method info, to VALUE, for the method with specializer list SPECIALIZERS, of the generic function GF-NAME.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Reader

gf-method (function)

Function: gf-methods GF-NAME

Returns the method information for the generic function GF-NAME. A hash-table mapping lists of specializers to ‘METHOD-INFO’ objects is returned.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: has-eql-specializer? SPECIALIZERS

Returns true if SPECIALIZERS contains EQL
specializers. SPECIALIZERS should be the list of specializers extracted from a DEFMETHOD lambda list.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: inline-method-body METHOD ARGS NEXT-METHODS &optional CHECK-TYPES TYPES

Returns the a form which contains the body of METHOD inline. ARGS is either a list of the arguments passed to METHOD or a symbol naming a variable in which the arguments list is
stored. NEXT-METHODS is the list of the next (less specific) applicable methods. TYPES is the types of the arguments as determined from the lexical environment.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: make-ignorable-declarations VARS

Creates a DECLARE IGNORABLE expression for the variables in VARS.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: make-type-checks VARS TYPES

Returns a list of CHECK-TYPE forms for each variable in VARS and corresponding type in TYPES.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: make-type-declarations VARS TYPES

Returns a DECLARE expression which declares each variable in VARS to be of the type stored in the corresponding element of TYPES

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: mark-no-dispatch GF-NAME

Mark the generic function as one which should not be dispatched statically. This is used primarily when unsupported features are used in the definition of the generic function or its methods.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: order-by-precedence PRECEDENCE ARGS

Orders the list ARGS by the order specified in PRECEDENCE.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: order-method-specializers METHODS PRECEDENCE

Orders the specializers of METHODS by the argument precedence order PRECEDENCE.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: parse-method ARGS
Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: parse-method-lambda-list LAMBDA-LIST
Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: precedence-order LAMBDA-LIST PRECEDENCE

Returns a list of the generic function arguments in argument precedence order (PRECEDENCE). Each element in the list is the index of the argument within LAMBDA-LIST.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: should-check-types ENV

Returns true if CHECK-TYPE forms should be added in the body of CALL-NEXT-METHOD. CHECK-TYPE forms are added if the priority of the SAFETY optimize quality is greater than or equal to the SPEED optimize quality in the environment ENV.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: sort-methods METHODS

Sorts METHODS by specificity.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: specializer->cl SPECIALIZER

Returns the CL representation of a specializer as used in a DEFMETHOD lambda-list. ‘CLASS’ specializers are replaced with their CLASS-NAME and EQL specializers are replaced with ‘(EQL ,EQL-SPECIALIZER-OBJECT). The EQL-SPECIALIZER-OBJECT is the value to which the EQL object form was evaluated not the form itself.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: specializer< S1 S2

Returns true if the specializer list S1 is more specific than specializer list S2.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: static-dispatch? NAME ENV

Checks whether the generic function named NAME should be statically dispatched. This is the case if it is declared inline in the environment ENV.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Function: static-overload GF-NAME ARGS ENV

Determines the types of the generic function (with name GF-NAME) arguments ARGS, determines the most applicable method and returns the body of the method. If there are no applicable methods, or the types of the arguments could not be determined, NIL is returned.

Package

static-dispatch

Source

static-dispatch.lisp (file)


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

5.2.3 Generic functions

Generic Function: body OBJECT
Generic Function: (setf body) NEW-VALUE OBJECT
Package

static-dispatch

Methods
Method: body (METHOD-INFO method-info)
Method: (setf body) NEW-VALUE (METHOD-INFO method-info)

The method function body.

Source

static-dispatch.lisp (file)

Generic Function: feature CONDITION
Package

static-dispatch

Methods
Method: feature (CONDITION not-supported)
Source

static-dispatch.lisp (file)

Generic Function: function-name OBJECT
Generic Function: (setf function-name) NEW-VALUE OBJECT
Package

static-dispatch

Methods
Method: function-name (METHOD-INFO method-info)
Method: (setf function-name) NEW-VALUE (METHOD-INFO method-info)

Symbol naming a non-generic function which implements the method.

Source

static-dispatch.lisp (file)

Generic Function: remove-on-redefine-p OBJECT
Generic Function: (setf remove-on-redefine-p) NEW-VALUE OBJECT
Package

static-dispatch

Methods
Method: remove-on-redefine-p (METHOD-INFO method-info)
Method: (setf remove-on-redefine-p) NEW-VALUE (METHOD-INFO method-info)

True if the method should be removed when the DEFGENERIC form is re-evaluated.

Source

static-dispatch.lisp (file)

Generic Function: specializers OBJECT
Generic Function: (setf specializers) NEW-VALUE OBJECT
Package

static-dispatch

Methods
Method: specializers (METHOD-INFO method-info)
Method: (setf specializers) NEW-VALUE (METHOD-INFO method-info)

The method’s specializers

Source

static-dispatch.lisp (file)


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

5.2.4 Conditions

Condition: not-supported ()

Error condition: A CLOS feature was used that is not supporting in inlining/static dispatch.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Direct superclasses

error (condition)

Direct methods

feature (method)

Direct slots
Slot: feature

Symbol identifying the unsupported feature.

Initargs

:feature

Initform

(quote nil)

Readers

feature (generic function)


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

5.2.5 Classes

Class: method-info ()

Stores the body of a method and the name of a non-generic function which contains the method’s body.

Package

static-dispatch

Source

static-dispatch.lisp (file)

Direct superclasses

standard-object (class)

Direct methods
Direct slots
Slot: body

The method function body.

Initargs

:body

Readers

body (generic function)

Writers

(setf body) (generic function)

Slot: lambda-list

The lambda-list of the method.

Initargs

:lambda-list

Readers

lambda-list (generic function)

Writers

(setf lambda-list) (generic function)

Slot: specializers

The method’s specializers

Initargs

:specializers

Readers

specializers (generic function)

Writers

(setf specializers) (generic function)

Slot: function-name

Symbol naming a non-generic function which implements the method.

Initargs

:function-name

Readers

function-name (generic function)

Writers

(setf function-name) (generic function)

Slot: remove-on-redefine-p

True if the method should be removed when the DEFGENERIC form is re-evaluated.

Initargs

:remove-on-redefine-p

Readers

remove-on-redefine-p (generic function)

Writers

(setf remove-on-redefine-p) (generic function)


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

Appendix A Indexes


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

A.1 Concepts

Jump to:   F   L   S  
Index Entry  Section

F
File, Lisp, static-dispatch.asd: The static-dispatch<dot>asd file
File, Lisp, static-dispatch/package.lisp: The static-dispatch/package<dot>lisp file
File, Lisp, static-dispatch/static-dispatch.lisp: The static-dispatch/static-dispatch<dot>lisp file

L
Lisp File, static-dispatch.asd: The static-dispatch<dot>asd file
Lisp File, static-dispatch/package.lisp: The static-dispatch/package<dot>lisp file
Lisp File, static-dispatch/static-dispatch.lisp: The static-dispatch/static-dispatch<dot>lisp file

S
static-dispatch.asd: The static-dispatch<dot>asd file
static-dispatch/package.lisp: The static-dispatch/package<dot>lisp file
static-dispatch/static-dispatch.lisp: The static-dispatch/static-dispatch<dot>lisp file

Jump to:   F   L   S  

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

A.2 Functions

Jump to:   (  
A   B   D   E   F   G   H   I   M   O   P   R   S  
Index Entry  Section

(
(setf body): Internal generic functions
(setf body): Internal generic functions
(setf function-name): Internal generic functions
(setf function-name): Internal generic functions
(setf gf-method): Internal functions
(setf remove-on-redefine-p): Internal generic functions
(setf remove-on-redefine-p): Internal generic functions
(setf specializers): Internal generic functions
(setf specializers): Internal generic functions

A
applicable-methods: Internal functions

B
block-name: Internal functions
body: Internal generic functions
body: Internal generic functions

D
defgeneric: Exported macros
defmethod: Exported macros

E
enclose-in-type-declarations: Internal functions
ensure-gf-methods: Internal functions
ensure-method-info: Internal functions

F
feature: Internal generic functions
feature: Internal generic functions
Function, (setf gf-method): Internal functions
Function, applicable-methods: Internal functions
Function, block-name: Internal functions
Function, enclose-in-type-declarations: Internal functions
Function, ensure-gf-methods: Internal functions
Function, ensure-method-info: Internal functions
Function, gf-compiler-macro: Internal functions
Function, gf-method: Internal functions
Function, gf-methods: Internal functions
Function, has-eql-specializer?: Internal functions
Function, inline-method-body: Internal functions
Function, make-ignorable-declarations: Internal functions
Function, make-type-checks: Internal functions
Function, make-type-declarations: Internal functions
Function, mark-no-dispatch: Internal functions
Function, order-by-precedence: Internal functions
Function, order-method-specializers: Internal functions
Function, parse-method: Internal functions
Function, parse-method-lambda-list: Internal functions
Function, precedence-order: Internal functions
Function, should-check-types: Internal functions
Function, sort-methods: Internal functions
Function, specializer->cl: Internal functions
Function, specializer<: Internal functions
Function, static-dispatch?: Internal functions
Function, static-overload: Internal functions
function-name: Internal generic functions
function-name: Internal generic functions

G
Generic Function, (setf body): Internal generic functions
Generic Function, (setf function-name): Internal generic functions
Generic Function, (setf remove-on-redefine-p): Internal generic functions
Generic Function, (setf specializers): Internal generic functions
Generic Function, body: Internal generic functions
Generic Function, feature: Internal generic functions
Generic Function, function-name: Internal generic functions
Generic Function, remove-on-redefine-p: Internal generic functions
Generic Function, specializers: Internal generic functions
gf-compiler-macro: Internal functions
gf-method: Internal functions
gf-methods: Internal functions

H
has-eql-specializer?: Internal functions

I
inline-method-body: Internal functions

M
Macro, defgeneric: Exported macros
Macro, defmethod: Exported macros
make-ignorable-declarations: Internal functions
make-type-checks: Internal functions
make-type-declarations: Internal functions
mark-no-dispatch: Internal functions
Method, (setf body): Internal generic functions
Method, (setf function-name): Internal generic functions
Method, (setf remove-on-redefine-p): Internal generic functions
Method, (setf specializers): Internal generic functions
Method, body: Internal generic functions
Method, feature: Internal generic functions
Method, function-name: Internal generic functions
Method, remove-on-redefine-p: Internal generic functions
Method, specializers: Internal generic functions

O
order-by-precedence: Internal functions
order-method-specializers: Internal functions

P
parse-method: Internal functions
parse-method-lambda-list: Internal functions
precedence-order: Internal functions

R
remove-on-redefine-p: Internal generic functions
remove-on-redefine-p: Internal generic functions

S
should-check-types: Internal functions
sort-methods: Internal functions
specializer->cl: Internal functions
specializer<: Internal functions
specializers: Internal generic functions
specializers: Internal generic functions
static-dispatch?: Internal functions
static-overload: Internal functions

Jump to:   (  
A   B   D   E   F   G   H   I   M   O   P   R   S  

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

A.3 Variables

Jump to:   *  
B   F   L   R   S  
Index Entry  Section

*
*current-gf*: Internal special variables
*generic-function-table*: Internal special variables

B
body: Internal classes

F
feature: Internal conditions
function-name: Internal classes

L
lambda-list: Internal classes

R
remove-on-redefine-p: Internal classes

S
Slot, body: Internal classes
Slot, feature: Internal conditions
Slot, function-name: Internal classes
Slot, lambda-list: Internal classes
Slot, remove-on-redefine-p: Internal classes
Slot, specializers: Internal classes
Special Variable, *current-gf*: Internal special variables
Special Variable, *generic-function-table*: Internal special variables
specializers: Internal classes

Jump to:   *  
B   F   L   R   S  

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

A.4 Data types

Jump to:   C   M   N   P   S  
Index Entry  Section

C
Class, method-info: Internal classes
Condition, not-supported: Internal conditions

M
method-info: Internal classes

N
not-supported: Internal conditions

P
Package, static-dispatch: The static-dispatch package

S
static-dispatch: The static-dispatch system
static-dispatch: The static-dispatch package
System, static-dispatch: The static-dispatch system

Jump to:   C   M   N   P   S