by Marc Nieper-Wißkirchen
This SRFI is currently in final status. Here is an explanation of each status that a SRFI can hold. To provide input on this SRFI, please send email to
firstname.lastname@example.org. To subscribe to the list, follow these instructions. You can access previous messages via the mailing list archive.
This SRFI introduces alias definitions, a syntactic extension. An alias definition transfers the binding of one identifier to another, effectively aliasing the identifier.
In standard Scheme, an identifier can either name a type of syntax or a location where a value can be stored. In the former case, the identifier is said to be bound to a transformer for that syntax, and in the latter case, the identifier is said to be bound to the location.
The (lexical) binding of an identifier is an expand-time property of the identifier, in contrast to the (dynamic) value stored in a location, which is a run-time property of the location.
New bindings are established through variable or syntax definitions. For example, a variable definition
(define variable expression)
creates a new location, binds the identifier
variable to it and stores the value
expression in the location.
(define variable1 variable2)
creates a new location
variable1 and copies
the value of
into it. Subsequently modifying the value
variable2 won't modify the
In contrast, the
alias definition introduced in
this SRFI transfers an existing binding to an identifier and
doesn't create a new one. For example,
(alias variable1 variable2)
doesn't create a new location
variable1 to the
particular, subsequently modifying the value
variable2 will modify the
Aliases allow one to locally alias identifiers under short names without changing the expanded version of the program:
(define *important-global-variable* '()) (define (setup!) (alias ls *important-global-variable*) (set! ls (cons 1 ls)) (set! ls (cons 2 ls))) (setup!) *important-global-variable* ⟹ (2 1)
Aliasing an unbound identifier is an error.
(alias x y) ⟹ error
Rebinding the aliased identifier doesn't change the binding of the aliasing identifier:
(let ((y +)) (alias x y) (let ((y *)) (free-identifier=? #'x #'y))) ⟹ #f
In particular, aliasing doesn't make the aliasing identifier equivalent to the aliased one in the sense that binding one would bind the other:
(let ((y +)) (alias x y) (bound-identifier=? #'x #'y)) ⟹ #f
The following expression, however, is invalid as it is an error for a definition to define an identifier whose binding has to be known in order to determine the meaning of any preceding definition that belongs to the same group of (internal) definitions:
(let ((y +)) (alias x y) (define y *) (free-identifier=? #'x #'y)) ⟹ error
Aliases can also be used to alias auxiliary syntax:
(alias inject unquote) `(list (inject (+ 1 2)) 4) ⟹ (list 3 4)
In macros, they can be used to inject bindings from the macro environment into the use environment:
(let ((y 1)) (let-syntax ((inject-y (syntax-rules () ((inject-y x) (alias x y))))) (let ((y 2)) (inject-y x) (set! x (* 3 x))) y)) ⟹ 3
Finally, the use of aliases is not limited to variables and keywords, but can also be used with other bindings like pattern variables:
(syntax-case #'pear () (pvar (let* () (alias fruit pvar) (syntax->datum #'(a fruit))))) ⟹ (a pear)
The alias definition is used to transfer the binding of one identifier to another. Like other definitions, it can appear either at the outermost level or in a body where other definitions can appear.
identifier2 is bound
to the location of a variable, the location of a pattern
variable, a type of syntax, a type of syntax parameter, or any
will be bound to the same quantity.
unbound, it is an error.
A portable Scheme implementation is not possible. An implementation of SRFI 212 is available in Unsyntax.
alias in its
The Kawa Scheme
language also contains an implementation of
albeit under the name
Test suite for an implementation.
The author got the idea from reading the manual of Chez Scheme by R. Kent Dybvig.
© 2020 Marc Nieper-Wißkirchen.
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice (including the next paragraph) shall be included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.