All Projects → scymtym → trivial-with-current-source-form

scymtym / trivial-with-current-source-form

Licence: LGPL-3.0 License
Helps macro writers produce better errors for macro users

Programming Languages

common lisp
692 projects

Projects that are alternatives of or similar to trivial-with-current-source-form

Phpcompatibility
PHP Compatibility check for PHP_CodeSniffer
Stars: ✭ 1,705 (+7650%)
Mutual labels:  compatibility
php-compatinfo
Library that find out the minimum version and the extensions required for a piece of code to run
Stars: ✭ 361 (+1540.91%)
Mutual labels:  compatibility
oconfigure
configuration script for BSD.lv projects
Stars: ✭ 36 (+63.64%)
Mutual labels:  compatibility
Stylecow
Modern CSS to all browsers
Stars: ✭ 147 (+568.18%)
Mutual labels:  compatibility
Doesitarm
🦾 A list of reported app support for Apple Silicon and the new Apple M1 Macs
Stars: ✭ 3,200 (+14445.45%)
Mutual labels:  compatibility
emulatetab
A jQuery plugin to emulate tabbing between elements on a page.
Stars: ✭ 15 (-31.82%)
Mutual labels:  compatibility
Browsers Support Badges
Browsers support badges for GitHub
Stars: ✭ 122 (+454.55%)
Mutual labels:  compatibility
mpx-es-check
Checks the version of ES in JavaScript files with simple shell commands
Stars: ✭ 15 (-31.82%)
Mutual labels:  compatibility
dd86
No longer maintained. See URL.
Stars: ✭ 36 (+63.64%)
Mutual labels:  compatibility
license-compatibility
©️ Check compatibility between different SPDX licenses
Stars: ✭ 31 (+40.91%)
Mutual labels:  compatibility
Obsolete Webpack Plugin
🌈 A Webpack plugin generates a browser-side standalone script that detects browser compatibility based on `Browserslist` and prompts website users to upgrade it.
Stars: ✭ 148 (+572.73%)
Mutual labels:  compatibility
Shims
Seamless interop layer between cats and scalaz
Stars: ✭ 174 (+690.91%)
Mutual labels:  compatibility
PHPUnit-Polyfills
Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests
Stars: ✭ 147 (+568.18%)
Mutual labels:  compatibility
Caniuse.email
HTML and CSS Compatibility tables for emails
Stars: ✭ 133 (+504.55%)
Mutual labels:  compatibility
pg global temp tables
Oracle-style global temporary tables for PostgreSQL
Stars: ✭ 16 (-27.27%)
Mutual labels:  compatibility
Revapi
Revapi is an API analysis and change tracking tool written in Java. Its focus is mainly on Java language itself but it has been specifically designed to not be limited to just Java. API is much more than just java classes - also various configuration files, schemas, etc. can contribute to it and users can become reliant on them.
Stars: ✭ 122 (+454.55%)
Mutual labels:  compatibility
BedrockBackwards
Connects older clients to newer servers
Stars: ✭ 24 (+9.09%)
Mutual labels:  compatibility
graphene
Graphene / Graphene-SGX - a library OS for Linux multi-process applications, with Intel SGX support
Stars: ✭ 741 (+3268.18%)
Mutual labels:  compatibility
node-compat-require
Easily allow your Node program to run in a target node version range to maximize compatibility.
Stars: ✭ 22 (+0%)
Mutual labels:  compatibility
compat-db
A browser API compatibility database
Stars: ✭ 61 (+177.27%)
Mutual labels:  compatibility

Introduction

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

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

For example, consider the following macro

(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))))

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:

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

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:

(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))))

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 functionality as well:

pictures/better-expansion-error.png

Tutorial

Reference

with-current-source-form (FORM &REST FORMS) &BODY BODY

In a macroexpander, indicate that FORM, 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.
Note that the project description data, including the texts, logos, images, and/or trademarks, for each open source project belongs to its rightful owner. If you wish to add or remove any projects, please contact us at [email protected].