On Fri, Mar 14, 2008 at 3:51 PM, Tobias C. Rittweiler tcr@freebits.de wrote:
In case b): If the code frobs destructively, the destructive operation is often not only restricted to the hash-table per se, but also to the data structures contained in the hash-table.
Notice that COPY-HASH-TABLE is still shallow by default. It's just that hash-tables are used in more complex situations, justifying a bit more flexibility.
This is obviously a question of taste, but IMO in this case the deep copying should be done by the frobber, not the copy-hash-table operation. ...but my own main objection is that it is not too obvious what :KEY means there.
Perhaps you might be better served with MAP-HASH-TABLE, which maps into a new hash-table? Something like this (untested), maybe:
(defun map-hash-table (function table &rest more &key test size rehash-size rehash-threshold) "Calls FUNCTION with every key and value in hash-table TABLE, and saves the returned value under the same key in a new hash-table. Finally returns the new hash-table. The new table has the same properties as the original, unless overridden by the keyword arguments. Implementation specific hash-table properties are not copied by default, but can be specified using keywords." (setf test (or test (hash-table-test table)) size (or size (hash-table-size table)) rehash-size (or rehash-size (hash-table-size table)) rehash-threshold (or rehash-threshold (hash-table-rehash-threshold table))) (let ((real-function (ensure-function function)) (copy (apply #'make-hash-table :test test :size size :rehash-size rehash-size :rehash-threshold rehash-threshold more))) (maphash (lambda (k v) (setf (gethash k copy) (funcall real-function k v))) table) copy))
(My use-cases for COPY-HASH-TABLE are mainly for debugging: grab a copy of an application internal hash-table at a certain point in time, and then poke at it at leisure.)
Cheers,
-- Nikodemus