by Lassi Kortela
This SRFI codifies the following shorthand syntax, which some Scheme implementations have had for a long time.
(define ((outer-name outer-args ...) inner-args ...) inner-body ...)
Procedures that make other procedures are commonly used in Scheme. A shorthand syntax makes them easier to define, obviating the need to write a lambda inside a lambda.
Recall that RnRS defines a standard shorthand whereby the code:
(define foo (lambda (a b c) body ...))
can be abbreviated as:
(define (foo a b c) body ...)
This SRFI defines an additional shorthand which is an extrapolation of the standard one. The code:
(define (foo a b c) (lambda (d e f) body ...))
can be abbreviated as:
(define ((foo a b c) d e f) body ...)
Apart from helping define higher-order functions, the additional shorthand syntax partially applies to the task of making partially applied functions in Scheme.
The following Scheme implementations have the shorthand syntax built in:
The following implementations don't have it: Bigloo, BiwaScheme, Chez Scheme, Chibi-Scheme, Cyclone, Gambit, Gerbil, Guile, Ikarus, IronScheme, Kawa, Loko, Mosh, s7, Scheme 48, SigScheme, STklos, TinyScheme, Vicare, Ypsilon.
Since the shorthand is non-standard (i.e. not defined in RnRS), it can be controversial or confusing to the uninitiated programmer.
This SRFI handles the conflict by storing the shorthand
define in a library that does not have to
be imported by default. Then programmers can choose whether to
import it or not. In portable code the
to document the dependency on this SRFI.
The shorthand version of
define behaves according
to the following
(define-syntax define (syntax-rules () ((define ((name args ... . tail) xargs ... . xtail) xbody ...) (define/native (name args ... . tail) (lambda (xargs ... . xtail) xbody ...))) ((define ((name args ... . tail) xargs ...) xbody ...) (define/native (name args ... . tail) (lambda (xargs ...) xbody ...))) ((define ((name args ...) xargs ... . xtail) xbody ...) (define/native (name args ...) (lambda (xargs ... . xtail) xbody ...))) ((define ((name args ...) xargs ...) xbody ...) (define/native (name args ...) (lambda (xargs ...) xbody ...))) ((define other-things ...) (define/native other-things ...))))
define/native is the implementation's
native version of
define. The native
define can be equivalent to the
from a RnRS report, or may have extensions to
In R6RS Scheme implementations, the shorthand
define is exported from the library
(srfi :NNN). In R7RS Scheme
implementations, it is exported from the library
The shorthand version of
define is exported under
define, which means that it shadows
define may also be imported from
libraries, possibly under other names.
This SRFI does not say whether or not the shorthand
define is imported into the default interaction
(define ((greet-with-prefix prefix) suffix) (string-append prefix " " suffix)) (define greet (greet-with-prefix "Hello")) (greet "there!") => "Hello there!"
With a dotted list to take a variable number of arguments:
(define ((append-to . a) . b) (apply append (append a b))) ((append-to)) => () ((append-to '(1 2) '(3 4)) '(5 6) '(7 8)) => (1 2 3 4 5 6 7 8)
To avoid the name conflict between RnRS
define and this SRFI's
program using this SRFI should import the
RnRS base library as:
(import (except (rnrs) define))
(import (except (scheme base) define))
Alternatively, Scheme's import renaming can be used to import
define under a different name, in
which case the same program can alternate between using the
define and RnRS
define. For example:
(import (rename (srfi :NNN) (define define/higher)))
(import (rename (srfi NNN) (define define/higher)))
R6RS and R7RS libraries using
syntax-rules are attached.
Thanks to Arthur Gleckler for explaining the syntax, and to Göran Weinholt for collaborating on Docker containers that made it easy to do the survey.
Copyright (C) Lassi Kortela (2021).
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 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.