|
From: Alexandre F. <ale...@gm...> - 2008-01-18 15:45:52
|
On Jan 18, 2008 9:33 AM, Andreas Leitgeb <av...@lo...> wrote: > On Fri, Jan 18, 2008 at 12:53:17AM +0100, Alexandre Ferrieux wrote: > > Mutability - principle > > ----------------------------- > > ... > > Maybe, you would have mentioned it anyway, sooner or later, Indeed. That was the plan just after the sleep :-) > But I'm curious now about the following: > > set m [create mutable list with initial elements: 1 2 3] > set n $m > lset m 0 foo; # $m now "foo 2 3", ditto $n > so far so clear, but: > set o [lreplace $m 1 2 bar]; # $o now "foo bar", $m,$n unchanged(?) Yes. [lreplace] is functional. See below. > set m $o ; # does this modify the mutable list, or replace it? Replaces. [set] forgets the old value anyway. So it makes sense to overwrite the reference rather than dereferencing and updating in-place (which may be impossible if the types are different). > Since you mention "in-place" modifying operations, my guess is, > that [lreplace...] would not modify a passed in mutable list, but > just create a new (mutable?) one. A new immutable one. See below. > What would be the procedure to apply a command like lreplace > to a mutable list, such as to "fake" an in-place operation on > the mutable list, such that it would then be visible to other > holders of that list-value? I think the only safe way or reusing existing commands for in-place operations, is to do this only to those commands that modify a variable (like [lappend] but unlike [lreplace]). Indeed, otherwise we'd violate the very functional (documented) nature of [lreplace] [lrange] et... So the change in behavior for "homogeneous" (list->list and dict->dict) operations is precisely as follows: - a small and well-defined set of commands, that already act in-place on a variable, are modified so that they update the value when it is mutable: [lappend] [lset] [dict set] ... - all others take an immutable snapshot of mutable values: [lrange] [lreplace] [dict replace]... Of course, for heterogeneous operations like [lindex], there's nothing to change, the value returned keeping its original mutable status. Thus [foreach] can iterate with no constraints on a (mutable) list of mutable dicts, and give access to each dict as mutable. Then, this leaves the question of how to do the equivalent of [lreplace] in-place on a mutable list ! (for dicts, no problem since [dict set] and [dict unset] are here to mutate). So far I have the impression that the only way is by offering a new [mlreplace]. I will do in my patch. The nice thing with the lreplace function, is that it's a Swiss Army knife able to append, prepend, slice, dice, and even reset to an empty or existing list. So, cloning it is not too bad a choice... -Alex |