Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Vee Satayamas
Vee Satayamas

Posted on

     

Key-value data in Common Lisp

I enjoy using key-value data in dynamic languages. For example, in Python, I can create key-value data for storing the metadata of a document as shown below. I don't discuss why I don't use struct, class, named tuple in this post.

doc_metadata={"title":"The Rust Programming Language","type":"book","number-of-pages":584,"authors":["Steve Klabnik","Carol Nichols","contributions"]}
Enter fullscreen modeExit fullscreen mode

I can code read/write a value easily, for example:

# Writedoc_metadata["type"]="text book"# Readprint(doc_metadata["type"])
Enter fullscreen modeExit fullscreen mode

In Perl and Ruby, we can use Hash, which is almost the same thing as Dict in Python. In JavaScript, we can use an object.

Common Lisp is different. We can use a hash table, but it is not as convenient as Dict in Python.

(let((doc-metadata(make-hash-table)))(setf(gethash:titledoc-metadata)"The Rust Programming Language")(setf(gethash:typedoc-metadata):BOOK)(setf(gethash:number-of-pagesdoc-metadata)584)(setf(gethash:authorsdoc-metadata)'("Steve Klabnik""Carol Nichols""contributions")))
Enter fullscreen modeExit fullscreen mode

Besides construction, printing a hash table is not so convenient. Maybe one can create a function or macro to make creating/printing a hash table convenient. I still felt that I abused Common Lisp.

My code is usually too buggy when I keep mutating the same variable. So I prefer using an immutable data structure to prevent me from messing things up. Moreover, my key-value data usually do not have more than five keys. So I don't strictly need to use an efficient data structure, namely, hash table or binary search tree. So I use alist (assosiation list). I can construct a list like below:

(setqdoc-metadata'((:title."The Rust Programming Language")(:type.:BOOK)(:number-of-pages.542)(:authors.'("Steve Klabnik""Carol Nichols""contributions"))))
Enter fullscreen modeExit fullscreen mode

IMO, it looks concise and convenient. We can retrieve key-value pair with a specific key using the assoc function, which I suppose it does linear search. Linear search can be slow. However, my alist doesn't have a lot of keys.

Instead of replacing a value with another value, I can add a new key-value pair with an existing key, for example:

(setqanother-doc-metadata(acons:type:TEXT-BOOKdoc-metadata))
Enter fullscreen modeExit fullscreen mode

By retrieving the value of :type using assoc, we get the new value because assoc function retrieves the first key found in alist, for example:

(cdr(assoc:typeanother-doc-metadata));; OUTPUT => :TEXT-BOOK
Enter fullscreen modeExit fullscreen mode

However, with function calls instead of number/string literal, alist doesn't look concise anymore, for example:

(list(cons:title(get-titlexyz))(cons:type(get-typex))(cons:number-of-pages(get-number-of-pagesabc))(cons:authors(get-authorscd)))
Enter fullscreen modeExit fullscreen mode

plist looks much more concise, for example:

(setqdoc-metadata(list:title(get-titlexyz):type(get-typex):number-of-pages(get-number-of-pagesabc):authors(get-authorscd)))
Enter fullscreen modeExit fullscreen mode

I can retrieve a value corresponding to a key easily by getf function. For example:

(getfdoc-metadata:type)
Enter fullscreen modeExit fullscreen mode

A new value can be replaced the old value by setf, example:

(setf(getfdoc-mentadata:type):TEXT-BOOK)
Enter fullscreen modeExit fullscreen mode

setf is different from acons since acons doesn't mutate the existing list, setf does. Therefore plist is not exactly what I'm looking for.

Maybe the best way is using an Alexandria function for converting plist ot alist as Michał "phoe" Herda suggested.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

I'm a Thai-Lao-English-speaking software engineer who has worked on data pipelines, web/app back-end, and multilingual text processing.
  • Location
    SE Asia
  • Work
    software engineer
  • Joined

More fromVee Satayamas

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp