Assoc lists make little sense as argument lists. Named arguments are basically like property lists. The point of argument lists for functions in Common Lisp is that they enable a contract. This requires special built-in support in the language. I want to see during compile time if an arg is missing or additional.
Example: the function WRITE takes several keyword arguments, but not :BAR. The compiler complains about wrong use.
* (defun test () (write "foo" :bar 10))
; in: DEFUN TEST
; (WRITE "foo" :BAR 10)
;
; caught WARNING:
; :BAR is not a known argument keyword.
Now if you allow a hashtable or some other data structure to be passed, then it would also be great, if one could specify at definition time which keys it takes, their default values, etc. We also may want to find out which values were default values, and which were actually passed.
The keyword argument facility for functions in Common Lisp provides all of that.
This allows you compile-time checks for code and makes interfaces easier to use.
Common Lisp also allows access to arguments as lists. This is simpler and more Lispy than using hash tables. For most purposes lists are useful enough and hash-tables would just add overhead.
Example: the function WRITE takes several keyword arguments, but not :BAR. The compiler complains about wrong use.
Now if you allow a hashtable or some other data structure to be passed, then it would also be great, if one could specify at definition time which keys it takes, their default values, etc. We also may want to find out which values were default values, and which were actually passed.The keyword argument facility for functions in Common Lisp provides all of that.
This allows you compile-time checks for code and makes interfaces easier to use.
Common Lisp also allows access to arguments as lists. This is simpler and more Lispy than using hash tables. For most purposes lists are useful enough and hash-tables would just add overhead.