Usage of &allow-other-keys in common lisp
Asked Answered
K

1

6

I want to make the most generic function and decided to go with keys as arguments. I want to use allow-other-keys since I want to use the function with any key.

Let me show you:

(defun myfunc (a &rest rest &key b &allow-other-keys)
  ;; Print A
  (format t "A = ~a~%" a)

  ;; Print B if defined
  (when b
    (format t "B = ~a~%" b))

  ;; Here ... I want to print C or D or any other keys
  ;; ?? 
)

(myfunc "Value of A")
(myfunc "Value of A" :b "Value of B")
(myfunc "Value of A" :b "Value of B" :c "Value of C" :d "Value of D")

I know that restis the remaining args but it has an array. It does not bind values c or d or even build them like an associative list (i.e to do sth like (cdr (assoc 'c rest)))

Do you have a clue or a solution ? Or maybe I am going in the wrong direction ?

Thanks in advance

Kocher answered 25/11, 2015 at 13:30 Comment(0)
C
9

Since when is &REST an array? The standard says list. In the case of keyword arguments, this is a property list. See getf to access elements of a property list.

One can also use DESTRUCTURING-BIND to access the contents of that property list:

CL-USER 15 > (defun foo (a &rest args &key b &allow-other-keys)
               (destructuring-bind (&key (c nil c-p) ; var default present?
                                         (d t   d-p)
                                         (e 42  e-p)
                                    &allow-other-keys)
                   args
                 (list (list :c c c-p)
                       (list :d d d-p)
                       (list :e e e-p))))
FOO

; c-p, d-p, e-p  show whether the argument was actually present
; otherwise the default value will be used

CL-USER 16 > (foo 10 :b 20 :d 30)
((:C NIL NIL) (:D 30 T) (:E 42 NIL))

But the same could have been done in the argument list already...

Crary answered 25/11, 2015 at 14:14 Comment(3)
Sorry for the type confusion. Yes, it is a list, you are absolutely right. I'll have a look to getf in my case. Thanks for your answer.Kocher
I am still confused since rest has this value: (C Value of C D Value of D) but (getf rest 'c) or (getf rest 'C) give me NILKocher
Ok ... MY BAD. :c. Silly me. Thanks, @rainerKocher

© 2022 - 2024 — McMap. All rights reserved.