[Top][All Lists]

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

keyword arguments and #:rest

From: Panicz Maciej Godek
Subject: keyword arguments and #:rest
Date: Sat, 10 Nov 2012 15:33:14 +0100

I've been writing a function to generate an array of random numbers.
I wanted it to optionally allow specifying the array type (and a few other
things) using keyword arguments. I eventually came up with the following

(define remove-keyword-args
  (letrec ((self (lambda(list)
                   (match list
                     (((? keyword?) (? (?not keyword?)) . rest)
                      (self rest))
                     (((? (?not keyword?) x) . rest)
                      (cons x (self rest)))
                     (((? keyword?) . rest)
                      (self rest)) ; for completeness only
                     (() '())))))

(define* (random-array #:key (range 1.0) (type #t) (mean 0) #:rest dims)
  (let ((dims (remove-keyword-args dims)))
    (array-map (lambda (mean) (+ mean (- (random (* 2 range)) range)))
                (apply make-typed-array type mean dims))))

The problem was, that, as the manual says, "When `#:key' is used
together with a rest argument, the keyword parameters in a call
all remain in the rest list.  This is the same as Common Lisp.",
so I had to get rid of the keywords myself, using the "remove-keyword-args"
procedure defined above.

The thing is that although this suits my case, it isn't a good
sollution in general.
So I thought that maybe there could be another keyword controlling whether
the keywords are left in the rest list or not, so the above code could
look like this:

(define* (random-array #:key (range 1.0) (type #t) (mean 0) #:rest
dims #:no-key)
  (array-map (lambda (mean) (+ mean (- (random (* 2 range)) range)))
              (apply make-typed-array type mean dims)))

Wouldn't the world be a better place?
[The semantics I'd expect would be that if #:allow-other-keys is enabled,
those keywords that weren't specified after #:key would still be captured
to the #:rest argument]

Best regards

reply via email to

[Prev in Thread] Current Thread [Next in Thread]