Skip to content

Instantly share code, notes, and snippets.

@cbaggers
Last active December 14, 2019 03:38
Show Gist options
  • Save cbaggers/7a0d432e45a71dd024af to your computer and use it in GitHub Desktop.
Save cbaggers/7a0d432e45a71dd024af to your computer and use it in GitHub Desktop.
Literal HashTable syntax for common lisp
(defmacro hash ((&key (test #'eql) (size 10)
(rehash-size 1.5) (rehash-threshold 1)
(hash-function nil) (weakness nil) synchronized)
&rest keys-vals-plist)
(let ((h (gensym "new-hashmap")))
`(let ((,h (make-hash-table :test ,test :size ,size
:rehash-size ,rehash-size
:rehash-threshold ,rehash-threshold
:hash-function ,hash-function
:weakness ,weakness
:synchronized ,synchronized)))
,@(loop
:with tmp = nil
:for e :in keys-vals-plist
:for i :from 0
:if (evenp i) :do (setf tmp e)
:collect `(setf (gethash ,tmp ,h) ,e))
,h)))
(defun hash-reader (stream char n)
(declare (ignore char n))
(let* ((body (read stream t nil t)))
(append (list 'hash nil) body)))
(set-dispatch-macro-character #\# #\H #'hash-reader)
(defmethod print-object ((object hash-table) stream)
(if (= (hash-table-count object) 0)
(format stream "#H()")
(let ((data (loop for k being the hash-keys of object
collect k
collect (gethash k object))))
(format stream "#H~s" data))))
@cbaggers
Copy link
Author

This should be updated to use the named-readtables package so you don't pollute the global readtable

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment