Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 962
Chris Brooks Avatar asked Mar 14 '23 07:03

Chris Brooks


1 Answers

You can use the Racket serialization library to do this. Here's an example:

Welcome to Racket v6.4.0.7.
-> (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))))
like image 128
Asumu Takikawa Avatar answered Apr 13 '23 07:04

Asumu Takikawa