The org.tfeb.conduit-packages Reference Manual

Table of Contents

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

The org.tfeb.conduit-packages Reference Manual

This is the org.tfeb.conduit-packages Reference Manual, version 1.0.0, generated automatically by Declt version 3.0 "Montgomery Scott" on Tue Dec 22 13:10:59 2020 GMT+0.


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

1 Introduction

Conduit packages

This system defines a way of treating Common Lisp packages as 'conduits' which can sit between one or more implementation packages and users of those packages. Conduits try to be dynamic: assuming you modify the packages for which they are conduits for using the functionality defined in this system, then conduit packages will notice the changes and recompute themselves.

This system also defines a way of making clones of packages which try to be as identical to them as possible. Clones are not dynamic, but rather point-in-time copies.

The most important interface to this is through a variant version of the defpackage macro, which supports some extra options. This version of defpackage works by checking for options it cares about and then deferring to the underlying implementation for anything it does not care about. This means that it can sit on top of an underlying implementation which has options other than the standard CL ones. Some other standard package functions are also overridden to support the dynamic behaviour of conduits.

Packages in this system

All packages have domain-structured names.

Note that it will not (and can not) work, in any package which uses cl, to simply say (use-package :org.tfeb.conduit-packages), as there are inevitable name clashes. Instead you should either define a package which uses org.tfeb.clc, or define your own conduit package (see below).

Conduits by example

All the examples below assume that the current package is org.tfeb.clc-user, so that defpackage means org.tfeb.conduit-packages:defpackage for instance.

Let's say I'm writing a program which consists of several implementation packages, say com.cley.my-great-prog.clever-hacks, com.cley.my-great-prog.not-so-clever-hacks and com.cley.my-great-prog.outright-misfeatures. The definitions of these three packages might be:

(defpackage :com.cley.my-great-prog.clever-hacks
  (:use :cl)
  (:export #:cause-fire))

(defpackage :com.cley.my-great-prog.not-so-clever-hacks
  (:use :cl)
  (:export #:cause-serious-fire))

(defpackage :com.cley.my-great-prog.outright-misfeatures
  (:use :cl)
  (:export #:fail-to-put-out-fire))

Now I want to provide a single package, com.cley.my-great-program which combines the functionality of the three packages:

(defpackage :com.cley.my-great-prog
  (:use)
  (:extends :com.cley.my-great-prog.clever-hacks)
  (:extends :com.cley.my-great-prog.not-so-clever-hacks)
  (:extends :com.cley.my-great-prog.outright-misfeatures))

And now

> (do-external-symbols
      (s (find-package :com.cley.my-great-prog))
    (format t "~&~A from ~A~%"
            (symbol-name s)
            (package-name (symbol-package s))))
FAIL-TO-PUT-OUT-FIRE from COM.CLEY.MY-GREAT-PROG.OUTRIGHT-MISFEATURES
CAUSE-FIRE from COM.CLEY.MY-GREAT-PROG.CLEVER-HACKS
CAUSE-SERIOUS-FIRE from COM.CLEY.MY-GREAT-PROG.NOT-SO-CLEVER-HACKS

So com.cley.my-great-prog serves as a conduit for the various implementation packages of the program, which means that users of the program don't have to worry about what the implementation packages are.

Conduits are dynamic. If I now decide that the com.cley.my-great-prog.clever-hacks package should export some other symbols, I can simply redefine it:

(defpackage :com.cley.my-great-prog.clever-hacks
  (:use :cl)
  (:export #:cause-fire
   #:light-match #:burn-petrol))

and now

(do-external-symbols
      (s (find-package :com.cley.my-great-prog))
    (format t "~&~A from ~A~%"
            (symbol-name s)
            (package-name (symbol-package s))))
FAIL-TO-PUT-OUT-FIRE from COM.CLEY.MY-GREAT-PROG.OUTRIGHT-MISFEATURES
BURN-PETROL from COM.CLEY.MY-GREAT-PROG.CLEVER-HACKS
CAUSE-FIRE from COM.CLEY.MY-GREAT-PROG.CLEVER-HACKS
LIGHT-MATCH from COM.CLEY.MY-GREAT-PROG.CLEVER-HACKS
CAUSE-SERIOUS-FIRE from COM.CLEY.MY-GREAT-PROG.NOT-SO-CLEVER-HACKS

The conduit package noticed the redefinition of a package for which it was a conduit, and changed its exports appropriately.

The dynamic behaviour of conduit packages is a little fragile: it will work so long as you use the conduits-provided versions of defpackage, export and so on, but it won't work if you use the standard CL ones, either explicity or implicitly, during error recovery say. If the system gets in a mess, you can always call org.tfeb.conduit-packages:recompute-conduits to recompute everything. The dynamic behaviour of conduit packages is meant to be a help for when writing a program, during which process packages often get reorganised fairly frequently: it's not something that should be relied on for production.

Conduits can export only part of the packages for which they are conduits. For instance, perhaps I don't want the burn-petrol feature:

(defpackage :com.cley.my-great-prog
  (:use)
  (:extends/excluding :com.cley.my-great-prog.clever-hacks
   #:burn-petrol)
  (:extends :com.cley.my-great-prog.not-so-clever-hacks)
  (:extends :com.cley.my-great-prog.outright-misfeatures))

Or perhaps I only want to burn petrol:

(defpackage :com.cley.my-great-prog
  (:use)
  (:extends/excluding :com.cley.my-great-prog.clever-hacks
   #:burn-petrol)
  (:extends :com.cley.my-great-prog.not-so-clever-hacks)
  (:extends :com.cley.my-great-prog.outright-misfeatures))

In these two latter cases the symbols you are excluding or including need to exist in the package being extended: you can't, for instance, add an exclusion for a symbol which only may be there, or which may be there in future. That might be a nice feature to add.

Using inclusions and exclusions like this allows you to construct conduit packages which are 'like' underlying packages but have some small differences, such as replacing some functionality. org.tfeb.clc is such a package: it is a conduit which extends cl but replaces some of its functionality. Here is its definition:

(defpackage :org.tfeb.cl/conduits
  (:use)
  (:nicknames :org.tfeb.clc)
  (:extends/excluding :cl #:export #:unexport #:defpackage
   #:delete-package #:rename-package)
  (:extends/excluding :org.tfeb.conduit-packages
   #:recompute-conduits #:*underlying-implementation-map*))

Note that org.tfeb.clc-user is not a conduit: it's just a package which uses org.tfeb.clc rather than cl:

(defpackage :org.tfeb.cl-user/conduits
  (:nicknames :org.tfeb.clc-user)
  (:use :org.tfeb.clc))))

Utilities

The org.tfeb.conduit-packages package (but not org.tfeb.clc) exports two other things.

recompute-conduits. This is a function that will recompute all the conduit packages that exist: it's useful if things have become confused, or if you just want to make sure that they definitely are not confused.

*underlying-implementation-map*. This is an alist which maps between the names of the functions and macros for which the org.tfeb.conduit-packages provides implementations and the names of the equivalent underlying implementations that it must call. So, for instance, in this alist, by default, is an entry (org.tfeb.conduit-packages:defsystem . cl:defsystem) which tells the system what the underlying implementation of the defsystem macro is.

The purpose of this alist is so that, if need be, this system could be layered on top of some other system which also provides versions of, say, defsystem or export &c. Unless you want to use it in that context you never need to worry about this variable.

Package cloning

Cloning a package is making a package which is 'like' it: all of its internal, external, and shadowing symbols, as well as its used packages will be the same as the package it clones, but in addition any other things asked for by the defpackage form will be done. Once a clone is made it lives an independent life to the the package it clones: clones are not dynamic, and don't remember what package they were cloned from. Clones also can't be conduits.

Here is an example of making a clone:

(defpackage :org.tfeb.foo
  (:use :org.tfeb.clc)
  (:export #:spot))

(intern "FUG" ':org.tfeb.foo)

(defpackage :org.tfeb.bar
  (:use :org.tfeb.clc)
  (:clones :org.tfeb.foo)
  (:export #:spit))

Now

>  (eq 'org.tfeb.foo:spot 'org.tfeb.bar:spot)
t

> (eq 'org.tfeb.foo::fug 'org.tfeb.bar::fug)
t

> (eq 'org.tfeb.foo::fog 'org.tfeb.bar::fog)
nil

> 'org.tfeb.bar:spit
org.tfeb.bar:spit

> 'org.tfeb.foo:spit

Error: Symbol "SPIT" not found at all in the ORG.TFEB.FOO package.
[...]

The idea behind package clones was to allow you to make a quick-and-dirty point-in-time copy of a package in which you could then experiment without contaminating the namespace of the cloned package. Their intended use was on LispMs which took a long time to reboot: in practice I think I have almost never used them.

Notes

Conduit packages should generally be defined with (:use) so the used-package list is empty rather than an implementation-default. A conduit really is just that: it doesn't need to use any packages because it's never a package where anything is defined.

The defsystem macro uses *underlying-implementation-map* to know what the underlying defsystem is, and so this variable matters at macro-expansion time as well as at runtime.

Building

There is an ASDF system definition, but in fact simply compiling and loading conduit-packages.lisp should be enough: there are no dependencies.

All of this system should be portable CL: if it's not that's a bug.


Conduit packages is copyright 1998-2002, 2020 by Tim Bradshaw. See LICENSE for the lice


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 org.tfeb.conduit-packages

Author

Tim Bradshaw

Home Page

https://github.com/tfeb/conduit-packages

License

MIT

Description

Conduit packages

Version

1.0.0

Source

org.tfeb.conduit-packages.asd (file)

Component

conduit-packages.lisp (file)


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 org.tfeb.conduit-packages.asd

Location

org.tfeb.conduit-packages.asd

Systems

org.tfeb.conduit-packages (system)


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

3.1.2 org.tfeb.conduit-packages/conduit-packages.lisp

Parent

org.tfeb.conduit-packages (system)

Location

conduit-packages.lisp

Packages
Exported Definitions
Internal Definitions

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

4 Packages

Packages are listed by definition order.


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

4.1 org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Use List

common-lisp

Exported Definitions
Internal Definitions

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

4.2 org.tfeb.cl-user/conduits

Source

conduit-packages.lisp (file)

Nickname

org.tfeb.clc-user

Use List

org.tfeb.cl/conduits


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

4.3 org.tfeb.cl/conduits

Source

conduit-packages.lisp (file)

Nickname

org.tfeb.clc

Used By List

org.tfeb.cl-user/conduits


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 Special variables

Special Variable: *underlying-implementation-map*

An alist which maps from names which conduits provides new implementations for and their underlying implementation function names. You can use this if you want to layer conduits on top of some other system which already is providing its own versions of these names. By default the underlying names are just the standard CL functions.

Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)


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

5.1.2 Macros

Macro: defpackage NAME &body CLAUSES

Define a package. See CL:DEFPACKAGE for tha basics.
In addition, this version of DEFPACKAGE can define a ‘conduit package’:
that you can use as a conduit to extend existing packages.
This works by importing symbols from the existing packages and
then reexporting them. The syntax is as DEFPACKAGE, with the addition
of three new clauses:
(:EXTENDS package) takes package and reexports all its symbols; (:EXTENDS/INCLUDING package . syms/names) reexports only syms/names; (:EXTENDS/EXCLUDING package . syms/names) reexports all *but* syms/names. When defining a conduit package you almost certainly will want to say (:USE) to prevent the CL package being used.

This version of DEFPACKAGE also support ‘cloning’ packages: making another package which is ‘just like’ an existing package. This means that all the internal, exported and shadowing symbols in the clone will be the same as those in the cloned package, but any additional things defined by DEFPACKAGE will also take effect. This allows you to essentially make a copy of
a package which you can then use to define new functionality without interning a lot of things in the original package. Cloning is a static operation - packages do not know who their clones are, and no attempt is made to keep clones up to date. Cloning is done by the clause
(:CLONES package)
Cloning is not compatible with extending (this is checked).
As with extending you probably want to specify (:USE) when cloning.

Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)


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

5.1.3 Functions

Function: delete-package PACK/NAME
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: export SYMBOL/S &optional PACKAGE
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: recompute-conduits ()

Clean up the lists of conduits, and recompute all conduit packages to make them consistent

Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: rename-package PACK/NAME NEW-NAME &optional NICKNAMES
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: unexport SYMBOL/S &optional PACKAGE
Package

org.tfeb.conduit-packages

Source

conduit-packages.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: *conduit-package-descriptions*
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Special Variable: *conduit-packages*
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Special Variable: *package-conduits*
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)


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

5.2.2 Functions

Function: canonicalise-package-name PACKAGE/NAME
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: clean-package-alist PA
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: clone-packages-to-package FROMS TO
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: conduit-error PACKAGE FORMAT &rest FORMAT-ARGUMENTS
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: funcall/ul FNAME &rest ARGS
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: make-package-conduit-package PACKAGE/NAME &key EXTENDS EXTENDS/INCLUDING EXTENDS/EXCLUDING
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: note-conduit PACK CONDUIT
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: recompute-conduits-for PACK &optional CHAIN
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Function: underlying NAME
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)


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

5.2.3 Conditions

Condition: conduit-error ()
Package

org.tfeb.conduit-packages

Source

conduit-packages.lisp (file)

Direct superclasses
  • package-error (condition)
  • simple-error (condition)

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

Appendix A Indexes


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

A.1 Concepts

Jump to:   F   L   O  
Index Entry  Section

F
File, Lisp, org.tfeb.conduit-packages.asd: The org․tfeb․conduit-packages․asd file
File, Lisp, org.tfeb.conduit-packages/conduit-packages.lisp: The org․tfeb․conduit-packages/conduit-packages․lisp file

L
Lisp File, org.tfeb.conduit-packages.asd: The org․tfeb․conduit-packages․asd file
Lisp File, org.tfeb.conduit-packages/conduit-packages.lisp: The org․tfeb․conduit-packages/conduit-packages․lisp file

O
org.tfeb.conduit-packages.asd: The org․tfeb․conduit-packages․asd file
org.tfeb.conduit-packages/conduit-packages.lisp: The org․tfeb․conduit-packages/conduit-packages․lisp file

Jump to:   F   L   O  

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

A.2 Functions

Jump to:   C   D   E   F   M   N   R   U  
Index Entry  Section

C
canonicalise-package-name: Internal functions
clean-package-alist: Internal functions
clone-packages-to-package: Internal functions
conduit-error: Internal functions

D
defpackage: Exported macros
delete-package: Exported functions

E
export: Exported functions

F
funcall/ul: Internal functions
Function, canonicalise-package-name: Internal functions
Function, clean-package-alist: Internal functions
Function, clone-packages-to-package: Internal functions
Function, conduit-error: Internal functions
Function, delete-package: Exported functions
Function, export: Exported functions
Function, funcall/ul: Internal functions
Function, make-package-conduit-package: Internal functions
Function, note-conduit: Internal functions
Function, recompute-conduits: Exported functions
Function, recompute-conduits-for: Internal functions
Function, rename-package: Exported functions
Function, underlying: Internal functions
Function, unexport: Exported functions

M
Macro, defpackage: Exported macros
make-package-conduit-package: Internal functions

N
note-conduit: Internal functions

R
recompute-conduits: Exported functions
recompute-conduits-for: Internal functions
rename-package: Exported functions

U
underlying: Internal functions
unexport: Exported functions

Jump to:   C   D   E   F   M   N   R   U  

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

A.3 Variables

Jump to:   *  
S  
Index Entry  Section

*
*conduit-package-descriptions*: Internal special variables
*conduit-packages*: Internal special variables
*package-conduits*: Internal special variables
*underlying-implementation-map*: Exported special variables

S
Special Variable, *conduit-package-descriptions*: Internal special variables
Special Variable, *conduit-packages*: Internal special variables
Special Variable, *package-conduits*: Internal special variables
Special Variable, *underlying-implementation-map*: Exported special variables

Jump to:   *  
S  

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

A.4 Data types

Jump to:   C   O   P   S  
Index Entry  Section

C
Condition, conduit-error: Internal conditions
conduit-error: Internal conditions

O
org.tfeb.cl-user/conduits: The org․tfeb․cl-user/conduits package
org.tfeb.cl/conduits: The org․tfeb․cl/conduits package
org.tfeb.conduit-packages: The org․tfeb․conduit-packages system
org.tfeb.conduit-packages: The org․tfeb․conduit-packages package

P
Package, org.tfeb.cl-user/conduits: The org․tfeb․cl-user/conduits package
Package, org.tfeb.cl/conduits: The org․tfeb․cl/conduits package
Package, org.tfeb.conduit-packages: The org․tfeb․conduit-packages package

S
System, org.tfeb.conduit-packages: The org․tfeb․conduit-packages system

Jump to:   C   O   P   S