Do we need the colons? That is, if we leave them off, is there anything that doesn't work?
Association lists could be (x 1 y 2) instead of ((x 1) (y 2)), and ('(x 1 y 2) 'y) could be implemented to return 2.
I have a hack that implements ('((x 1) (y 2)) 'y) to return 2 so that I can use a!y with association lists; it would work as well if association lists were represented without the extra parentheses.
"Do we need the colons? That is, if we leave them off, is there anything that doesn't work?"
Yes! It's necessary to distinguish between keyword args and normal args:
(foo x y :a 3 :b 4)
Sure, you could define keyword args to be separate... but I like the idea of unifying them, since they serve such a similar purpose. Plus, I like that there's a syntatic difference between a list that is used for sequential lookup, and a list that's used for key/value lookup. You may disagree.
In any case, you can freely mix alists, plists, plists with keyword symbols, and ordinary tables in your own code. The question of this post is: should keyword plists be supported at all?
I'm leaning toward yes, assuming we can solve the questions I presented. And then, rather than making data types tables, I could make them keyword plists, which is probably better since the number of keys is usually small.
> Association lists could be (x 1 y 2) instead of ((x 1) (y 2))
Nice, I never consciously realized that. (I suppose we've been seeing it all along in replacing (let ((a 1) (b 2))) with (with (a 1 b 2)), but I never thought about remaking alists that way.) I think the single drawback of actually doing that is that O(n) lookup is now O(2n). [Obviously, if lookup time is a bottleneck, you probably should replace the alists with something else, like... tables! or AVL trees.]
It's an old concept, known as plists[1]. Common Lisp has them, and uses the same syntax that I'm proposing.
By the way, one benefit of alists is that you can iterate over them easier:
(each '(k v) '((a 1) (b 2) (c 3))
...)
Compared to the following, with a plist:
(each '(k v) (pair '(a 1 b 2 c 3))
...)
Which, incidentally, uses `pair` to create an alist, then iterate over that... I was thinking about how to solve this, and figured a form of destructuring might help: