Skip to content

Instantly share code, notes, and snippets.

@privet-kitty
Last active March 2, 2023 20:46
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save privet-kitty/e5abd3f09485c5828af81ad02e8c2baf to your computer and use it in GitHub Desktop.
Save privet-kitty/e5abd3f09485c5828af81ad02e8c2baf to your computer and use it in GitHub Desktop.
Clojure's {} in Common Lisp
;; {}: Map literal like Clojure
;; Note:
;; 1. Equality operator is #'eql.
;; 2. {} is a literal here though it is a constructor in Clojure:
;; Clojure:
;; (:b {:a 1 :b (+ 1 2)}) => 3
;; CL:
;; (gethash :b {:a 1 :b (+ 1 2)}) => (+ 1 2)
(eval-when (:compile-toplevel :load-toplevel :execute)
(ql:quickload :named-readtables)
(use-package :named-readtables))
(defun plist-to-hash (plist &rest hash-table-initargs)
"slightly modified version of alexandria:plist-hash-table"
(let ((table (apply #'make-hash-table hash-table-initargs)))
(do ((tail plist (cddr tail)))
((null tail) table)
(when (null (cdr tail))
(error "The length of ~S is not even." plist))
(setf (gethash (first tail) table)
(second tail)))))
(defun read-hash (stream char)
(declare (ignore char))
(let ((*readtable* (copy-readtable)))
(set-macro-character #\} nil)
(set-syntax-from-char #\, #\space)
(plist-to-hash (read-delimited-list #\} stream t)
:test #'eql)))
(defreadtable :test-table
(:merge :standard)
(:macro-char #\{ #'read-hash))
(in-readtable :test-table)
(format t "Moved to the test read-table.~%")
(format t "(gethash :b {:a 1, :b 2, :c 3})~%=> ~S~%" (gethash :b {:a 1, :b 2, :c 3}))
(format t "(get-macro-character #\\{)~%=> ~S~%" (get-macro-character #\{))
(in-readtable :standard)
(terpri)
(format t "Returned to the standard read-table.~%")
(format t "(get-macro-character #\\{)~%=> ~S" (get-macro-character #\{))
;; $ sbcl --load map-literal.lisp --quit
;; Moved to the test read-table.
;; (gethash :b {:a 1, :b 2, :c 3})
;; => 2
;; (get-macro-character #\{)
;; => #<FUNCTION READ-HASH>
;; Returned to the standard read-table.
;; (get-macro-character #\{)
;; => NIL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment