Next: Introduction, Previous: (dir), Up: (dir) [Contents][Index]
This is the trivial-with-current-source-form Reference Manual, version 0.1.0, generated automatically by Declt version 3.0 "Montgomery Scott" on Mon Apr 19 18:08:27 2021 GMT+0.
• Introduction | What trivial-with-current-source-form is all about | |
• Systems | The systems documentation | |
• Modules | The modules documentation | |
• Files | The files documentation | |
• Packages | The packages documentation | |
• Definitions | The symbols documentation | |
• Indexes | Concepts, functions, variables and data types |
#+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: Modules, Previous: Introduction, Up: Top [Contents][Index]
The main system appears first, followed by any subsystem dependency.
• The trivial-with-current-source-form system |
Jan Moringen <jmoringe@techfak.uni-bielefeld.de>
GPLv3
Helps macro writers produce better errors for macro users
0.1.0
alexandria
src (module)
Modules are listed depth-first from the system components tree.
• The trivial-with-current-source-form/src module |
trivial-with-current-source-form (system)
src/
Files are sorted by type and then listed depth-first from the systems components trees.
• Lisp files |
Next: The trivial-with-current-source-form/src/package․lisp file, Previous: Lisp files, Up: Lisp files [Contents][Index]
trivial-with-current-source-form.asd
trivial-with-current-source-form (system)
Next: The trivial-with-current-source-form/src/sbcl․lisp file, Previous: The trivial-with-current-source-form․asd file, Up: Lisp files [Contents][Index]
src (module)
src/package.lisp
Next: The trivial-with-current-source-form/src/clasp․lisp file, Previous: The trivial-with-current-source-form/src/package․lisp file, Up: Lisp files [Contents][Index]
sbcl
package.lisp (file)
src (module)
src/sbcl.lisp
expand (function)
Next: The trivial-with-current-source-form/src/unsupported․lisp file, Previous: The trivial-with-current-source-form/src/sbcl․lisp file, Up: Lisp files [Contents][Index]
clasp
src (module)
src/clasp.lisp
Next: The trivial-with-current-source-form/src/macro․lisp file, Previous: The trivial-with-current-source-form/src/clasp․lisp file, Up: Lisp files [Contents][Index]
(not (or clasp sbcl))
src (module)
src/unsupported.lisp
Previous: The trivial-with-current-source-form/src/unsupported․lisp file, Up: Lisp files [Contents][Index]
src (module)
src/macro.lisp
with-current-source-form (macro)
Next: Definitions, Previous: Files, Up: Top [Contents][Index]
Packages are listed by definition order.
• The trivial-with-current-source-form package |
package.lisp (file)
common-lisp
with-current-source-form (macro)
expand (function)
Definitions are sorted by export status, category, package, and then by lexicographic order.
• Exported definitions | ||
• Internal definitions |
Next: Internal definitions, Previous: Definitions, Up: Definitions [Contents][Index]
• Exported macros |
Previous: Exported definitions, Up: Exported definitions [Contents][Index]
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.
macro.lisp (file)
Previous: Exported definitions, Up: Definitions [Contents][Index]
• Internal functions |
Previous: Internal definitions, Up: Internal definitions [Contents][Index]
sbcl.lisp (file)
Previous: Definitions, Up: Top [Contents][Index]
• Concept index | ||
• Function index | ||
• Variable index | ||
• Data type index |
Next: Function index, Previous: Indexes, Up: Indexes [Contents][Index]
Jump to: | F L M T |
---|
Jump to: | F L M T |
---|
Next: Variable index, Previous: Concept index, Up: Indexes [Contents][Index]
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: Data type index, Previous: Function index, Up: Indexes [Contents][Index]
Previous: Variable index, Up: Indexes [Contents][Index]
Jump to: | P S T |
---|
Jump to: | P S T |
---|