178 lines
5.8 KiB
HTML
178 lines
5.8 KiB
HTML
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
|
|
<html>
|
|
<head>
|
|
<title>SRFI 16: Syntax for procedures of variable arity</title>
|
|
</head>
|
|
|
|
<body>
|
|
|
|
<H1>Title</H1>
|
|
|
|
SRFI 16: Syntax for procedures of variable arity.
|
|
|
|
<H1>Author</H1>
|
|
|
|
Lars T Hansen
|
|
|
|
<H1>Status</H1>
|
|
This SRFI is currently in ``final'' status. To see an explanation of each status that a SRFI can hold, see <A HREF="http://srfi.schemers.org/srfi-process.html">here</A>.
|
|
You can access the discussion via <A HREF="http://srfi.schemers.org/srfi-16/mail-archive/maillist.html">the archive of the mailing list</A>.
|
|
<P><UL>
|
|
<LI>Received: 1999/11/01
|
|
<LI>Draft: 1999/11/06-2000/01/07
|
|
<LI>Final: 2000/03/10
|
|
</UL>
|
|
|
|
<H1>Abstract</H1>
|
|
|
|
CASE-LAMBDA, a syntax for procedures with a variable number of arguments,
|
|
is introduced.
|
|
|
|
<H1>Rationale</H1>
|
|
|
|
CASE-LAMBDA reduces the clutter of procedures that execute different
|
|
code depending on the number of arguments they were passed; it is
|
|
a pattern-matching mechanism that matches on the number of arguments.
|
|
CASE-LAMBDA is available in some Scheme systems.
|
|
|
|
<p>While CASE-LAMBDA can be implemented as a macro using only facilities
|
|
available in R5RS Scheme, it admits considerable implementation-specific
|
|
optimization.
|
|
|
|
|
|
<H1>Specification</H1>
|
|
|
|
<dl>
|
|
<dt><a name="case-lambda"></a>
|
|
(CASE-LAMBDA <clause> ...)
|
|
<br> Syntax
|
|
<dd>
|
|
<p>Each <clause> should have the form (<formals> <body>), where
|
|
<formals> is a formal arguments list as for LAMBDA, cf section
|
|
4.1.4 of the R5RS. Each <body> is a <tail-body>, cf section
|
|
3.5 of the R5RS.
|
|
|
|
<p>A CASE-LAMBDA expression evaluates to a procedure that accepts
|
|
a variable number of arguments and is lexically scoped in the
|
|
same manner as procedures resulting from LAMBDA expressions.
|
|
When the procedure is called with some arguments V1 .. Vk, then
|
|
the first <clause> for which the arguments agree with <formals>
|
|
is selected, where agreement is specified as for the <formals>
|
|
of a LAMBDA expression. The variables of <formals> are bound
|
|
to fresh locations, the values V1 .. Vk are stored in those
|
|
locations, the <body> is evaluated in the extended environment,
|
|
and the results of <body> are returned as the results of the
|
|
procedure call.
|
|
|
|
<p>It is an error for the arguments not to agree with the <formals>
|
|
of any <clause>.
|
|
|
|
<pre>
|
|
(define plus
|
|
(case-lambda
|
|
(() 0)
|
|
((x) x)
|
|
((x y) (+ x y))
|
|
((x y z) (+ (+ x y) z))
|
|
(args (apply + args))))
|
|
|
|
(plus) --> 0
|
|
(plus 1) --> 1
|
|
(plus 1 2 3) --> 6
|
|
|
|
((case-lambda
|
|
((a) a)
|
|
((a b) (* a b)))
|
|
1 2 3) --> error
|
|
</pre>
|
|
</dl>
|
|
|
|
<H1>Implementation</H1>
|
|
|
|
The following implementation is written in R5RS Scheme. It is not
|
|
compatible with the IEEE Scheme standard because the IEEE standard does
|
|
not contain the high-level macro system.
|
|
|
|
<p>The implementation assumes that some top-level names defined by the
|
|
R5RS are bound to their original values.
|
|
|
|
<p>
|
|
<pre>
|
|
;; This code is in the public domain.
|
|
|
|
(define-syntax case-lambda
|
|
(syntax-rules ()
|
|
((case-lambda
|
|
(?a1 ?e1 ...)
|
|
?clause1 ...)
|
|
(lambda args
|
|
(let ((l (length args)))
|
|
(case-lambda "CLAUSE" args l
|
|
(?a1 ?e1 ...)
|
|
?clause1 ...))))
|
|
((case-lambda "CLAUSE" ?args ?l
|
|
((?a1 ...) ?e1 ...)
|
|
?clause1 ...)
|
|
(if (= ?l (length '(?a1 ...)))
|
|
(apply (lambda (?a1 ...) ?e1 ...) ?args)
|
|
(case-lambda "CLAUSE" ?args ?l
|
|
?clause1 ...)))
|
|
((case-lambda "CLAUSE" ?args ?l
|
|
((?a1 . ?ar) ?e1 ...)
|
|
?clause1 ...)
|
|
(case-lambda "IMPROPER" ?args ?l 1 (?a1 . ?ar) (?ar ?e1 ...)
|
|
?clause1 ...))
|
|
((case-lambda "CLAUSE" ?args ?l
|
|
(?a1 ?e1 ...)
|
|
?clause1 ...)
|
|
(let ((?a1 ?args))
|
|
?e1 ...))
|
|
((case-lambda "CLAUSE" ?args ?l)
|
|
(error "Wrong number of arguments to CASE-LAMBDA."))
|
|
((case-lambda "IMPROPER" ?args ?l ?k ?al ((?a1 . ?ar) ?e1 ...)
|
|
?clause1 ...)
|
|
(case-lambda "IMPROPER" ?args ?l (+ ?k 1) ?al (?ar ?e1 ...)
|
|
?clause1 ...))
|
|
((case-lambda "IMPROPER" ?args ?l ?k ?al (?ar ?e1 ...)
|
|
?clause1 ...)
|
|
(if (>= ?l ?k)
|
|
(apply (lambda ?al ?e1 ...) ?args)
|
|
(case-lambda "CLAUSE" ?args ?l
|
|
?clause1 ...)))))
|
|
</pre>
|
|
|
|
<H1>Copyright</H1>
|
|
<p>Copyright (C) Lars T Hansen (1999). All Rights Reserved.</p>
|
|
|
|
<p>
|
|
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:
|
|
</p>
|
|
<p>
|
|
The above copyright notice and this permission notice shall be
|
|
included in all copies or substantial portions of the Software.
|
|
</p>
|
|
<p>
|
|
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.
|
|
</p>
|
|
|
|
<hr>
|
|
<address>Editor: <a href="mailto:srfi-editors@schemers.org">Mike Sperber</a></address>
|
|
<!-- Created: Tue Sep 29 19:20:08 EDT 1998 -->
|
|
<!-- hhmts start -->
|
|
Last modified: Mon Apr 19 20:38:48 CEST 2004
|
|
<!-- hhmts end -->
|
|
</body>
|
|
</html>
|