The lisp-namespace Reference Manual

Table of Contents

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

The lisp-namespace Reference Manual

This is the lisp-namespace Reference Manual, version 0.1, generated automatically by Declt version 2.3 "Robert April" on Tue Jan 09 15:13:01 2018 GMT+0.


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

1 Introduction


[[https://travis-ci.org/guicho271828/lisp-namespace][https://travis-ci.org/guicho271828/lisp-namespace.svg?branch=master]]


#+BEGIN_SRC
Long time ago, in a galaxy far far away... 

It is a period of a civil war. Lisp-2
aliens, striking from the function
namespace, have fought for the
design of their language against lisp-1.
#+END_SRC

tl;dr; → skip to API definition https://github.com/guicho271828/lisp-namespace#macro-define-namespace

+ update (2016/5/14) : added support for `documentation` and `describe`.
+ update (2016/5/21) : works on ECL, CLISP, ABCL and CMUCL.

* Introduction

# However, destructuring is merely
# a syntax sugar for writing the accessor.

There are several libraries which extends =let=. To my knowledge,
most of them goes toward destructuring, e.g., allowing
=&some-fancy-directive= in the argument list.  However, destructuring is
now **obsolete**: superseded by pattern-matching (e.g. fare-matcher, optima, trivia), which
cleanly combines =cond=, =typecase=, destructuring and constructors[1].
Now it comes to my mind: what could be the *orthogonal* aspect
that could be combined with =let=, or, =let + cond = pattern matching= ?

Then I noticed an oddness in flet, macrolet, labels, let,
symbol-macrolet. Pattern matching works in the value namespace only. 
# Also,
# while special bindings for /namespaces/ can be trivially implemented with a
# hash table, the lexical binding is not
--- it's worth a library.  This is
what this library is for.

[1] Like =(cons A B)= matching clause vs =(cons A B)= constructor.

* Namespaces in CL?

By /namespace/ I don't mean a /package/,
which is a way to manage symbols. It is orthogonal to /namespace/.

CL already has major 2 namespaces, /function/ namespace and /value/
namespace (or /variable/ namespace), but there are actually more --- e.g.,
/class/ namespace. Since the same symbol can represent different
objects in each namespace, this is obviously orthogonal to /package/.
For example, all these below can coexist in a
same file without errors, and each object is accessible with the
corresponding function.

#+BEGIN_SRC lisp
(in-package :cl-user)

(defclass foo () ())
(defun foo () nil)
(defvar foo 1)

(find-class 'foo)      ; -> #
(symbol-function 'foo) ; -> #
(symbol-value 'foo)    ; -> 1

(make-instance 'bar)   ; -> SIMPLE-ERROR
(symbol-function 'bar) ; -> UNDEFINED-FUNCTION
(symbol-value 'bar)    ; -> UNBOUND-VARIABLE
#+END_SRC

| namespace | accessor        | unbound condition  | boundp  | binding     |
|-----------+-----------------+--------------------+---------+-------------|
| class     | find-class      | SIMPLE-ERROR       | n/a     | n/a         |
| function  | symbol-function | UNDEFINED-FUNCTION | fboundp | flet,labels |
| value     | symbol-value    | UNBOUND-VARIABLE   | boundp  | let         |

/Some/ namespaces in CL can be said to overlap with each other. For example:

+ *class* namespace --- with *type*, *condition* and *struct* namespace
+ *function* namspace --- with *macro-function* and *generic-function* namespace
+ *value* namespace --- with *symbol-macro* namespace.

** Macro DEFINE-NAMESPACE

: (define-namespace name &optional (expected-type t) (binding t) (documentation ""))

This macro defines a namespace. For the given name of namespace X,
DEFINE-NAMESPACE defines 4 functions/macros:

+ =#'symbol-x, #'(setf symbol-x)= : accessor to the global binding. Optionally,
  =expected-type= provides =ftype= proclamation and results in the
  better optimization. =expected-type= is not evaluated.
+ =#'x-boundp= : unary function returning a boolean
+ condition =UNBOUND-X= which is signaled when trying to access the value of an unbounded symbol.
+ macro =(X-LET (binding...) body)= : lexical binding. Can be turned off
  when =binding= is nil.

** Extending the usability of =documentation= and =describe=

=define-namespace= also defines a method for =cl:documentation= and extend =cl:describe-object=. For example, you will be able to =(setf (documentation 'mysymbol 'x) "description")= and you will see it pretty printed in =(describe 'mysymbol)=.

Here is an example used in TRIVIA pattern matcher. Trivia has an =assoc= pattern, and everyone would feel happy if we can browse the documentation of this pattern from SLIME C-c C-d. Below is such an output on SBCL.

While such a practice is taken by some libraries (e.g. QL-HTTP and Stefil defines =describe= methods), those facility is made independently, and this feature is not much popular.

#+begin_src diff
COMMON-LISP:ASSOC
  [symbol]

ASSOC names a compiled function:
  Lambda-list: (ITEM ALIST &KEY KEY (TEST NIL TESTP)
                (TEST-NOT NIL NOTP))
  Declared type: (FUNCTION
                  (T LIST &KEY (:KEY (OR FUNCTION SYMBOL))
                   (:TEST (OR FUNCTION SYMBOL))
                   (:TEST-NOT (OR FUNCTION SYMBOL)))
                  (VALUES LIST &OPTIONAL))
  Documentation:
    Return the cons in ALIST whose car is equal (by a given test or EQL) to
       the ITEM.
  Known attributes: call, foldable, flushable, unsafely-flushable
  Source file: SYS:SRC;CODE;LIST.LISP

+Symbol ASSOC is bound in a namespace PATTERN:
+  Value: #
+  Documentation:
+    It matches when the object X is a list, and then further matches the contents
+    returned by (cdr (assoc item X...)) against SUBPATTERN.
+    If :KEY and :TEST is specified, they are passed to ASSOC.
#+end_src

Note that /namespace/ itself has its own namespace. The optional argument =documentation= to =define-namespace= is a docstring of the namespace itself. It will be set to =(setf (documentation NAME 'namespace) documentation)= and will also be visible from =describe=.

Examples are in [[EXAMPLE.org]] .

* Expected Usecase?

Every time you want to define a =define-cool-object= macro. E.g.,

+ in [[https://github.com/guicho271828/eazy-project][eazy-project]], [[https://github.com/guicho271828/eazy-project/blob/master/src/defmenu.lisp#L24][defmenu]]
+ in [[https://github.com/AccelerationNet/function-cache][function-cache]], [[https://github.com/AccelerationNet/function-cache/blob/master/src/cache.lisp#L4][defcached]] (currently implemented with hash tables)
+ in [[https://github.com/m2ym/optima][optima]], [[https://github.com/m2ym/optima/blob/master/src/pattern.lisp#L337][defpattern and pattern-expand-function]] (currently implemented
  with symbol properties)
+ in [[https://github.com/Bike/compiler-macro][compiler-macro]], [[https://github.com/Bike/compiler-macro/blob/master/hint.lisp#L10][define-compiler-hinter]] (currently implemented with hash tables)
+ in [[https://github.com/cffi/cffi][cffi]], [[https://github.com/cffi/cffi/blob/master/src/libraries.lisp#L129][define-foreign-library]] (currently implemented with hash tables)
 
* Other misc

** Macro NAMESPACE-LET / NSLET

=LET= with ability to lexically bind any value in the namespace.
It currently supports /function, labels, value, symbol-macro, macrolet,
restart, handler/ [2] namespaces and the user-defined namespaces.

Full examples are in [[EXAMPLE.org]] .

#+BEGIN_SRC lisp
(namespace-let ((#'x (y) (1+ y))
                ((macro x) (y) (1+ y))
                ((macro y) (y) (1+ y))
                (#'x (y) (1+ y))
                ((label y) (y) (y y))
                ((symbol-macro sm) 0)
                (b 0))
  (let ((b 1))
    (print :x)))

;; (PROGN
;;  (FLET ((X (Y) (1+ Y)))
;;    (MACROLET ((X (Y) (1+ Y))
;;               (Y (Y) (1+ Y))) ; same kinds of bindings are merged
;;      (FLET ((X (Y) (1+ Y)))
;;        (LABELS ((Y (Y) (Y Y)))
;;          (SYMBOL-MACROLET ((SM 0))
;;            (LET ((B 0))
;;              (PROGN
;;               (LET ((B 1))
;;                 (PRINT :X))))))))))
#+END_SRC

[2] restarts and handlers have the dynamic scope only.

** Package LISP-NAMESPACE

it has =(:nicknames lispn)= .



* Design?

I'm wondering which abbreviation to =namespace-let= is appropriate.
It should be something consistent with the historic name as =let=.
However, I do not like names like =let+= because they are not
self-expressive --- =let+= does not describe how it's different from the
original =let=.  =bind= and =where= are not considered good either, due to the
similar reason.

I adopted =nslet=, thanks to masatoi0@twitter's
advice. However, there is another alternative: Make it =let= and force the
user to shadow =cl:let=?  (nah I don't like it.)  I'm still searching for a
crazy bright idea.

Here are the remaining TODOs:

+ X-let does not recognize =(declare (special ...))= currently.

* Dependencies

This library is at least tested on implementation listed below:

+ SBCL 1.2.8 on X86 Linux 3.13.0-44-generic (author's environment)
+ CCL 1.10-r16196  (LinuxX8664)

Also, it depends on the following libraries:

+ alexandria by ** :
    Alexandria is a collection of portable public domain utilities.


* Author & Copyright

Copyright (c) 2015 Masataro Asai (guicho2.71828@gmail.com)

Licensed under the LLGPL License.


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 lisp-namespace

Author

Masataro Asai

Contact

guicho2.71828@gmail.com

License

LLGPL

Description

Provides LISP-N — extensible namespaces in Common Lisp.

Version

0.1

Dependency

alexandria

Source

lisp-namespace.asd (file)

Component

src (module)


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

3 Modules

Modules are listed depth-first from the system components tree.


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

3.1 lisp-namespace/src

Parent

lisp-namespace (system)

Location

src/

Components

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

4 Files

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


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

4.1 Lisp


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

4.1.1 lisp-namespace.asd

Location

lisp-namespace.asd

Systems

lisp-namespace (system)

Packages

lisp-namespace-asd


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

4.1.2 lisp-namespace/src/package.lisp

Parent

src (module)

Location

src/package.lisp

Packages

lisp-namespace

Exported Definitions

define-namespace (macro)

Internal Definitions

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

4.1.3 lisp-namespace/src/namespace.lisp

Dependency

package.lisp (file)

Parent

src (module)

Location

src/namespace.lisp

Exported Definitions

clear-namespace (function)

Internal Definitions

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

4.1.4 lisp-namespace/src/namespace-let.lisp

Dependency

namespace.lisp (file)

Parent

src (module)

Location

src/namespace-let.lisp

Exported Definitions
Internal Definitions

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

5 Packages

Packages are listed by definition order.


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

5.1 lisp-namespace-asd

Source

lisp-namespace.asd

Use List

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

5.2 lisp-namespace

This package provides a method to define additional namespaces for lisp.

Common lisp is lisp-2, which means it has a different namespaces for the value and the function. With lisp-namespace, you can define arbitrary additional namespaces and its accessors as well.

The idea is simple. Common lisp has ‘symbol-value’ and ‘symbol-function’, so I added ‘symbol-anything-you-like’. Current implementation is
built on a hashtable.

Source

package.lisp (file)

Nickname

lispn

Use List
Exported Definitions
Internal Definitions

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

6 Definitions

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


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

6.1 Exported definitions


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

6.1.1 Macros

Macro: define-namespace NAME &optional EXPECTED-TYPE NAMESPACE-LET DOCUMENTATION

This macro defines a namespace. For the given name of namespace X,
DEFINE-NAMESPACE defines 4 functions/macros:

+ #’SYMBOL-X, #’(setf SYMBOL-X) : accessor to the global binding. Optionally,
EXPECTED-TYPE provides FTYPE proclamation and results in the
better optimization. EXPECTED-TYPE is not evaluated.
+ #’X-BOUNDP : unary function returning a boolean
+ condition UNBOUND-X which is signaled when trying to access the value of an unbounded symbol. + macro (X-LET (binding...) body) : lexical binding. It is defined when BINDING is non-nil.

Package

lisp-namespace

Source

package.lisp (file)

Macro: namespace-let BINDINGS &body BODY

Bindings is a list of bindings where each car is of form (NAMESPACE NAME),
or a symbol NAME for a variable namespace.

function, macro, label, symbol-macro, handler, restart is by default recognized as a namespace.

Example:
(namespace-let ((#’x (y) (1+ y)) ; – equivalent to ((function x) (y) (1+ y))
((macro x) (y) (1+ y))
((macro y) (y) (1+ y))
(#’x (y) (1+ y))
((label y) (y) (y y))
((symbol-macro sm) 0)
(b 0))
(let ((b 1))
(print :x)))

Package

lisp-namespace

Source

namespace-let.lisp (file)

Macro: nslet BINDINGS &body BODY

Bindings is a list of bindings where each car is of form (NAMESPACE NAME),
or a symbol NAME for a variable namespace.

function, macro, label, symbol-macro, handler, restart is by default recognized as a namespace.

Example:
(namespace-let ((#’x (y) (1+ y)) ; – equivalent to ((function x) (y) (1+ y))
((macro x) (y) (1+ y))
((macro y) (y) (1+ y))
(#’x (y) (1+ y))
((label y) (y) (y y))
((symbol-macro sm) 0)
(b 0))
(let ((b 1))
(print :x)))

Package

lisp-namespace

Source

namespace-let.lisp (file)


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

6.1.2 Functions

Function: clear-namespace NAME

Get rid of all values bound in the given namespaces.

Package

lisp-namespace

Source

namespace.lisp (file)


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

6.2 Internal definitions


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

6.2.1 Special variables

Special Variable: *namespace-doc-table*
Package

lisp-namespace

Source

namespace.lisp (file)

Special Variable: *namespace-hash*
Package

lisp-namespace

Source

package.lisp (file)

Special Variable: *namespace-table*
Package

lisp-namespace

Source

namespace.lisp (file)


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

6.2.2 Functions

Function: %merge KIND NAME DEF BODY REST
Package

lisp-namespace

Source

namespace-let.lisp (file)

Function: %namespace NAME &aux ACCESSOR HASH CONDITION BOUNDP TYPE LETNAME DOC-TABLE
Package

lisp-namespace

Source

package.lisp (file)

Function: %namespace-accessor INSTANCE
Package

lisp-namespace

Source

package.lisp (file)

Function: %namespace-boundp INSTANCE
Package

lisp-namespace

Source

package.lisp (file)

Function: %namespace-condition INSTANCE
Package

lisp-namespace

Source

package.lisp (file)

Function: %namespace-doc-table INSTANCE
Package

lisp-namespace

Source

package.lisp (file)

Function: %namespace-hash INSTANCE
Package

lisp-namespace

Source

package.lisp (file)

Function: %namespace-letname INSTANCE
Package

lisp-namespace

Source

package.lisp (file)

Function: %namespace-name INSTANCE
Package

lisp-namespace

Source

package.lisp (file)

Function: %namespace-p OBJECT
Package

lisp-namespace

Source

package.lisp (file)

Function: %namespace-type INSTANCE
Package

lisp-namespace

Source

package.lisp (file)

Function: %pickone BINDINGS BODY
Package

lisp-namespace

Source

namespace-let.lisp (file)

Function: %wrap NAMESPACE NAME DEFINITION BODY
Package

lisp-namespace

Source

namespace-let.lisp (file)

Function: copy-%namespace INSTANCE
Package

lisp-namespace

Source

package.lisp (file)

Function: namespace-boundp SYMBOL

Automatically defined boolean function.

Package

lisp-namespace

Source

namespace.lisp (file)

Function: symbol-namespace SYMBOL &optional DEFAULT

Automatically defined getter function. When DEFAULT is supplied, the value is set automatically.

Package

lisp-namespace

Source

namespace.lisp (file)

Writer

(setf symbol-namespace) (function)

Function: (setf symbol-namespace) NEW-VALUE SYMBOL

Automatically defined setter function.

Package

lisp-namespace

Source

namespace.lisp (file)

Reader

symbol-namespace (function)


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

6.2.3 Conditions

Condition: unbound-namespace ()
Package

lisp-namespace

Source

namespace.lisp (file)

Direct superclasses

unbound-variable (condition)


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

6.2.4 Structures

Structure: %namespace ()
Package

lisp-namespace

Source

package.lisp (file)

Direct superclasses

structure-object (structure)

Direct methods
  • print-object (method)
  • make-load-form (method)
Direct slots
Slot: name
Type

symbol

Initform

(error "anonymous namespace?")

Readers

%namespace-name (function)

Writers

(setf %namespace-name) (function)

Slot: accessor
Type

symbol

Readers

%namespace-accessor (function)

Writers

(setf %namespace-accessor) (function)

Slot: hash
Type

symbol

Readers

%namespace-hash (function)

Writers

(setf %namespace-hash) (function)

Slot: condition
Type

symbol

Readers

%namespace-condition (function)

Writers

(setf %namespace-condition) (function)

Slot: boundp
Type

symbol

Readers

%namespace-boundp (function)

Writers

(setf %namespace-boundp) (function)

Slot: type
Type

symbol

Readers

%namespace-type (function)

Writers

(setf %namespace-type) (function)

Slot: letname
Type

symbol

Readers

%namespace-letname (function)

Writers

(setf %namespace-letname) (function)

Slot: doc-table
Type

symbol

Readers

%namespace-doc-table (function)

Writers

(setf %namespace-doc-table) (function)


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

6.2.5 Types

Type: namespace-type ()
Package

lisp-namespace

Source

namespace.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, lisp-namespace.asd: The lisp-namespace<dot>asd file
File, Lisp, lisp-namespace/src/namespace-let.lisp: The lisp-namespace/src/namespace-let<dot>lisp file
File, Lisp, lisp-namespace/src/namespace.lisp: The lisp-namespace/src/namespace<dot>lisp file
File, Lisp, lisp-namespace/src/package.lisp: The lisp-namespace/src/package<dot>lisp file

L
Lisp File, lisp-namespace.asd: The lisp-namespace<dot>asd file
Lisp File, lisp-namespace/src/namespace-let.lisp: The lisp-namespace/src/namespace-let<dot>lisp file
Lisp File, lisp-namespace/src/namespace.lisp: The lisp-namespace/src/namespace<dot>lisp file
Lisp File, lisp-namespace/src/package.lisp: The lisp-namespace/src/package<dot>lisp file
lisp-namespace.asd: The lisp-namespace<dot>asd file
lisp-namespace/src: The lisp-namespace/src module
lisp-namespace/src/namespace-let.lisp: The lisp-namespace/src/namespace-let<dot>lisp file
lisp-namespace/src/namespace.lisp: The lisp-namespace/src/namespace<dot>lisp file
lisp-namespace/src/package.lisp: The lisp-namespace/src/package<dot>lisp file

M
Module, lisp-namespace/src: The lisp-namespace/src module

Jump to:   F   L   M  

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

A.2 Functions

Jump to:   %   (  
C   D   F   M   N   S  
Index Entry  Section

%
%merge: Internal functions
%namespace: Internal functions
%namespace-accessor: Internal functions
%namespace-boundp: Internal functions
%namespace-condition: Internal functions
%namespace-doc-table: Internal functions
%namespace-hash: Internal functions
%namespace-letname: Internal functions
%namespace-name: Internal functions
%namespace-p: Internal functions
%namespace-type: Internal functions
%pickone: Internal functions
%wrap: Internal functions

(
(setf symbol-namespace): Internal functions

C
clear-namespace: Exported functions
copy-%namespace: Internal functions

D
define-namespace: Exported macros

F
Function, %merge: Internal functions
Function, %namespace: Internal functions
Function, %namespace-accessor: Internal functions
Function, %namespace-boundp: Internal functions
Function, %namespace-condition: Internal functions
Function, %namespace-doc-table: Internal functions
Function, %namespace-hash: Internal functions
Function, %namespace-letname: Internal functions
Function, %namespace-name: Internal functions
Function, %namespace-p: Internal functions
Function, %namespace-type: Internal functions
Function, %pickone: Internal functions
Function, %wrap: Internal functions
Function, (setf symbol-namespace): Internal functions
Function, clear-namespace: Exported functions
Function, copy-%namespace: Internal functions
Function, namespace-boundp: Internal functions
Function, symbol-namespace: Internal functions

M
Macro, define-namespace: Exported macros
Macro, namespace-let: Exported macros
Macro, nslet: Exported macros

N
namespace-boundp: Internal functions
namespace-let: Exported macros
nslet: Exported macros

S
symbol-namespace: Internal functions

Jump to:   %   (  
C   D   F   M   N   S  

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

A.3 Variables

Jump to:   *  
A   B   C   D   H   L   N   S   T  
Index Entry  Section

*
*namespace-doc-table*: Internal special variables
*namespace-hash*: Internal special variables
*namespace-table*: Internal special variables

A
accessor: Internal structures

B
boundp: Internal structures

C
condition: Internal structures

D
doc-table: Internal structures

H
hash: Internal structures

L
letname: Internal structures

N
name: Internal structures

S
Slot, accessor: Internal structures
Slot, boundp: Internal structures
Slot, condition: Internal structures
Slot, doc-table: Internal structures
Slot, hash: Internal structures
Slot, letname: Internal structures
Slot, name: Internal structures
Slot, type: Internal structures
Special Variable, *namespace-doc-table*: Internal special variables
Special Variable, *namespace-hash*: Internal special variables
Special Variable, *namespace-table*: Internal special variables

T
type: Internal structures

Jump to:   *  
A   B   C   D   H   L   N   S   T  

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

A.4 Data types

Jump to:   %  
C   L   N   P   S   T   U  
Index Entry  Section

%
%namespace: Internal structures

C
Condition, unbound-namespace: Internal conditions

L
lisp-namespace: The lisp-namespace system
lisp-namespace: The lisp-namespace package
lisp-namespace-asd: The lisp-namespace-asd package

N
namespace-type: Internal types

P
Package, lisp-namespace: The lisp-namespace package
Package, lisp-namespace-asd: The lisp-namespace-asd package

S
Structure, %namespace: Internal structures
System, lisp-namespace: The lisp-namespace system

T
Type, namespace-type: Internal types

U
unbound-namespace: Internal conditions

Jump to:   %  
C   L   N   P   S   T   U