The trivial-with-current-source-form Reference Manual

Table of Contents

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

The trivial-with-current-source-form Reference Manual

This is the trivial-with-current-source-form Reference Manual, version 0.1.0, generated automatically by Declt version 3.0 "Montgomery Scott" on Tue Apr 28 13:14:07 2020 GMT+0.


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

1 Introduction

#+OPTIONS: toc:nil num:nil

* Introduction

  This library allows macro writers to provide better feedback to
  macro users when errors are signaled during macroexpansion.

  #+BEGIN_QUOTE
    Note: While this library can be loaded into and used in any Common
    Lisp implementation, the improved behavior described below is only
    available in SBCL and only in relatively recent versions (1.3.13
    and newer).
  #+END_QUOTE

  For example, consider the following macro 

  #+BEGIN_SRC lisp
    (defmacro even-number-case (value &body clauses)
      "Like `cl:case' but each key has to be an even number."
      (alexandria:once-only (value)
        `(cond ,@(mapcar (lambda (clause)
                           (destructuring-bind (number &rest body) clause
                             (unless (evenp number)
                               (error "Only even numbers are allowed."))
                             `((= ,value ,number)
                               ,@body)))
                         clauses))))
  #+END_SRC
  
  This is fine if the expansion does not signal an error. If it does,
  however, it is not immediately clear which of the clauses (if any)
  caused the error:

  #+BEGIN_SRC lisp
    (defun foo (x)
      (even-number-case x
        (2 :two)
        (4 :four)
        (5 :fix)
        (8 :eight)
        (10 :ten)))
  #+END_SRC

  [[file:pictures/bad-expansion-error.png]]

  The problem is not very hard to spot in the above code, but think of
  macros for declaring complex things like ~cl:defpackage~ or
  ~cl:defclass~ or macros for domain specific languages and the
  problem becomes more severe.

  The mechanism provided by this library is the
  ~with-current-source-form~ macro. The macro is intended to surround
  parts of macro expanders that process certain sub-forms of the form
  passed to the expander:
  
  #+BEGIN_SRC lisp
    (defmacro even-number-case (value &body clauses)
      "Like `cl:case' but each key has to be an even number."
      (alexandria:once-only (value)
        `(cond ,@(mapcar (lambda (clause)
                           (trivial-with-current-source-form:with-current-source-form (clause)
                             (destructuring-bind (number &rest body) clause
                               (unless (evenp number)
                                 (error "Only even numbers are allowed."))
                               `((= ,value ,number)
                                 ,@body))))
                         clauses))))
  #+END_SRC
  
  The effect of the above change is that the implementation can now
  report a more useful location when reporting the error during macro
  expansion. Other tools like SLIME benefit from this as well:

  [[file:pictures/better-expansion-error.png]]

* TODO Tutorial

* Reference

  #+BEGIN_SRC lisp :results none :exports none
    #.(progn
        #1=(ql:quickload '(:trivial-with-current-source-form :alexandria :split-sequence))
        '#1#)
    (defun doc (symbol kind)
      (let* ((lambda-list (sb-introspect:function-lambda-list symbol))
             (string      (documentation symbol kind))
             (lines       (split-sequence:split-sequence #\Newline string))
             (trimmed     (mapcar (alexandria:curry #'string-left-trim '(#\Space)) lines)))
        (format nil "~(~A~) ~<~{~A~^ ~}~:@>~2%~{~A~^~%~}"
                symbol (list lambda-list) trimmed)))
  #+END_SRC

  #+BEGIN_SRC lisp :results value :exports results
    (doc 'trivial-with-current-source-form:with-current-source-form 'function)
  #+END_SRC

  #+RESULTS:
  #+BEGIN_EXAMPLE
  with-current-source-form (FORM &REST FORMS) &BODY BODY

  In a macroexpander, indicate that FORMS are being processed by BODY.

  FORMS are usually sub-forms of the whole form passed to the expander.

  If more than one form is supplied, FORMS should be ordered by
  specificity, with the most specific form first. This allows the
  compiler to try and obtain a source path using subsequent elements of
  FORMS if it fails for the first one.

  Indicating the processing of sub-forms lets the compiler report
  precise source locations in case conditions are signaled during the
  execution of BODY.
  #+END_EXAMPLE


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 trivial-with-current-source-form

Author

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

License

GPLv3

Description

Helps macro writers produce better errors for macro users

Version

0.1.0

Dependency

alexandria

Source

trivial-with-current-source-form.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 trivial-with-current-source-form/src

Parent

trivial-with-current-source-form (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 trivial-with-current-source-form.asd

Location

trivial-with-current-source-form.asd

Systems

trivial-with-current-source-form (system)


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

4.1.2 trivial-with-current-source-form/src/package.lisp

Parent

src (module)

Location

src/package.lisp

Packages

trivial-with-current-source-form


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

4.1.3 trivial-with-current-source-form/src/sbcl.lisp

If Feature

sbcl

Dependency

package.lisp (file)

Parent

src (module)

Location

src/sbcl.lisp

Internal Definitions

expand (function)


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

4.1.4 trivial-with-current-source-form/src/clasp.lisp

If Feature

clasp

Dependency

sbcl.lisp (file)

Parent

src (module)

Location

src/clasp.lisp


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

4.1.5 trivial-with-current-source-form/src/unsupported.lisp

If Feature

(not (or clasp sbcl))

Dependency

clasp.lisp (file)

Parent

src (module)

Location

src/unsupported.lisp


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

4.1.6 trivial-with-current-source-form/src/macro.lisp

Dependency

unsupported.lisp (file)

Parent

src (module)

Location

src/macro.lisp

Exported Definitions

with-current-source-form (macro)


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

5 Packages

Packages are listed by definition order.


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

5.1 trivial-with-current-source-form

Source

package.lisp (file)

Use List

common-lisp

Exported Definitions

with-current-source-form (macro)

Internal Definitions

expand (function)


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


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

6.1.1 Macros

Macro: with-current-source-form (FORM &rest FORMS) &body BODY

In a macroexpander, indicate that FORMS are being processed by BODY.

FORMS are usually sub-forms of the whole form passed to the expander.

If more than one form is supplied, FORMS should be ordered by specificity, with the most specific form first. This allows the compiler to try and obtain a source path using subsequent elements of FORMS if it fails for the first one.

Indicating the processing of sub-forms lets the compiler report precise source locations in case conditions are signaled during the execution of BODY.

Package

trivial-with-current-source-form

Source

macro.lisp (file)


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

6.2 Internal definitions


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

6.2.1 Functions

Function: expand FORMS BODY
Package

trivial-with-current-source-form

Source

sbcl.lisp (file)


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

Appendix A Indexes


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

A.1 Concepts

Jump to:   F   L   M   T  
Index Entry  Section

F
File, Lisp, trivial-with-current-source-form.asd: The trivial-with-current-source-form․asd file
File, Lisp, trivial-with-current-source-form/src/clasp.lisp: The trivial-with-current-source-form/src/clasp․lisp file
File, Lisp, trivial-with-current-source-form/src/macro.lisp: The trivial-with-current-source-form/src/macro․lisp file
File, Lisp, trivial-with-current-source-form/src/package.lisp: The trivial-with-current-source-form/src/package․lisp file
File, Lisp, trivial-with-current-source-form/src/sbcl.lisp: The trivial-with-current-source-form/src/sbcl․lisp file
File, Lisp, trivial-with-current-source-form/src/unsupported.lisp: The trivial-with-current-source-form/src/unsupported․lisp file

L
Lisp File, trivial-with-current-source-form.asd: The trivial-with-current-source-form․asd file
Lisp File, trivial-with-current-source-form/src/clasp.lisp: The trivial-with-current-source-form/src/clasp․lisp file
Lisp File, trivial-with-current-source-form/src/macro.lisp: The trivial-with-current-source-form/src/macro․lisp file
Lisp File, trivial-with-current-source-form/src/package.lisp: The trivial-with-current-source-form/src/package․lisp file
Lisp File, trivial-with-current-source-form/src/sbcl.lisp: The trivial-with-current-source-form/src/sbcl․lisp file
Lisp File, trivial-with-current-source-form/src/unsupported.lisp: The trivial-with-current-source-form/src/unsupported․lisp file

M
Module, trivial-with-current-source-form/src: The trivial-with-current-source-form/src module

T
trivial-with-current-source-form.asd: The trivial-with-current-source-form․asd file
trivial-with-current-source-form/src: The trivial-with-current-source-form/src module
trivial-with-current-source-form/src/clasp.lisp: The trivial-with-current-source-form/src/clasp․lisp file
trivial-with-current-source-form/src/macro.lisp: The trivial-with-current-source-form/src/macro․lisp file
trivial-with-current-source-form/src/package.lisp: The trivial-with-current-source-form/src/package․lisp file
trivial-with-current-source-form/src/sbcl.lisp: The trivial-with-current-source-form/src/sbcl․lisp file
trivial-with-current-source-form/src/unsupported.lisp: The trivial-with-current-source-form/src/unsupported․lisp file

Jump to:   F   L   M   T  

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

A.2 Functions

Jump to:   E   F   M   W  
Index Entry  Section

E
expand: Internal functions

F
Function, expand: Internal functions

M
Macro, with-current-source-form: Exported macros

W
with-current-source-form: Exported macros

Jump to:   E   F   M   W  

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

A.3 Variables


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

A.4 Data types

Jump to:   P   S   T  
Index Entry  Section

P
Package, trivial-with-current-source-form: The trivial-with-current-source-form package

S
System, trivial-with-current-source-form: The trivial-with-current-source-form system

T
trivial-with-current-source-form: The trivial-with-current-source-form system
trivial-with-current-source-form: The trivial-with-current-source-form package

Jump to:   P   S   T