I just noticed that arc's copy on lists doesn't create copies of the car. So lists of lists are only shallow-copied. ; called from copy when xs is a list
(def copylist (xs)
(if (no xs)
nil
(cons (car xs) (copylist (cdr xs)))))
Does this seem like the right semantic for copy? I'm inclined to say no, that copy should be powerful at the price of performance. What do y'all think?The drawback of a deeper copy is that the above function needs to be inlined into arc's list function, which is currently: (def list args
(copylist args))
I'll update anarki if there's no objections.--- Incidentally, the definition of copy is a great illustration of wart's strengths. This: (def copy (x . args)
(let x2 (case (type x)
sym x
cons (copylist x)
string (let new (newstring (len x))
(forlen i x
(= (new i) (x i)))
new)
table (let new (table)
(each (k v) x
(= (new k) v))
new)
(err "Can't copy " x))
(map (fn ((k v)) (= (x2 k) v))
(pair args))
x2))
Becomes this: # in list.wart
def (copy x)
if ~cons?.x
x
(cons copy:car.x copy:cdr.x)
# in table.wart
def (copy x) :case table?.x
(as table (as list x))
def (copy x ... merge_args) :case merge_args
ret result copy.x
each (k v) pair.merge_args
result.k <- v
It's about the same length, but various concerns are disentangled. It does something reasonable for every type, including numbers and user-defined types.I just noticed today that arc's copy had that additional semantic of merging in new args, and it turned out to be easy to add. Can Nulan add it cleanly? :) (Ignoring whether it's a good idea or not.) |