Edit
Attach
Printable
topic end
<!-- * Set TOPICTITLE = #define private public - I'm just a simple property list... (19 Jul 2007) --> <style type="text/css"> pre {background-color:#ffeecc;} </style> %STARTINCLUDE% <a name="19"></a> <img src="%ATTACHURLPATH%/MontStMichel12.jpg" alt="MontStMichel12.jpg" width="120" height="90" align="right" /> ---+++ [[DefinePrivatePublic20070719][I'm just a simple property list, I didn't expect the Spanish strinquisition!]] (19 Jul 2007) <summary> My co-worker looked a little tense. Our office is in the sixth floor, my window was wide open, and somehow I became slightly nervous as he walked up to it. </summary> "Now, you're the Lisp aficionado here, right", he said, "You've got to help me out: Strings don't work in property lists!" Oh, great. Who knows, being regarded (undeservedly) as the local Lisp, ahem, expert may become a factor for my job security some day, so I thought I'd better keep a straight face. Besides, he was still standing close to that window, and I wanted to leave nothing but a reassuring impression on him. On the other hand, what the heck was he talking about? Frantically grepping my grey cells for information on property lists, I somehow recalled we sometimes use them as a poor man's hashtable, usually mapping keywords to flags. But it had been so long I used property lists myself that I even had to look up the syntax details. To avoid this embarrassment next time around, here are some notes. A property list is associated with a symbol. This flat and unstructured list can be thought of as a sequence of indicator/value pairs, with the indicator being the "key", in hash map terms. So the list starts with an indicator, followed by a value, followed by an indicator and its value, and so on. This is how you usually set a symbol property: <pre> (setf (get 'some-symbol some-indicator) some-value) </pre> And to inquire a symbol property, you just say something like =(get 'some-symbol some-indicator)=. =some-indicator= can basically be any type, and so I wasn't sure what my co-worker meant when he said that he couldn't get strings to work, until he explained the details to me: He was calling some Lisp-based API function in our product, and that function returns a property list. Unfortunately, that property list was special in that somebody had stuffed a string into it as an _indicator_, and so the property list looked somehow like this: <pre> ("foo" 42 "bar" 4711) </pre> And indeed, if you now try to inquire the "foo" property using =(get 'some-symbol "foo")=, all you get is - =nil=. To retrieve a property value, =get= walks the list and compares each indicator in the list with "foo" (in this example) - using =eq=. From which we can immediately conclude: * The correct spelling of "property list" is p-e-r-f-o-r-m-a-n-c-e p-r-o-b-l-e-m, as each lookup requires traversing potentially all of the list. * =eq= checks for _object equality_, not just _value equality_. Which means that things like literal (!) strings or characters cannot be indicators! In our case, we say =(get 'some-symbol "foo")=, and that "foo" string literal creates a _new_ string object. While that new object happens to have the same _value_ as the "foo" string in the property list, it is _not_ the same object. Indeed, the [[http://www.lisp.org/HyperSpec/Body/acc_get.html][Common Lisp <nop>HyperSpec]] is quite clear on that topic: <i>"Numbers and characters are not recommended for use as indicators in portable code since get tests with [[http://www.lisp.org/HyperSpec/Body/fun_eq.html][eq]] rather than eql, and consequently the effect of using such indicators is implementation-dependent."</i> It all boils down to the simple fact that =(eq "foo" "foo")= returns =nil=. Now hopefully we can fix the API which returned those inadequate property lists to my co-worker's code, but his code also needs to run in older and current installations, and so he needed a workaround of some sort. His first idea was to get the property list and fix it up in a preprocessing step before using =get= or =getf= for lookup, i.e. something like this: <pre> (defun fix-plist(plist old-indicator new-indicator) (let ((cnt 0)) (mapcar #'(lambda(item) (incf cnt) (if (and (oddp cnt) (equal item old-indicator)) new-indicator item)) plist))) (setf my-symbol 42) (setf (get 'my-symbol "indicator") "value") ;; mess up plist (print (get 'my-symbol "indicator")) ;; returns NIL (print (getf (fix-plist (symbol-plist 'my-symbol) "indicator" :indicator) :indicator)) </pre> This works, kind of - but it is actually quite ugly. Sure, with this code, we should be able to safely move ahead, especially since I also closed that office window in the meantime, but still: I really hope I'm missing something here. Any other ideas out there? --- %STOPINCLUDE% %COMMENT{type="below" nonotify="on"}% ---
to top
End of topic
Skip to action links
|
Back to top
Edit
|
Attach image or document
|
Printable version
|
Raw text
|
Refresh
|
More topic actions
Revisions: | r1.7 |
>
|
r1.6
|
>
|
r1.5
|
Total page history
|
Backlinks
You are here:
Blog
>
DefinePrivatePublic20070719
r1.7 - 19 Sep 2007 - 21:59 -
ClausBrod
to top
Blog
This site
2017
:
12
-
11
-
10
2016
:
10
-
7
-
3
2015
:
11
-
10
-
9
-
4
-
1
2014
:
5
2013
:
9
-
8
-
7
-
6
-
5
2012
:
2
-
10
2011
:
1
-
8
-
9
-
10
-
12
2010
:
11
-
10
-
9
-
4
2009
:
11
-
9
-
8
-
7
-
6
-
5
-
4
-
3
2008
:
5
-
4
-
3
-
1
2007:
12
-
8
-
7
-
6
-
5
-
4
-
3
-
1
2006:
4
-
3
-
2
-
1
2005:
12
-
6
-
5
-
4
2004:
12
-
11
-
10
C++
CoCreate Modeling
COM & .NET
Java
Mac
Lisp
OpenSource
Scripting
Windows
Stuff
Changes
Index
Search
Maintenance
Impressum
Datenschutzerklärung
Home
Webs
Atari
Blog
Claus
CoCreateModeling
Klassentreffen
Main
Sandbox
Sommelier
TWiki
Xplm
Jump:
Copyright © 1999-2024 by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki?
Send feedback