Skip to content

Instantly share code, notes, and snippets.

@osa1
Created February 18, 2012 21:46
Show Gist options
  • Save osa1/1861099 to your computer and use it in GitHub Desktop.
Save osa1/1861099 to your computer and use it in GitHub Desktop.
Utils for PRINTing and READing CL standard hash-tables, inspired by Haskell's fromList
(in-package :cl-user)
(defpackage :m-utils
(:use :cl)
(:export :from-list :print-ht))
(in-package m-utils)
(defmacro from-list (list &rest params)
"A hash-table generator inspired by Haskell's fromList."
(let ((ht (gensym))
(item (gensym))
(key (gensym))
(value (gensym)))
`(let ((,ht (make-hash-table ,@params)))
(dolist (,item ,list)
(destructuring-bind (,key ,value) ,item
(setf (gethash ,key ,ht) ,value)))
,ht)))
(defun print-ht (ht &optional (stream *standard-output*))
"Print a READable version of a hash-table"
(prin1 `(from-list
,(loop for key being the hash-keys of ht
collect `(,key ,(gethash key ht)))
:test ',(hash-table-test ht)
:rehash-size ,(hash-table-rehash-size ht)
:rehash-threshold ,(hash-table-rehash-threshold ht))
stream))
;; since standard print function for hash-table are already
;; unreadable, this should be backward compatible
(defmethod print-object ((object hash-table) stream)
(print-ht object stream))
;; all keys and values are PRINTable with print-ht and READable with
;; from-list, as long as this vals and keys are PRINTable and READable
;; (defvar test-map (from-list '(("ok" t) ("nop" t)) :test 'equal))
;; (gethash
;; "ok"
;; (eval (read-from-string "(from-list '((\"ok\" t) (\"nop\" '())) :test 'equal)")))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment