[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Superfluous actual arguments

This page is part of the web mail archives of SRFI 89 from before July 7th, 2015. The new archives for SRFI 89 contain all messages, not just those from before July 7th, 2015.

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") port))

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