Ticket UUID: | 1881766 | |||
Title: | Mutability | |||
Type: | Patch | Version: | TIP Implementation | |
Submitter: | ferrieux | Created on: | 2008-01-29 12:11:41 | |
Subsystem: | 10. Objects | Assigned To: | msofer | |
Priority: | 5 Medium | Severity: | ||
Status: | Closed | Last Modified: | 2008-03-08 23:50:24 | |
Resolution: | None | Closed By: | ferrieux | |
Closed on: | 2008-03-08 16:50:24 | |||
Description: |
This experimental patch, which could make it to a TIP eventually, adds optional "mutability" to container values (Lists, but the same could be done to Dicts). This means that when explicitly requested by the programmer (by the command prefix "mutant"), in-place operations may occur regardless of the sharedness of the object. Hence several other values may be simultaneously updated. The purpose is to allow passing a deeply nested substructure and modifying it in-place, without knowledge of its surroundings. Here are a few examples illustrating usage: # create a mutable set m [mutable [list 1 2 3]] # let another var hold it set n $m # mutate it mutant lappend m 4 puts $m --> 1 2 3 4 puts $n --> 1 2 3 4 # use it like an immutable in all unaware code (no "mutant") lappend n 5 ;# this forks an immutable snapshot puts $n --> 1 2 3 4 5 puts $m --> 1 2 3 4 (mutable value untouched) # now a deeper substructure set m [mutable [list 1 2 3]] set n [mutable [list 4 5 6]] set p [mutable [list 7 8 9]] mutant lappend m $n mutant lappend n $p puts $m --> 1 2 3 {4 5 6 {7 8 9}} mutant lset p 1 foo puts $m --> 1 2 3 {4 5 6 {7 foo 9}} # the cases that are not yet forbidden, but shoud shortly be: set l [list 1 2 3 [mutable [list 4 5 6]]] ;# contagion violation set m [mutable [list 1 2 3]];mutant lappend m $m; # cycle | |||
User Comments: |
ferrieux added on 2008-03-08 23:50:24:
Logged In: YES user_id=496139 Originator: YES Miguel found a conceptual show stopper: iterators. Indeed, the caller and the callee of a mutability-unaware iterator (like [foreach], which could be made mutability-aware, but extensions are allowed to declare other similar unaware functions) can cooperate to render invalid pointers kept locally in the iterator's implementation (like a pointer into a mutable list's elements array). The bottom line is that "cheating" with Tcl_IsShared is fundamentally problematic. Hence the only sound way of promoting in-place operations is to make it relatively easy to render objects truly unshared, through idioms like upvarring a global, *and* to implement optimized in-place modes wherever it is useful, like in [lrange] (see patch 1890831). Consequently, I close this tracker entry. ferrieux added on 2008-01-30 07:22:17: File Added - 264232: mutability851rc0.patch Logged In: YES user_id=496139 Originator: YES Update: - properly per-interp and mutexed => thread- and slave- safe - debug info under the control of ::tcl_traceMutable - Mass Invalidator list is made of Tcl_Obj to reuse allocator - test suite OK including mutability.test Todo: contagion; acyclicity; Dicts File Added: mutability851rc0.patch ferrieux added on 2008-01-30 07:18:16: File Deleted - 264123: ferrieux added on 2008-01-30 07:18:15: File Deleted - 264124: ferrieux added on 2008-01-30 07:16:31: File Added - 264230: mutability850.patch Logged In: YES user_id=496139 Originator: YES File Added: mutability850.patch ferrieux added on 2008-01-29 19:12:49: File Added - 264124: mutability851rc0.patch Logged In: YES user_id=496139 Originator: YES File Added: mutability851rc0.patch ferrieux added on 2008-01-29 19:11:42: File Added - 264123: mutability850.patch |