From: Ivan Kupalov <charlag@tutanota.com>
To: <guile-user@gnu.org>
Subject: Some reader syntax for data structures
Date: Mon, 25 Mar 2019 21:55:11 +0100 (CET) [thread overview]
Message-ID: <LaqaI6L--3-1@tutanota.com> (raw)
[-- Attachment #1: Type: text/plain, Size: 759 bytes --]
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!
[-- Attachment #2: collection-readers.scm --]
[-- Type: text/x-scheme, Size: 2032 bytes --]
(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"))))
next reply other threads:[~2019-03-25 20:55 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-03-25 20:55 Ivan Kupalov [this message]
2019-03-30 22:24 ` Some reader syntax for data structures Alex Vong
2019-04-03 20:39 ` Ludovic Courtès
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/guile/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=LaqaI6L--3-1@tutanota.com \
--to=charlag@tutanota.com \
--cc=guile-user@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).