Arc Forumnew | comments | leaders | submitlogin
Wart: File I/O for tables
4 points by akkartik 3928 days ago | 2 comments
It's bothered me for a while that we need read/write-table, that just read/write don't suffice. The reason seems to be: mzscheme reads tables from file as immutable tables.

  > (= a (obj 1 2 3 4))
  > (w/outfile f "x" (write a f))
  > (w/infile f "x" (= b (read f)))

  > (= (a 5) 6) ; Works
  > (= (b 5) 6) ; Error: "hash-set!: expects type <mutable table> as 1st argument..
You can't tell if b is immutable except by trying to add to it. Totally sucks:

  > (type a) ; table
  > (type b) ; table
  > (iso a b) ; t
So we're stuck with functions read/write-table that convert tables to and from lists of pairs, but that too is a leaky abstraction -- nested tables turn immutable after reading from file:

  > (= a (obj 1 2 3 (obj 4 5 6 7)))
  > (w/outfile f "x" (write a f))
Now look at x and see that it has the #hash objects of doom.

I've spun off arc's primitives to create versions that work with nested tables in the usual way:

  (def tablist? (l)
    (if (isa l 'cons)
        (all 2 (map len l))))

  (def coerce-tab (l)
    (if (tablist? l)
      (listtab2 l)

  (def listtab2 (al)
    (let h (table)
      (map (fn ((k v)) (= (h k) (coerce-tab v)))

  (def read-nested-table ((o i (stdin)) (o eof))
    (let e (read i eof)
      (if (alist e) (listtab2 e) e)))

  (def tablist2 (h)
    (if (isa h 'table)
      (accum a (maptable (fn (k v) (a (list k (tablist2 v)))) h))

  (def write-nested-table ((o o (stdout)))
    (write (tablist2 h) o))
Question: should something like these versions supercede read-table and write-table?

Arc philosophy doesn't seem to care much about immutability. Does mzscheme have primitives for reading/writing mutable tables? Can we just use them throughout? Why does mzscheme make mutable hashes immutable when writing them to file?

Prior discussion:

3 points by akkartik 3907 days ago | link

Ah, you can copy immutable hashes into mutable ones with hash-copy. ( Why was this so hard to figure out?


2 points by akkartik 3921 days ago | link

Sorry, the nested tables example should be:

  > (= a (obj 1 2 3 (obj 4 5 6 7)))
  > (w/outfile f "x" (write-table a f))