Hash Tables

Press C-c C-s "slime-complete-form" to look at function arg-lists.

  • Ergonomic problem 1: we don't see the content of the printed Hash-Table.
  • Ergonomic problem 2: you can't pass initial data to make-hash-table.

;; Hash-Table: key-value store
;; aka dictionaries, hashmaps.
;; bonus: ergonomic flaws & fixes


;; Create
(make-hash-table)

;; access keys
(defparameter *ht* (make-hash-table))
(setf 
  (gethash :name *ht*)
  :first-example-hash-table)

;; GETHASH returns 2 values:
;; - our result
;; - T if the key was found.

;; Create with initial data?
(defun make-hash-table-with-data (list-of-key/value-pairs)
  (let ((ht (make-hash-table)))
  (loop for key/val in list-of-key/value-pairs
    :do (setf
        (gethash (first key/val)
                  ht)
        (second key/val)))
  ht))

;; (ht- TAB
  • Hash-Table from third party libraries
#+(or)
(ql:quickload "alexandria")

;; (alex:hash TAB

(loop for key in (alexandria:hash-table-keys *ht*)
      :do (format t "~a: ~a~&" key (gethash key *ht*)))
  • Printing without third party libraries
(loop for key being :the :hash-key :of *ht*
      :do (print key))

(maphash (lambda (k v)
            (format t "key ~a = ~a" k v))
          *ht*)
  • Better ergonomics

#+(or)
(ql:quickload "serapeum")

(defpackage :dict-user
  (:use :cl)
  (:import-from :serapeum
   :dict)
  (:documentation "cl-user + dict"))

(in-package :dict-user)

;; C-c ~
;; in REPL:
;; (serapeum:toggle-pretty-print-hash-table t)
;; (dict :a 1 :b 2)

;; no need of new syntax like { }
;; no reader macros like #M( _ )