From: Lowell
Subject: keyword args
Date: 
Message-ID: <bi4i5l$edq$1@mughi.cs.ubc.ca>
I want an average function that works like this:

(avg 1 2 3) -> 2
(avg '(1) '(2) '(3) :key #'car) -> 2

I assume the first line will look like:

(defun avg (@rest args @key key) ...

Am I on the right track?

Lowell

From: Frode Vatvedt Fjeld
Subject: Re: keyword args
Date: 
Message-ID: <2hbruirr4k.fsf@vserver.cs.uit.no>
Lowell <······@cs.ubc.ca> writes:

> I want an average function that works like this:
>
> (avg 1 2 3) -> 2
> (avg '(1) '(2) '(3) :key #'car) -> 2
>
> I assume the first line will look like:
>
> (defun avg (@rest args @key key) ...
>
> Am I on the right track?

Well, consider (average 1 2 3 :key #'foo). How will the average
function know that the objects :key and #'foo specify a keying
function rather than being among the set of objects of which you want
to compute the average?

Try this:

  (defun foo (&rest args &key key)
    (format t "args: ~W, key: ~W"))


You could in principle specify that any arguments to average that
aren't numbers will be treated as keyword arguments. However, this
isn't very good lisp style.

I'd suggest one of two alternatives:

1. Make the key a required argument, if you expect it to be needed often:

  (defun average (key &rest numbers)
     ....)

2. Don't accept a key:

  (defun average (&rest numbers)
      ...)

..and use it like this when you do need a keying function:

  (apply #'average (mapcar #'foo numbers))

or perhaps

  (reduce #'average numbers :key #'foo)

-- 
Frode Vatvedt Fjeld
From: Patrick O'Donnell
Subject: Re: keyword args
Date: 
Message-ID: <rtvfshtrc9.fsf@ascent.com>
Frode Vatvedt Fjeld <······@cs.uit.no> writes:
> or perhaps
> 
>   (reduce #'average numbers :key #'foo)


You might want to think about this one a little more....

		- Pat
From: Barry Margolin
Subject: Re: keyword args
Date: 
Message-ID: <Vzr1b.362$mD.234@news.level3.com>
In article <············@mughi.cs.ubc.ca>, Lowell  <······@cs.ubc.ca> wrote:
>I want an average function that works like this:
>
>(avg 1 2 3) -> 2
>(avg '(1) '(2) '(3) :key #'car) -> 2
>
>I assume the first line will look like:
>
>(defun avg (@rest args @key key) ...
>
>Am I on the right track?

Why does it have to be like that?  What's wrong with:

(avg '(1 2 3))
(avg '((1) (2) (3)) :key #'car)

Common Lisp doesn't provide any built-in way to mix &key args in the middle
of &rest args.  If you want your function to process an arbitrary number of
things, make it take a list or sequence as the argument -- that's what
these data structures are there for.

-- 
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.