Intricate lambda list syntax Lassi Kortela 18 Oct 2019 08:26 UTC
> I checked with CLISP and #lisp, and they agree: > optional arguments are filled before any keyword detection begins. That's right. (defun foo (&optional x &key y) (list x y)) (foo :y) ; => (:Y NIL) (foo :y :y 1) ; => (:Y 1) When you think through the ramifications, it's the logical choice when keywords are self-evaluating objects, but it probably confuses everyone at first. Even more confusing is that keyword args can co-exist with a rest arg. They receive the same portion of the arglist, the rest arg gets the raw version and the keyword args the parsed one: (defun foo (&optional x &rest r &key y) (list* x y r)) (foo) => (NIL NIL) (foo :y) => (:Y NIL) (foo :y :y 1) => (:Y 1 :Y 1) Finally there's &allow-other-keys, default values and supplied-p parameters. I left all of this out of 177 on purpose, as I think it confuses users without offering much benefit. Another fun fact: Racket has required keyword arguments. In fact they are required by default unless you give them a default value.