Basically, I'm wondering if there is such a thing as a plist in Common Lisp outside the concept of the built-in symbol property list. So if I have
(setq Joe '(:fav-season "Fall" :fav-color "Blue"))
then I do
(setf (get 'Joe 'fav-season) "Summer")
(setf (get 'Joe 'fav-color) "Green")
I've got two separate plists associated with Joe
going at once, one ad-hoc, the other "official" because it's bound to the symbol Joe
.
(get 'Joe 'fav-color)
"Green"
or
(symbol-plist 'Joe)
(FAV-COLOR "Green" FAV-SEASON "Summer")
So I assume the direct assigning of a plist-like structure to Joe
(assigning to the symbol Joes
's value cell) isn't a truly supported data structure (like get
, getf
etc.) as it is with the symbol Joe
's property list. Nor as an alist, which is always the value of a variable and has assoc
, rassoc
, etc. May I therefore conclude there really is no use of the plist concept in the real world besides the built-in symbol cell for property lists? So often in tutorials, plist is automatically described as the symbol's property list, and there is no further discussion of the concept.
I guess in a backwards way, I'm pursuing the rather vague, spotty idea of what are good, best-practice data structures in Lisp.
Use GETF
to retrieve values from a list, which is a property list.
CL-USER 141 > (let ((joe '(:fav-season "Fall"
:fav-color "Blue")))
(list (getf joe 'fav-color)
(getf joe :fav-color)))
(NIL "Blue")
Notice that you need to get the indicator right.
You've used GET
, which can be implemented in terms of GETF
:
(defun get (x y)
(getf (symbol-plist x) y))
Thus one can use property lists not just in symbol property lists - there is a basic operator for it.
Note also that there are many other data structures, which allow access to values via keys: assoc lists, CLOS classes, hash-tables. There are slightly different use cases for those.
Property lists are often used when simple key and value data needs to be used in lists - for example in source code.
Functions use property list like lists for keyword arguments, which one can manipulate:
(let ((foo (list 'window :x 100 :y 200)))
(setf (getf (rest foo) :x) 200)
(apply #'make-instance foo))
Sometimes property lists are added to CLOS classes or structures. Structures in Common Lisp may not be extensible at runtime - they can't be redefined with additional slots. So often some classes and structures have a properties slot, where one can at runtime add/remove/updated the key/value pairs.
Yes, but to my bigger question, Is a plist only (mainly) for use with a symbol's property list, or is it ever used by itself?
My confusion came from how tutorials seem to imply that a plist was only employed in the case of symbols. Now I understand that almost the same syntax as with symbol-plists is used when a variable has a plist as a value. Now I have to learn when to use a key/value list, a structure, or an object. Still, it seems strange that we can create a symbol, load it up with a big plist, but if we don't give it an actual value, it's not really any sort of variable, global or lexical. Is that ever done, or have any advantage over normal variable work?
@147pm historically symbol plists were important internally in Lisp: things like values or functions may have been entries on a plist. Also symbols with plists were probably the earliest objects (in an OOP sense), where the plist entries were the slots&values.
@147pm still today some Lisp systems have some internal info on a symbol: documentation strings, source location, compiler infos, ...