Hello everyone!
I wanted to learn some Scheme before starting one project and it seemed to me
that it might be a nice exercise to try and extend syntax for hash tables, a-la
Clojure/Rackjure (and only later I've learned about Racket's `#hash()`).
I think it's really not optimized and not even really elegant but it works!
(readers don't have much documentation attached to them unlike macros so it was
kinda difficult). I later extended it to vhashes and vlists because I already
had some understanding on what is required from me.
(also here's a link in case something doesn't work, I didn't use mailing lists
much before: https://gitlab.com/snippets/1838863)
<https://gitlab.com/snippets/1838863>
So I just wanted to share. Feel free to send feedback!
(use-modules (ice-9 match))
(use-modules (ice-9 vlist))
(use-modules (srfi srfi-1))
(eval-when (expand load eval)
(define (read-hash-table-2 datum)
(let ((insertions (map (match-lambda
((key value)
`(hash-set! table ,key ,value)))
datum)))
(append
`(let ((table (make-hash-table ,(length insertions)))))
insertions
'(table))))
(define (read-vhash-table datum)
(let ((datum (reverse datum)))
(fold (lambda (el acc)
(match el
((key value)
`(vhash-consq ,key ,value ,acc))
))
'vlist-null
datum)))
(define (read-vlist datum)
(list 'list->vlist (cons 'list datum)))
(read-hash-extend #\h (lambda (chr port)
(read-hash-table-2 (read port))))
(read-hash-extend #\v (lambda (chr port)
(let ((type (read port))
(definition (read port)))
(cond
((eq? 'h type) (read-vhash-table definition))
((eq? 'l type) (read-vlist definition))
(else (error "woah I don't know this syntax")))))))
(define characters #h(('you "hooman") ('me "schemer")))
(display "I am a ")
(display (hash-ref characters 'me)) ;; => schemer
(newline)
(define demo-table
#h(
('name "Demo name")
('version "3.45.5")
('dependencies #h(
('hash-map-syntax "0.0.1")))
((string-append "computed-" "key") #t)))
(display (hash-ref demo-table "computed-key")) ;; => #t
(newline)
(define demo-vhash #vh(
('vh "vhash")
('vl "vlist")))
(define demo-vlist #vl(
"Nice"
"Syntax"
#vl(
"For"
(string-append "Efficient" " " "structures"))))