On Mon, Mar 16, 2020 at 10:37 AM Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> wrote:
How do you call `bar' in Common Lisp's/Gauche's model so that `x' and `y' do not receive any values but `foo' receives the value `3'?

You can't.  
Kawa's model to distinguish "bare" keyword and quoted one is interesting.   Is there a way to pass argument list,
including keyword arguments, via apply?   Once it becomes data, it looks like it loses "keywordness".
How would you handle a procedure that can arbitrarily many positional arguments and keyword arguments?

The rest argument "overlaps" on keyword argument list.

(define (bar :rest args :key foo) (list args key))
(bar) => (() #<undef>)
(bar :foo 3) => ((:foo 3) 3)

The above definition rejects keywords that's not listed:
(bar :baz 3) => ERROR: unknown keyword :bar

But you can allow other keywords.
(define (bar :rest args :key foo :allow-other-keys) (list args key))
(bar :baz 3) => ((:baz 3) #<undef>)

Which comes handy when you're writing a wrapper procedure
(define (baz :rest args :key baz :allow-other-keys) (list baz (apply bar args)))
(baz :foo 1 :baz 3) => (3 ((:foo 1 :baz 3) 1))

;; In case you want to remove :baz from the keyword list passing to bar: 
(define (baz :key baz :allow-other-keys otherkeys) (list baz (apply bar otherkeys)))
(baz :foo 1 :baz 3) => (3 ((:foo 1) 1))

;; In case you don't want to intercept inner procedure's keyword arguments:
;; (in this case, the caller knows it's using a wrapper procedure, so it can adjust arguments accordingly)
(define (baz :key foo bar-args :allow-other-keys otherkeys) (list foo (apply bar (append bar-args otherkeys))))
(baz :foo 1 :bar-args '(:foo 3))

The optimization possibilities Per mentioned don't work with CL's model, which just looks like an ordinary plist argument in disguise.

In both Gauche and CL, keyword binding is constant.   When the call site uses bare keyword (not 'apply'), and
the compiler knows the called procedure takes which keyword arguments, it can parse keyword arguments at
runtime.  Is that the optimization you're referring?

Here's a macro version of such optimization.  It uses a special definition (define/kw) to define procedures
that take keyword arguments, but if you modify the compiler, the ordinal define can handle it.


In Common Lisp,

(defun bar (&optional x y &key foo) (list x y foo))

(bar) => (nil nil nil)
(bar 1) => (1 nil nil)
(bar 1 2) => (1 2 nil)
(bar :foo 3) => (:foo 3 nil)
(bar 1 2 :foo 3) => (1 2 3)