Tcl Source Code

View Ticket
Login
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

Attachments: