The utilities.print-items Reference Manual

Table of Contents

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

The utilities.print-items Reference Manual

This is the utilities.print-items Reference Manual, version 0.2.0, generated automatically by Declt version 3.0 "Montgomery Scott" on Tue Apr 28 13:16:24 2020 GMT+0.


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

1 Introduction

#+TITLE:       utilities.print-items README
#+AUTHOR:      Jan Moringen
#+EMAIL:       jmoringe@techfak.uni-bielefeld.de
#+DESCRIPTION: Composable, unreadable printing of objects
#+KEYWORDS:    print-items, composable printing, print-object, utilities
#+LANGUAGE:    en

#+OPTIONS: num:nil

* Introduction

  The =utilities.print-items= system provides a protocol for flexible
  and composable printing, primarily unreadable printing.

  Why is this useful? Common Lisp has the generic function
  ~cl:print-object~, which is often used to print compact and
  intuitive yet unreadable representations of objects. Thanks to CLOS,
  considerable flexibility and composability would, in principle, be
  achievable. However, a common idiom is

  #+BEGIN_SRC lisp
    (defmethod print-object ((object CLASS) stream)
      (print-unreadable-object (stream :type t :id t)
        CODE))
  #+END_SRC

  which prevents CLOS' flexibility from actually being used:

  + Calling the next method in a ~print-object~ method would either
    wrap the final result in multiple layers of
    ~print-unreadable-object~ or some of the method would not be fully
    functional on their own.

  + Similarly, ~:before~ and ~:after~ methods on ~print-object~ would
    produce output parts outside of the prefix and suffix produced by
    ~print-unreadable-object~.

  #+ATTR_HTML: :alt "build status image" :title Build Status :align right
  [[https://travis-ci.org/scymtym/utilities.print-items][https://travis-ci.org/scymtym/utilities.print-items.svg]]

* Tutorial

  To illustrate the problem and the solution offered by the
  =utilities.print-items= system more concretely, consider the
  following example:

  #+BEGIN_SRC lisp :exports both :results silent
    (defclass name-mixin ()
      ((name :initarg :name :reader name)))

    (defclass value-mixin ()
      ((value :initarg :value :reader value)))

    (defclass binding (name-mixin value-mixin)
      ())
  #+END_SRC

** The Problem

   Due to the issues mentioned [[*Introduction][above]], =print-object=-based solutions
   are not satisfactory:

   #+BEGIN_SRC lisp :exports both :results value
     (defmethod print-object ((object name-mixin) stream)
       (format stream "~S" (name object))
       (when (next-method-p)
         (call-next-method)))

     (defmethod print-object ((object value-mixin) stream)
       (format stream "= ~S" (value object))
       (when (next-method-p)
         (call-next-method)))

     (princ-to-string (make-instance 'binding :name "foo" :value 5))
   #+END_SRC

   #+RESULTS:
   : "foo"= 5#

   This is somewhat composable and the output has all expected parts,
   but the arrangement of the output parts is completely wrong as well
   as hard to control.

   #+BEGIN_SRC lisp :exports results :results silent
     (ignore-errors
      (remove-method #'print-object (find-method #'print-object '() (list (find-class 'name-mixin) (find-class 't)))))
     (ignore-errors
      (remove-method #'print-object (find-method #'print-object '() (list (find-class 'value-mixin) (find-class 't)))))
   #+END_SRC

   The opposite approach would be:

   #+BEGIN_SRC lisp :exports both :results value
     (defmethod print-object ((object binding) stream)
       (print-unreadable-object (object stream :type t :identity t)
         (format stream "~S = ~S" (name object) (value object))))

     (princ-to-string (make-instance 'binding :name "foo" :value 5))
   #+END_SRC

   #+RESULTS:
   : #

   This produces the expected result but is not composable at all
   since every user of ~name-mixin~ and ~value-mixin~ has to do all
   the printing itself.

   #+BEGIN_SRC lisp :exports results :results silent
     (ignore-errors
      (remove-method #'print-object (find-method #'print-object '() (list (find-class binding) (find-class 't)))))
   #+END_SRC

** The Solution

   When using the =utilities.print-items= system, ~print-object~
   methods are replaced by ~print-items:print-items~ methods (note the
   ~append~ method combination) for mixin classes:

   #+BEGIN_SRC lisp :exports both :results value
     (defclass name-mixin ()
       ((%name :initarg :name :reader name)))

     (defmethod print-items:print-items append ((object name-mixin))
       `((:name ,(name object) "~S")))

     (defclass value-mixin ()
       ((%value :initarg :value :reader value)))

     (defmethod print-items:print-items append ((object value-mixin))
       `((:value ,(value object) "= ~S")))

     (defclass binding (name-mixin value-mixin)
       ())

     (defmethod print-object ((object binding) stream)
       (print-unreadable-object (object stream :type t :identity t)
         (print-items:format-print-items stream (print-items:print-items object))))

     (princ-to-string (make-instance 'binding :name "foo" :value 5))
   #+END_SRC

   #+RESULTS:
   : #

   #+BEGIN_SRC lisp :exports results :results silent
     (ignore-errors
      (remove-method #'print-object (find-method #'print-object '() (list (find-class binding) (find-class 't)))))
   #+END_SRC

   This solves the problem of composability and getting all output
   parts between the prefix and suffix produced by
   ~print-unreadable-object~, but the arrangement of output parts is
   not ideal. We could improve the situation by tweaking the order of
   elements in the superclass list of ~binding~ but that would be
   intrusive and again not composable when, for example, subclasses of
   ~binding~ are defined. Furthermore, the ~print-object~ method does
   not do anything specific to ~binding~.

   The following adjustments solve both issues (changes in upper
   case):

   #+BEGIN_SRC lisp :exports both :results value
     (defmethod print-items:print-items append ((object value-mixin))
       `((:value ,(value object) " = ~S" ((:AFTER :NAME)))))

     (defclass binding (name-mixin value-mixin PRINT-ITEMS:PRINT-ITEMS-MIXIN)
       ())

     ;; no PRINT-OBJECT method for BINDING

     (princ-to-string (make-instance 'binding :name "foo" :value 5))
   #+END_SRC

   #+RESULTS:
   : #

   Constraints such as ~(:after :name)~ control the order of
   items. Constraints referring to absent items have no
   effect. Contradictory constraints cause an error to be signaled.

** Advanced Usage

   It is sometimes necessary to modify the print items produced by
   superclasses to get the desired printed representation. This can be
   achieved in two ways:

   1. By defining a ~print-items:print-items append~ method that
      returns replacements for the undesired items:

      #+BEGIN_SRC lisp :exports both :results value
        (defclass unnamed-binding (binding)
          ())

        (defmethod print-items:print-items append ((object unnamed-binding))
          `((:name nil "«unnamed»")))

        (princ-to-string (make-instance 'unnamed-binding :name nil :value 5))
      #+END_SRC

      #+RESULTS:
      : #

      #+BEGIN_SRC lisp :exports results :results silent
        (ignore-errors
         (remove-method #'print-items:print-items (find-method #'print-items:print-items '(append) (list (find-class 'unnamed-binding)))))
      #+END_SRC

   2. By defining a ~print-items:print-items :around~ method that
      explicitly modifies the complete item list:

      #+BEGIN_SRC lisp :exports both :results value
        (defclass unnamed-binding (binding)
          ())

        (defmethod print-items:print-items :around ((object unnamed-binding))
          (remove :name (call-next-method) :key #'first))

        (princ-to-string (make-instance 'unnamed-binding :name nil :value 5))
      #+END_SRC

      #+RESULTS:
      : #

      #+BEGIN_SRC lisp :exports results :results silent
        (ignore-errors
         (remove-method #'print-items:print-items (find-method #'print-items:print-items '(:around) (list (find-class 'unnamed-binding)))))
      #+END_SRC

* Reference

  The =utilities.print-items= system provides the following protocol
  for composable printing:

  * =print-items:print-items OBJECT [generic function]=

    Return a list of items that should appear in the printed
    representation of =OBJECT=.

    Each method should return a list of items of the form

    #+BEGIN_EXAMPLE
      (KEY VALUE [FORMAT [(CONSTRAINT*)]]
    #+END_EXAMPLE

    where

    #+BEGIN_EXAMPLE
      KEY        ::= any Lisp object
      VALUE      ::= any Lisp object
      FORMAT     ::= nil or a format string (Default is \"~A\")

      CONSTRAINT ::= (:before | :after) KEY
    #+END_EXAMPLE

    When multiple items have =cl:eql= =KEY= s, items appearing closer
    to the beginning of the item list take precedence. This mechanism
    can be used by subclasses to replace print items produced by
    superclasses.

    When =FORMAT= is =nil=, the whole item is ignored. This mechanism
    can be used by subclasses to disable print items produced by
    superclasses.

  * =print-items:print-items-mixin [class]=

    This mixin class adds printing via =print-items= to classes.

    Subclasses can define methods on =print-items:print-items= to
    change or extend the printed representation.

  * =print-items:format-print-items STREAM ITEMS &optional COLON? AT? [function]=

    This utility function prints items in the format constructed by
    the =print-items= functions to a stream.

    It is used to implement the =cl:print-object= method for
    =print-items-mixin=.


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 utilities.print-items

Maintainer

Jan Moringen <jmoringe@techfak.uni-bielefeld.de>

Author

Jan Moringen <jmoringe@techfak.uni-bielefeld.de>

License

LLGPLv3

Description

A protocol for flexible and composable printing.

Version

0.2.0

Dependency

alexandria

Source

utilities.print-items.asd (file)

Components

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 utilities.print-items/src

Parent

utilities.print-items (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.


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

4.1 Lisp


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

4.1.1 utilities.print-items.asd

Location

utilities.print-items.asd

Systems

utilities.print-items (system)


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

4.1.2 utilities.print-items/src/package.lisp

Parent

src (module)

Location

src/package.lisp

Packages

utilities.print-items


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

4.1.3 utilities.print-items/src/util.lisp

Dependency

package.lisp (file)

Parent

src (module)

Location

src/util.lisp

Internal Definitions

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

4.1.4 utilities.print-items/src/protocol.lisp

Dependency

util.lisp (file)

Parent

src (module)

Location

src/protocol.lisp

Exported Definitions

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

4.2 Static


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

4.2.1 utilities.print-items/README.org

Parent

utilities.print-items (system)

Location

README.org


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

5 Packages

Packages are listed by definition order.


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

5.1 utilities.print-items

Utilities for composable printing.

The interface consists of

* ‘print-items’ [generic function]

Methods extend the printed representation of an object in a composable manner.

* ‘print-items-mixin’ [class]

Can be used to make subclasses the print items mechanism when passed to ‘print-object’.

* ‘format-print-items’ [function]

Utility function for formatting print items onto a stream.

Source

package.lisp (file)

Nickname

print-items

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 Functions

Function: format-print-items STREAM ITEMS &optional COLON? AT?

Print ITEMS onto STREAM.

ITEMS is a list of items of the form

(KEY VALUE [FORMAT [(CONSTRAINT*)]]

where

KEY ::= any Lisp object
VALUE ::= any Lisp object
FORMAT ::= ‘nil’ or a format string (Default is "~A")

CONSTRAINT ::= (:before | :after) KEY

Package

utilities.print-items

Source

protocol.lisp (file)


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

6.1.2 Generic functions

Generic Function: print-items OBJECT

Return a list of items that should appear in the printed representation of OBJECT.

Each method should return a list of items of the form

(KEY VALUE [FORMAT [(CONSTRAINT*)]]

where

KEY ::= any Lisp object
VALUE ::= any Lisp object
FORMAT ::= ‘nil’ or a format string (Default is "~A")

CONSTRAINT ::= (:before | :after) KEY

When multiple items have ‘eql’ KEYs, items appearing closer to the beginning of the item list take precedence. This mechanism can be used by subclasses to replace print items produced by superclasses.

When FORMAT is ‘nil’ the whole item is ignored. This mechanism can be used by subclasses to disable print items produced by superclasses.

Package

utilities.print-items

Source

protocol.lisp (file)

Method Combination

append (short method combination)

Options: :most-specific-first

Methods
Method: print-items OBJECT append

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

6.1.3 Classes

Class: print-items-mixin ()

This mixin class adds printing via ‘print-items’ to classes.

Package

utilities.print-items

Source

protocol.lisp (file)

Direct superclasses

standard-object (class)

Direct methods

print-object (method)


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

6.2 Internal definitions


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

6.2.1 Functions

Function: item-< LEFT RIGHT

Return non-nil if the left item should be placed before the right.

Package

utilities.print-items

Source

util.lisp (file)

Function: make-node OBJECT
Package

utilities.print-items

Source

util.lisp (file)

Function: node-edges INSTANCE
Function: (setf node-edges) VALUE INSTANCE
Package

utilities.print-items

Source

util.lisp (file)

Function: node-object INSTANCE
Package

utilities.print-items

Source

util.lisp (file)

Function: node-state INSTANCE
Function: (setf node-state) VALUE INSTANCE
Package

utilities.print-items

Source

util.lisp (file)

Function: sort-with-partial-order SEQUENCE PREDICATE
Package

utilities.print-items

Source

util.lisp (file)

Function: topological-sort NODES
Package

utilities.print-items

Source

util.lisp (file)


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

6.2.2 Generic functions

Generic Function: cycle-error-path CONDITION
Package

utilities.print-items

Methods
Method: cycle-error-path (CONDITION cycle-error)
Source

util.lisp (file)


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

6.2.3 Conditions

Condition: cycle-error ()
Package

utilities.print-items

Source

util.lisp (file)

Direct superclasses

error (condition)

Direct methods

cycle-error-path (method)

Direct slots
Slot: %path
Initargs

:path

Readers

cycle-error-path (generic function)

Direct Default Initargs
InitargValue
:path(error "missing required initarg for class ~s: ~s" (quote utilities.print-items::cycle-error) :path)

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

6.2.4 Structures

Structure: node ()
Package

utilities.print-items

Source

util.lisp (file)

Direct superclasses

structure-object (structure)

Direct slots
Slot: object
Readers

node-object (function)

Writers

(setf node-object) (function)

Slot: edges
Type

list

Initform

(quote nil)

Readers

node-edges (function)

Writers

(setf node-edges) (function)

Slot: state
Type

(member :new :in-progress :done)

Initform

:new

Readers

node-state (function)

Writers

(setf node-state) (function)


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

Appendix A Indexes


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

A.1 Concepts

Jump to:   F   L   M   S   U  
Index Entry  Section

F
File, Lisp, utilities.print-items.asd: The utilities․print-items․asd file
File, Lisp, utilities.print-items/src/package.lisp: The utilities․print-items/src/package․lisp file
File, Lisp, utilities.print-items/src/protocol.lisp: The utilities․print-items/src/protocol․lisp file
File, Lisp, utilities.print-items/src/util.lisp: The utilities․print-items/src/util․lisp file
File, static, utilities.print-items/README.org: The utilities․print-items/readme․org file

L
Lisp File, utilities.print-items.asd: The utilities․print-items․asd file
Lisp File, utilities.print-items/src/package.lisp: The utilities․print-items/src/package․lisp file
Lisp File, utilities.print-items/src/protocol.lisp: The utilities․print-items/src/protocol․lisp file
Lisp File, utilities.print-items/src/util.lisp: The utilities․print-items/src/util․lisp file

M
Module, utilities.print-items/src: The utilities․print-items/src module

S
Static File, utilities.print-items/README.org: The utilities․print-items/readme․org file

U
utilities.print-items.asd: The utilities․print-items․asd file
utilities.print-items/README.org: The utilities․print-items/readme․org file
utilities.print-items/src: The utilities․print-items/src module
utilities.print-items/src/package.lisp: The utilities․print-items/src/package․lisp file
utilities.print-items/src/protocol.lisp: The utilities․print-items/src/protocol․lisp file
utilities.print-items/src/util.lisp: The utilities․print-items/src/util․lisp file

Jump to:   F   L   M   S   U  

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

A.2 Functions

Jump to:   (  
C   F   G   I   M   N   P   S   T  
Index Entry  Section

(
(setf node-edges): Internal functions
(setf node-state): Internal functions

C
cycle-error-path: Internal generic functions
cycle-error-path: Internal generic functions

F
format-print-items: Exported functions
Function, (setf node-edges): Internal functions
Function, (setf node-state): Internal functions
Function, format-print-items: Exported functions
Function, item-<: Internal functions
Function, make-node: Internal functions
Function, node-edges: Internal functions
Function, node-object: Internal functions
Function, node-state: Internal functions
Function, sort-with-partial-order: Internal functions
Function, topological-sort: Internal functions

G
Generic Function, cycle-error-path: Internal generic functions
Generic Function, print-items: Exported generic functions

I
item-<: Internal functions

M
make-node: Internal functions
Method, cycle-error-path: Internal generic functions
Method, print-items: Exported generic functions

N
node-edges: Internal functions
node-object: Internal functions
node-state: Internal functions

P
print-items: Exported generic functions
print-items: Exported generic functions

S
sort-with-partial-order: Internal functions

T
topological-sort: Internal functions

Jump to:   (  
C   F   G   I   M   N   P   S   T  

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

A.3 Variables

Jump to:   %  
E   O   S  
Index Entry  Section

%
%path: Internal conditions

E
edges: Internal structures

O
object: Internal structures

S
Slot, %path: Internal conditions
Slot, edges: Internal structures
Slot, object: Internal structures
Slot, state: Internal structures
state: Internal structures

Jump to:   %  
E   O   S  

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

A.4 Data types

Jump to:   C   N   P   S   U  
Index Entry  Section

C
Class, print-items-mixin: Exported classes
Condition, cycle-error: Internal conditions
cycle-error: Internal conditions

N
node: Internal structures

P
Package, utilities.print-items: The utilities․print-items package
print-items-mixin: Exported classes

S
Structure, node: Internal structures
System, utilities.print-items: The utilities․print-items system

U
utilities.print-items: The utilities․print-items system
utilities.print-items: The utilities․print-items package

Jump to:   C   N   P   S   U