Re: Associative Arrays
- Posted by Jeff Zeitlin <jzeitlin at CYBURBAN.COM> May 25, 2000
- 488 views
On Thu, 25 May 2000 00:01:10 -0400, Jiri Babor <J.Babor at GNS.CRI.NZ> wrote: >Jeff Zeitlin wrote: >>The discussion on this topic has been mildly interesting, but the >>participants seem to be unaware that I did an implementation of >>this concept some time ago - you can find it as assoc.e in >>zeitlin.zip in the Archives - I'd appreciate it if someone would >>look at it, and offer some criticisms and suggestions for >>enhancement. >Jeff, do you reall expect anybody would indulge you when you say in >the same breath, politely of course, the topic is not really worth it? Not "not worth it", more like "don't really have enough time to follow it". Or the rest of this list. Or most of my lists. (I'm finding that with recent changes at the precinct and on my railroad, I'm having to leave earlier to get there on time, and getting home much later, after leaving later. I'm racking up plenty of comp time, though (OT incurred in such a way that I can't demand cash - not that I necessarily want to; I'm looking forward to a long vacation later this summer...). >I dug it out. (Btw, burying eight disparate includes under unpromising >zeitlin.zip title was not terribly clever. I know, I made the same >stupid mistake many times myself...) ... and someday, when I have time (sigh), I _will_ be taking a second look at all of those, updating as needed, and reposting - separately. And finish up a call-compatible graphics.e for Linux. And rewrite a fairly complex QBASIC application in Euphoria. And... Yes, I sort of came to the same conclusion some time ago - but couldn't really justify trying to change it without seriously modifying the contents, which was not realistic at that point, mostly due to lack of feedback (so I didn't know what needed modification - if anything). I don't think I gave Roger the name, though; I don't recall how I shipped it to him. I might have called it something like "datstruc.zip" (assuming limitation to 8.3) with a description that included a list of what data structures were implemented. Or something like that. >Your scheme is essentially the same as the one I am currently using, >except for the 'default value' complication. Unnecessary complication, >in my opinion, because I can't see why the default value cannot be a >normal item of a 'two sequence' list, or a value supplied externally, >when appropriate tests indicate it is required. The idea that I was working with was that the internals should be concealed from the user, and that every list be able to have its own default, for when a particular key isn't associated. The best way to handle that is to put the default value into the list somewhere - but it can't be part of a key-value pair, because it would mean that I have to have one "reserved" key in every list - and I didn't want to do that; it would break one of the concepts I borrowed. If you read the comments in the file, the concept isn't purely borrowed from one language; I took concepts from SNOBOL, REXX, and LISP when designing it. The default was lifted from REXX; if I do an assignment FOO. = 'BAR', and request the value of an otherwise-undefined FOO.BAZ, I'll get back 'BAR'. There's no reserved name that I can reference to get that default value, which leaves me with the ability to use _any_ name for "real" data - I can set FOO.DEFAULT separately, and they will have two different meanings. The same capability exists in assoc.e. As far as supplying it externally, I did provide a procedure that allows the user to do so - alist_default(). Or am I misinterpreting what you mean? > But that's a minor >quibble. Another one: why would I want to sort my lists if you do not >give me tools to take advantage of it all. Good question. Are there any others? Seriously, though, I really don't recall why I did that; the best excuse I can come up with is so that you can get an alist iterator that's sorted, and then process the iterator. A rewrite will probably just have alist_iterate_start(), alist_iterate_next(), alist_iterate_sorted_start(), and alist_iterate_sorted_next() that will return single key-value pairs. Of course, the question of sorting is a difficult one anyway; can you decide which of any two arbitrary objects is "greater" than the other? Right now, I use whatever algorithm sort.e uses; if you have keys which would cause sort() to blow its brains out, so will alist_sort(). If you can think of tools that would be useful, either with the present implementation or with the alist_iterate_* implementation, I'd appreciate hearing them. > And just one more, because >I like doing things in threes: to my mind, it's certainly more logical >to define an empty list as {{},{},{}}, and your type check should flag >{} as a failure. I remember thinking along the same lines, but hit an obstacle of some sort when I was testing that made it necessary to allow an alist to be an empty sequence, as well as a sequence containing three subsequences. I don't recall what the problem was, but I suspect that it had something to do with the fact that I didn't want the user/programmer to need to know the internal structure of the alist, which would mean that after declaring an alist (assoc_list l), it would be a simple empty sequence if tested. I could have required that a procedure alist_init() be called, but I've never really been a fan of that sort of thing. As is, after the first attempt to modify a list, it _will_ have the correct structure - and attempting to retrieve from an alist that has never been modified will have the same effect as retrieving from a properly structured list with no keys and no default - so while it makes my code (i.e., assoc.e itself) slightly more complex, it simplifies things for the person using my code - which is always what I strive for when writing libraries. If I could have sensibly implemented alists with the same kind of internal structure that I did stacks and queues, I would have - but an initial attempt made the code so unwieldy for so little return (essentially, all I would have gained was that alist_set() and alist_default() could have been procedures instead of value-returning functions) that I gave up on that particular idea - an alist is not, after all, like a stack or a queue. >Fourth one: what about nested lists? No tools? - Any self-respecting >OO bullshit artist will need truckloads of them! Well, I'd written this before OO became a big theme here on the list, and I'm not sure I really understand some of the concepts - I may be able to translate into basic OO-style code, but I'm still _thinking_ procedural. If I'm making the correct assumptions as to what you're implying by "nested list", it's just an ordinary associative pair, where the value itself happens to be an associative list - thus, you would do a retrieval and assign the retrieved value to an alist variable, and then use that variable as the alist to do the next retrieval on, and so on for as many levels as you care to nest the lists. Updating the nested list would necessarily require multiple stores - first into the temporary alist that contains the most nested list, then into the next level up, and so on through the top-level list. What sort of tools would you propose? -- Jeff Zeitlin jzeitlin at cyburban.com