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)
l))
(def listtab2 (al)
(let h (table)
(map (fn ((k v)) (= (h k) (coerce-tab v)))
al)
h))
(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))
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: http://arclanguage.org/item?id=8145 |