From: Pascal Bourguignon
Subject: function call/keyword indirection
Date: 
Message-ID: <8765dt4jtu.fsf@thalassa.informatimago.com>
Where can I find the reference in the standard that would support this
(great) feature:

(defun f (a &key (red 0) (green 0) (blue 0)) 
    (format t "a=~S~%red=~A~%green=~S~%blue=~S~2%" a red green blue))

(defun g (key) (f 1 key 2))

(list (g :red)  (g :green) (g :blue))

Just to be sure it's not implementation dependent.
(A section about function calls and how they're processed?)

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/

From: Paul Dietz
Subject: Re: function call/keyword indirection
Date: 
Message-ID: <403E6B7B.86D24120@motorola.com>
Pascal Bourguignon wrote:
> 
> Where can I find the reference in the standard that would support this
> (great) feature:
> 
> (defun f (a &key (red 0) (green 0) (blue 0))
>     (format t "a=~S~%red=~A~%green=~S~%blue=~S~2%" a red green blue))
> 
> (defun g (key) (f 1 key 2))
> 
> (list (g :red)  (g :green) (g :blue))
> 
> Just to be sure it's not implementation dependent.
> (A section about function calls and how they're processed?)


There's nothing that requires keyword arguments
to be present as constants in a calling form, so
why doesn't this follow directly from the meaning
of ordinary lambda lists (section 3.4.1)?

	Paul
From: Marco Antoniotti
Subject: Re: function call/keyword indirection
Date: 
Message-ID: <dtO%b.61$IJ5.20452@typhoon.nyu.edu>
Let's also remember that

CL-USER 1 > (defun foo (&key ((forty-two xxx) 42)) (+ xxx 42))
FOO

CL-USER 2 > (foo)
84

CL-USER 3 > (foo 'forty-two 44)
86

CL-USER 4 >


Cheers


marco




Paul Dietz wrote:
> Pascal Bourguignon wrote:
> 
>>Where can I find the reference in the standard that would support this
>>(great) feature:
>>
>>(defun f (a &key (red 0) (green 0) (blue 0))
>>    (format t "a=~S~%red=~A~%green=~S~%blue=~S~2%" a red green blue))
>>
>>(defun g (key) (f 1 key 2))
>>
>>(list (g :red)  (g :green) (g :blue))
>>
>>Just to be sure it's not implementation dependent.
>>(A section about function calls and how they're processed?)
> 
> 
> 
> There's nothing that requires keyword arguments
> to be present as constants in a calling form, so
> why doesn't this follow directly from the meaning
> of ordinary lambda lists (section 3.4.1)?
> 
> 	Paul
From: Pascal Costanza
Subject: Re: function call/keyword indirection
Date: 
Message-ID: <c1lqit$cp3$1@newsreader2.netcologne.de>
Pascal Bourguignon wrote:

> Where can I find the reference in the standard that would support this
> (great) feature:
> 
> (defun f (a &key (red 0) (green 0) (blue 0)) 
>     (format t "a=~S~%red=~A~%green=~S~%blue=~S~2%" a red green blue))
> 
> (defun g (key) (f 1 key 2))
> 
> (list (g :red)  (g :green) (g :blue))
> 
> Just to be sure it's not implementation dependent.
> (A section about function calls and how they're processed?)

AFAIK, there is no single place in the spec that states that keyword 
symbols are passed to a function as any other parameter. However, there 
are a few places from which one can deduce that this is the intended 
behavior.

3.1.2.1.2.3 Function Forms says: "The subforms in the cdr of the 
original form are evaluated in left-to-right order in the current 
lexical and dynamic environments. The primary value of each such 
evaluation becomes an argument to the named function; any additional 
values returned by the subforms are discarded."

3.4 Lambda Lists says: "A lambda list is a list that specifies a set of 
parameters (sometimes called lambda variables) and a protocol for 
receiving values for those parameters." (I think "protocol" is a keyword 
here.)

...and then 3.4.1.4 Specifiers for keyword parameters specifies what 
happens with keyword parameters. Especially the interaction with &rest 
parameters does not leave much implementational freedom.


Pascal

-- 
Tyler: "How's that working out for you?"
Jack: "Great."
Tyler: "Keep it up, then."
From: Pascal Bourguignon
Subject: Re: function call/keyword indirection
Date: 
Message-ID: <87znb424z7.fsf@thalassa.informatimago.com>
Pascal Costanza <········@web.de> writes:

> Pascal Bourguignon wrote:
> 
> > Where can I find the reference in the standard that would support this
> > (great) feature:
> > (defun f (a &key (red 0) (green 0) (blue 0))     (format t
> > "a=~S~%red=~A~%green=~S~%blue=~S~2%" a red green blue))
> > (defun g (key) (f 1 key 2))
> > (list (g :red)  (g :green) (g :blue))
> > Just to be sure it's not implementation dependent.
> > (A section about function calls and how they're processed?)
> 
> AFAIK, there is no single place in the spec that states that keyword
> symbols are passed to a function as any other parameter. However,
> there are a few places from which one can deduce that this is the
> intended behavior.
> 
> 3.1.2.1.2.3 Function Forms says: "The subforms in the cdr of the
> original form are evaluated in left-to-right order in the current
> lexical and dynamic environments. The primary value of each such
> evaluation becomes an argument to the named function; any additional
> values returned by the subforms are discarded."
> 
> 3.4 Lambda Lists says: "A lambda list is a list that specifies a set
> of parameters (sometimes called lambda variables) and a protocol for
> receiving values for those parameters." (I think "protocol" is a
> keyword here.)
> 
> ...and then 3.4.1.4 Specifiers for keyword parameters specifies what
> happens with keyword parameters. Especially the interaction with &rest
> parameters does not leave much implementational freedom.

Thank you.   I was wondering  and worrying if an  implementation could
consider  the keywords  specially and  have a  special scheme  to pass
these  arguments.   But  indeed,  3.1.2.1.2.3  covers  all  the  cases
generally,  and implies that  the interpretation  of keywords  is only
done at the  callee (and only if it has such  "protocol" in its lambda
list).

-- 
__Pascal_Bourguignon__                     http://www.informatimago.com/
There is no worse tyranny than to force a man to pay for what he doesn't
want merely because you think it would be good for him.--Robert Heinlein
http://www.theadvocates.org/
From: Tim Bradshaw
Subject: Re: function call/keyword indirection
Date: 
Message-ID: <ey3ad346c11.fsf@cley.com>
* Pascal Bourguignon wrote:

> Thank you.   I was wondering  and worrying if an  implementation could
> consider  the keywords  specially and  have a  special scheme  to pass
> these  arguments.   But  indeed,  3.1.2.1.2.3  covers  all  the  cases
> generally,  and implies that  the interpretation  of keywords  is only
> done at the  callee (and only if it has such  "protocol" in its lambda
> list).

I think they can have such a scheme, but they have to act as if they
don't.  I suspect strongly that good compilers will optimise keyword
arguments for at least some functions when they can see them in the
source.

--tim
From: Duane Rettig
Subject: Re: function call/keyword indirection
Date: 
Message-ID: <44qtcwl9k.fsf@franz.com>
Tim Bradshaw <···@cley.com> writes:

> * Pascal Bourguignon wrote:
> 
> > Thank you.   I was wondering  and worrying if an  implementation could
> > consider  the keywords  specially and  have a  special scheme  to pass
> > these  arguments.   But  indeed,  3.1.2.1.2.3  covers  all  the  cases
> > generally,  and implies that  the interpretation  of keywords  is only
> > done at the  callee (and only if it has such  "protocol" in its lambda
> > list).
> 
> I think they can have such a scheme, but they have to act as if they
> don't.  I suspect strongly that good compilers will optimise keyword
> arguments for at least some functions when they can see them in the
> source.

The standard way to do that is by implementing a two-tier interface and a
compiler-macro.  One example:

(defun foo (bar &key bas bam)
  (internal-foo bar bas bam))

(defun internal-foo (bar bas bam)
  ...)

(define-compiler-macro (bar &key bas bam)
  `(internal-foo ,bar ,bas ,bam))


-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Duane Rettig
Subject: Re: function call/keyword indirection
Date: 
Message-ID: <4vflsv53e.fsf@franz.com>
Duane Rettig <·····@franz.com> writes:

A typo, and a note:

This:

> (define-compiler-macro (bar &key bas bam)
>   `(internal-foo ,bar ,bas ,bam))

should be:

(define-compiler-macro foo (bar &key bas bam)
  `(internal-foo ,bar ,bas ,bam))

Someone has also reminded me that the above does not preserve
argument-evaluation order; it is a trivial implementation, and if
the order of evaluation is important, then a let form will have to
be manufactured as part of the expansion, probably using a &rest
argument in the compiler-macro's lambda-list.  Otherwise, for example,
the form

   (let ((x 10))
     (foo x :bam (incf x) :bas (decf x)))

will have a different effect, depending on whether the evaluation
order is preserved.

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Timothy Moore
Subject: Re: function call/keyword indirection
Date: 
Message-ID: <wdrptc0bwu4.fsf@serveur5.labri.fr>
Pascal Bourguignon <····@thalassa.informatimago.com> writes:

> Thank you.   I was wondering  and worrying if an  implementation could
> consider  the keywords  specially and  have a  special scheme  to pass
> these  arguments.   But  indeed,  3.1.2.1.2.3  covers  all  the  cases
> generally,  and implies that  the interpretation  of keywords  is only
> done at the  callee (and only if it has such  "protocol" in its lambda
> list).

There isn't anything preventing special treatment of constant keyword
arguments as long as non-constant values are also supported.

Tim