From: <Joe...@t-...> - 2016-09-22 15:47:24
|
Hi, All languages I know with good enough documentation disallow modifying hash-tables while iterating over them. CLHS: http://www.lispworks.com/documentation/HyperSpec/Body/f_maphas.htm#maphash "The consequences are unspecified if any attempt is made to add or remove an entry from the hash-table while a maphash is in progress, with two exceptions...[setf current and remhash current entry]" The technical reason is that iterators typically embed pointers into the complicated hash-table structure; destructive modification of said structure would break havoc. Yesterday I talked with Bruno and the idea arose to have CLISP signal an error in that case, given that the CLISP philosophy has always been to minimize unspecified behaviour. The curious & adventurous might try and see how the various Lisp implementations reacting to modifications of various elements of a hash-table while its being walked through (incl. nested walks): which crashes, which behaves? We discussed plausible implementations and Bruno mentioned stack frames like those known from unwind-protect or let that would a) link one iterator on the stack to the next (both maphash and loop::%hash-table-iterator) and b) help locate the current entry whose modification is allowed. I believe no modification is allowed at all if 2 iterators are active (on the same table) and they are currently processing different entries. Thinking again about this, an alternative implementation comes to mind: check within the iterator whether a modification took place. I have no idea how much these checks would slow down (SETF GETHASH) and REMHASH or iteration. The outcome: this might help people using clisp find complex and hard to trace bugs in code that uses maphash/loop a lot with non-trivial code. Signaling an error is a very reasonable choice. Of course, if clisp's internal hash-table implementation were changed to better support MT, introducing a data structure that allows concurrent updates would perhaps also support nested updates, then that would not be an error condition any more. Regards, Jörg Höhle |