Email list hosting service & mailing list manager

Re: Superfluous actual arguments Joo ChurlSoo (14 Apr 2006 12:42 UTC)
Re: Superfluous actual arguments Marc Feeley (14 Apr 2006 13:05 UTC)

Re: Superfluous actual arguments Marc Feeley 14 Apr 2006 13:05 UTC

On 14-Apr-06, at 8:42 AM, Joo ChurlSoo wrote:

> In SRFI-89:
> (define (g a #!optional (b a) #!key (k (* a b))) (list a b k))
> (g 3 4 k: 5 k: 6)                   ==>  (3 4 5)
> In this case, there is no rest parameter.  Why is this not an error?
> Are another k: and 6 not arguments?

Sorry, I didn't get what you were after in the previous message.
Just to make sure, you are referring to point 5 of the spec, that is:

    If `#!key' appears in the <extended formals> and there is no
<rest formal> then there must be
    an even number of remaining actual parameters. These are
interpreted as a series of pairs,
    where the first member of each pair is a keyword object
specifying the parameter name, and
    the second is the corresponding value. It is an error if the
first member of a pair is not a
    keyword object. It is an error if the parameter name is not the
same as a variable in a
    <keyword formal>. If the same parameter name occurs more than
once in the list of actual
    parameters, then the first value is used. If there is no actual
parameter for a particular
    <keyword formal>, then the variable is bound to the result of
evaluating <initializer> if
    one was specified, and otherwise to `#f'. The <initializer> is
evaluated in an environment
    in which all previous formal parameters have been bound.

This is the behaviour specified by DSSSL and the example is correct
(the first value given for parameter "k" has precedence over the
second value given).  The ability to provide the value of a named
parameter more than once is useful for implementing wrapper functions
that override the default value of a named parameter.  Here's a
simple example:

(define (debug f)
   (lambda args
     (apply f (append args (list debug: #t)))))

(define (foo x y #!key (debug #f) (port (current-output-port)))
   (if debug
       (display "foo\n" port))
   (display (string-append "x+y=" (number->string (+ x y)) "\n") port))

(define (bar x #!key (debug #f) (port (current-output-port)))
   (if debug
       (display "bar\n" port))
   (display (string-append "log(x)=" (number->string (log x)) "\n")

(define dfoo (debug foo))
(define dbar (debug bar))

 > (foo 1 2)
 > (foo 1 2 debug: #t)
 > (dfoo 1 2)
 > (dfoo 1 2 debug: #f)
 > (dfoo 1 2 unknown-param: #f)
*** ERROR -- Unknown keyword argument passed to procedure
(foo 1 2 unknown-param: #f debug: #t)