Hacker News new | ask | show | jobs
by svetlyak40wt 2535 days ago
You can define your own syntax in CL:

    CL-USER> (set-macro-character #\{
           (lambda (str char)
             (declare (ignore char))
             (let ((*readtable* (copy-readtable *readtable* nil))
            (keep-going t))
        (set-macro-character #\} (lambda (stream char)
              (declare (ignore char) (ignore stream))
              (setf keep-going nil)))
        (let ((pairs (loop for key = (read str nil nil t)
            while keep-going
            for value = (read str nil nil t)
            collect (list key value)))
              (retn (gensym)))
          `(let ((,retn (make-hash-table :test #'equal)))
             ,@(mapcar
         (lambda (pair)
           `(setf (gethash ,(car pair) ,retn) ,(cadr pair)))
         pairs)
             ,retn)))))
    T
    
    CL-USER> {:foo 100500 :bar 42}
    #<HASH-TABLE :TEST EQUAL :COUNT 2 {1005879463}>
    
    CL-USER> (alexandria:hash-table-alist #v1)
    ((:BAR . 42) (:FOO . 100500))
    CL-USER> 

And define a printer for the hash to output it as desired:

    CL-USER> (defmethod print-object ((obj hash-table) stream)
               (princ "{" stream)
               (loop with indent = nil
                     for key being the hash-keys in obj using (hash-value value)
                     when indent
                       do (format stream "~% ")
                     unless indent
                       do (setf indent t)
                     do (format stream "~S ~S" key value))
               (princ "}" stream))
    #<STANDARD-METHOD COMMON-LISP:PRINT-OBJECT (HASH-TABLE T) {10040C9F83}>
    
    CL-USER> {:foo 100500 :bar 42}
    {:FOO 100500
     :BAR 42}