|
From: Neil M. <ne...@Cs...> - 2008-01-18 16:27:30
|
On 17 Jan 2008, at 23:53, Alexandre Ferrieux wrote:
>
> OK, sorry for the delay :-) Here it goes.
> Sorry in advance for the obvious introduction, but let's start from
> the basics to be sure.
>
> Mutability - principle
> -----------------------------
>
> Values in Tcl, be they "scalars" like integers or strings, or
> "containers" like lists or dicts, are so far strictly independent from
> one another. Hence, in
>
> # assuming no trick like upvar #0 x y
> set x [function call returning some value]
> set y $x
> do anything to y
>
> the $x value will *never* be touched by whatever is done to the
> variable y, including "in-place" operations like [lappend], [lset],
> etc. In other words, as seen from the script level, values can just be
> copied, never passed "by reference".
Nit picking, but values, strictly speaking, are always immutable.
It's variables that are passed by reference in most languages, or
some kind of first-class reference cell or "object". This is an
important point, because presumably it doesn't make sense to make the
Tcl_Obj representation of "2" mutable. I mean, if "2" gets changed to
"3", what has happened? What *is* the explanation of:
set a [mutable 2]
convert $a 3 ;# assuming "convert" is rough analogue of set
Right now the equivalent is simple: "a" is a variable, which
initially contains 2 and then contains 3. But in the new world, what
exactly is this thing that contains 2 and then contains 3? We clearly
(hopefully) haven't changed the number 2 itself, and the variable "a"
hasn't been touched, so what is this extra thing and what are its
properties?
> Now let's introduce a special state for Tcl values: "mutable".
> We define it by the fact that all the usual "copy" operations are now
> turned into "pass a reference". Thus:
>
> set m [function call returning a mutable value]
> set n $m
> do something in-place to m (or $m)
> # $n is updated too !
Which we of course have now in many forms, e.g.:
set m [frame .f]
set n $m
$m configure -text "Foo"
etc.
> ...
> I have a slight preference for (c) as it helps people maintain a clear
> boundary between mutables and immutables in their programs, which is
> IMO a Good Thing considering that mutability basically violates what
> was previously nearly a fundamental principle of Tcl.
Yes, it does. Given that Tcl already quite nicely separates values
from mutable variables, why introduce another layer?
>
> Mutability and existing commands
> -------------------------------------------------
>
> Defining mutability as a *state* of existing Tcl values has one
> notable advantage: we may reuse many existing commands, only adapting
> their behavior slightly to respect the new "reference" semantics
> instead of the old "copy" mechanism when writing. This makes [lappend]
> [lset] and [dict set] the canonical tools to update mutable lists and
> dicts. Also, [lindex] and [dict get] need no modification to be the
> natural read-only accessors.
lappend, lset, etc operate on variables, not values. So converting
them to also operate on "mutable" values would seem to be quite a
large and surprising change in their behaviour.
>
> Now, we need primitives to change the mutability state. This is
> done with
>
> set l [list 1 2 3] ;# $l is immutable
> set m [mutable $l] ;# $l is untouched, still immutable
So m is now a mutable variable containing a mutable value? This seems
like a lot of duplication. Will mutable values support traces like
variables? This all seems far more complicated than would seem
justified by any potential benefits of introducing mutability into
Tcl values.
>
> Applications of Mutability
> ------------------------------------
>
> Apart from aesthetic considerations, mutability also helps define
> modular in-place algorithms. For example, a large mutable list of
> mutable dicts can be maintained, and from time to time pass one of its
> dicts to a an in-place manipulation function that doesn't know (nor
> wants to) about the nesting:
>
> foreach d $mutable_list_of_mutable_dicts {
> transitive_closure d
> }
For dicts, doesn't [dict with] and [dict update] solve many of these
same problems? Designing a similar facility for lists could be a
useful addition.
I'm still struggling to see a really compelling use-case for these
mutable things. Introducing mutability at the Tcl_Obj level really
lets the cat out of the bag in that you then have to be aware of the
possibility of mutation in almost every piece of code you write.
IMO, the correct way to approach any perceived deficit in this area
would be to examine why variables are not suitable for the job, and
what precisely would need to change to make them suitable.
-- Neil
This message has been checked for viruses but the contents of an attachment
may still contain software viruses, which could damage your computer system:
you are advised to perform your own checks. Email communications with the
University of Nottingham may be monitored as permitted by UK legislation.
|