How do I read a set from a file in Racket?
It seems that if I write a set to a file, it's not in a format where it can be read back in easily as a set. Here's an example:
#lang racket (let ([out (open-output-file "test.rkt" #:exists 'replace)]) (write (set 1 2 3 4 5) out) (close-output-port out))
This makes a file with #<set: 1 3 5 2 4>, which the reader complains about. There is a related unanswered question on the mailing list here.
The way I'm getting around it right now is by printing literally the string "(set " to a file, then all the integers with spaces, then a closing ")". Super ugly and I would like to use the reader if possible.
You can use the Racket serialization library to do this. Here's an example:
Welcome to Racket v126.96.36.199. -> (require racket/serialize) -> (with-output-to-file "/tmp/set.rktd" (lambda () (write (serialize (set 1 2 3))))) -> (with-input-from-file "/tmp/set.rktd" (lambda () (deserialize (read)))) (set 1 3 2)
Note that a serialized value is just a special kind of s-expression, so you can manipulate it like other values (like store it in a database, write it to disk, send it over a network, etc.):
-> (serialize (set 1 2 3)) '((3) 1 (((lib "racket/private/set-types.rkt") . deserialize-info:immutable-custom-set-v0)) 0 () () (0 #f (h - (equal) (1 . #t) (3 . #t) (2 . #t))))