Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

dict traces ...

37 views
Skip to first unread message

MartinLemburg@Siemens-PLM

unread,
Feb 3, 2008, 3:06:19 PM2/3/08
to
Hi,

since the introduction of dict's I was a bit suspicious about my own
usage of dict's. Will I use them? The syntax is more complicated than
the array's one, if I only substitute an array by a dict, not using
the other features via the dict API.

Now ... holding data for an UI in a dict I suddenly see, that I have
to switch back to an array or scalar variables, because I want to
trace changes inside this dict to reflect them inside the UI.

So ... suddenly I realize, that I can not specifiy a dict with a key
as data source for a widget, but I can specify an array element!
And ... I can not trace the change or usage of a dict key, while I can
trace an array element.

If there is a chance to introduce tracing for dict keys or on dicts in
general (like on arrays in general), than I would like to examine it
and to write a TIP like I did for "namespace import".
The main help I would need is, to get some hints, where to look to in
the sources, to see how traces are implemented on arrays and scalar
variables.

Some thoughts about such traces:

1. dict set|lappend|append|... => write trace
2. dict get => read trace
3. dict remove => unset trace
4. dict keys => read trace
5. dict values => read trace
...

And ... is there a chance to add to such widgets with "-listvariable",
or "-textvariable" options a kind of "-dictkey" option, so that - if
configured - only the value of the key of the configured variable will
be used - if the variable content is a dict or is convertable into a
dict?
If there is a chance, than I would like to write a TIP, too!

Best regards,

Martin Lemburg

Alexandre Ferrieux

unread,
Feb 3, 2008, 3:48:06 PM2/3/08
to
On Feb 3, 9:06 pm, "MartinLemburg@Siemens-PLM"

<martin.lemburg.siemens-...@gmx.net> wrote:
> Hi,
>
> since the introduction of dict's I was a bit suspicious about my own
> usage of dict's. Will I use them? The syntax is more complicated than
> the array's one, if I only substitute an array by a dict, not using
> the other features via the dict API.
>
> Now ... holding data for an UI in a dict I suddenly see, that I have
> to switch back to an array or scalar variables, because I want to
> trace changes inside this dict to reflect them inside the UI.
>
> So ... suddenly I realize, that I can not specifiy a dict with a key
> as data source for a widget, but I can specify an array element!
> And ... I can not trace the change or usage of a dict key, while I can
> trace an array element.
>
> If there is a chance to introduce tracing for dict keys or on dicts in
> general (like on arrays in general), than I would like to examine it
> and to write a TIP like I did for "namespace import".

If you look for discussions on dicts and arrays here in the last few
months, you'll find ample material about the spirit of the
*coexistence* of the two types. Basically, dicts are not meant to
obsolete arrays. Arrays and dicts are two different species that dwell
in different ecological niches, even though an interesting area of
intersection also exists.

The key difference is that dicts are values, while arrays can be seen
as just families of sililarly-named scalar variables. There's a
compromise here: being variables brings traces to arrays, while having
none of this machinery allows dicts do be more "lightweight". In fact,
dicts are just like lists, but with a slightly different [lindex].
Would you request traces on a list's elements ?

So, the answer to your question would be: if you need traces on a
dict's contents, then most likely what you really need is an array.
Unless of course you bring evidence to the contrary.

-Alex

MartinLemburg@Siemens-PLM

unread,
Feb 3, 2008, 3:58:49 PM2/3/08
to
Thanks Alexandre for your description!

For me - ignoring the "implementation" of lists, dicts and arrays -
all these "data types" are kinds of structured data.

While IMO lists are "only" indexed data fields, dicts and arrays are
much more structured.

While arrays allow us to trace elements usage and to use them element-
wise inside the UI, the structured dict-data inside a variable can not
be used for those purposes.

Ignoring the fact, that a list and a dict are only variable contents
and an array is a "collection" of variables, but only focussing on the
usage of data, let me say, that I'm missing something.

So - I have to use an UI array to store dict-structured data from my
data source for displaying and controlling?
And changes on the data source are only reflected by traces on the
whole data, but on the interesting parts of the data?
To reflect changes inside a dict, I have to hold a copy of the dict or
its data in an array and to compare the contents.
Why not acting a bit specific - using dict traces, dict key access in
UI elements (widgets)?

Ok - I will read on in this thread ...!

Best regards,

Martin Lemburg

On Feb 3, 9:48 pm, Alexandre Ferrieux <alexandre.ferri...@gmail.com>
wrote:

Alexandre Ferrieux

unread,
Feb 3, 2008, 4:05:13 PM2/3/08
to
On Feb 3, 9:58 pm, "MartinLemburg@Siemens-PLM"

<martin.lemburg.siemens-...@gmx.net> wrote:
>
> So - I have to use an UI array to store dict-structured data from my
> data source for displaying and controlling?

Why in the first place are your data dict-structured ?
Can't you instead do it with arrays all the way from data source to
GUI ?

-Alex

Keith Nash

unread,
Feb 6, 2008, 4:42:47 PM2/6/08
to
MartinLemburg@Siemens-PLM wrote:

> Thanks Alexandre for your description!
>
> For me - ignoring the "implementation" of lists, dicts and arrays -
> all these "data types" are kinds of structured data.
>
> While IMO lists are "only" indexed data fields, dicts and arrays are
> much more structured.
>
> While arrays allow us to trace elements usage and to use them element-
> wise inside the UI, the structured dict-data inside a variable can not
> be used for those purposes.
>
> Ignoring the fact, that a list and a dict are only variable contents
> and an array is a "collection" of variables, but only focussing on the
> usage of data, let me say, that I'm missing something.
>
> So - I have to use an UI array to store dict-structured data from my
> data source for displaying and controlling?
> And changes on the data source are only reflected by traces on the
> whole data, but on the interesting parts of the data?
> To reflect changes inside a dict, I have to hold a copy of the dict or
> its data in an array and to compare the contents.
> Why not acting a bit specific - using dict traces, dict key access in
> UI elements (widgets)?

I agree with the view of dicts and arrays as different kinds of "structured
data", even if the implementation is different. If a dictionary value is
held in a variable, it would be useful if individual dictionary elements
could have the behaviour of a variable (including the use of traces and
upvar).

If such a change were technically possible, then nearly all the
functionality currently provided by arrays would also be available from
dictionaries. A significant cleanup would be possible at the next revision
of Tcl that breaks backwards compatibility.

http://wiki.tcl.tk/1203 "Better Arrays for Tcl9"


Keith.

Joe English

unread,
Feb 6, 2008, 9:03:46 PM2/6/08
to
Keith Nash wrote:

> I agree with the view of dicts and arrays as different kinds of "structured
> data", even if the implementation is different. If a dictionary value is
> held in a variable, it would be useful if individual dictionary elements
> could have the behaviour of a variable (including the use of traces and
> upvar).

They cannot.

If you have:

set a 1
set b "foo"
set c [list x y z]

you can put a trace on the variables "a", "b", or "c";
but you can't put a trace on the number 1, the string "foo",
the list {x y z}, or the second element of the list {x y z}.

The number 1 never changes -- it's always 1. The string
"foo" never changes -- it's always "foo". The list {x y z}
is always the list {x y z}, and its second element is always "y".
You can't put a trace on any of these things, because they're
values; you can only put a trace on the variables holding
those values.

Dictionaries are also values.


--JE

MartinLemburg@Siemens-PLM

unread,
Feb 7, 2008, 3:56:14 AM2/7/08
to
Hi Joe,

my question was not ... how to create trace on variables, because
dicts are values!

My question was about to allow to trace structured data, like a
dictionary.
And using an array I don't care about the fact, that they are
containers for variables. Arrays are for me structured data, like a
list is too.

Why I don't ask for a trace on list elements?

I forgot it, because I never needed this kind of trace.

So the discussion for me is about something new - traces on structured
data, on elements of structured data, so on values, not on variables!

BTW - you can define a dict in another way ... a list of variable
names and their values to be hold by a variable. While this list is
comparable to the list we can get with [array get ...].
And since dicts use hashtables like an array does, I thought it might
be possible to introduce traces on dicts and their keys.

So let's talk about the possiblities, and usabilities of a future
features! While the 2nd feature I asked for was to allow UI elements
to reflect elements of structured data, like a key of a dict!

My use case for these 2 features is to allow to use dicts inside of an
UI and to react on changes made in such UI.

Best regards,

Martin Lemburg

Alexandre Ferrieux

unread,
Feb 7, 2008, 4:09:24 AM2/7/08
to
On Feb 7, 9:56 am, "MartinLemburg@Siemens-PLM"

<martin.lemburg.siemens-...@gmx.net> wrote:
> So the discussion for me is about something new - traces on structured
> data, on elements of structured data, so on values, not on variables!

Currently in Tcl values are immutable, and can be seamlessly shared or
copied (COW).
So, it doesn't make sense to attach a write trace to a value, since
the only things that can happen to it are either to be freed (nobody
referencing it any more) or silently copied somewhere else.

Mutability is a slippery avenue, which we happen to be evaluating on
tclcore just for the fun.
But the purpose is not at all that of write traces, it is instead
efficient in-place operations.

So, the only reasonable thing that could (and does) support traces is
a variable, simply because that's the only place where "change over
time" is meaningful.

Now please, again, tell us concretely what today you cannot do with
write traces on scalar or array variables, that seem to motivate so
strongly the quest for traceable values ?

-Alex

Donal K. Fellows

unread,
Feb 7, 2008, 5:56:38 AM2/7/08
to
MartinLemburg@Siemens-PLM wrote:
> My question was about to allow to trace structured data, like a
> dictionary.

You can't. If you could (leaving aside the whole discussion about
mutability) you'd be forcing every user of dictionaries to carry a lot
of cost (both time and memory) to support traces.

> And using an array I don't care about the fact, that they are
> containers for variables. Arrays are for me structured data, like a
> list is too.

You are confused. There are two types of entity in play here: variables
and values. Variables are mutable and traceable. Values are constant
(unless nothing else is looking, and that's *just* a performance
enhancement). Arrays are variables that are collections of variables.
Dicts (and lists) are values that are collections of values.

> So the discussion for me is about something new - traces on structured
> data, on elements of structured data, so on values, not on variables!

Well, you don't need traces on structured values since they never
change. You'll never get a write trace callback, and what would be the
point of a read trace callback? (You might also find that the answers
such a thing would produce would surprise you, since we're fairly
aggressive about sharing references to values where we can.)

> BTW - you can define a dict in another way ... a list of variable
> names and their values to be hold by a variable. While this list is
> comparable to the list we can get with [array get ...].
> And since dicts use hashtables like an array does, I thought it might
> be possible to introduce traces on dicts and their keys.

I suppose we could define any word to mean anything. But what would be
the point of that? Handlebar tea-kettle dingo-wombat? Republican quarter
stereophonic zoom-zoom distort handbag. ;-)

> So let's talk about the possiblities, and usabilities of a future
> features! While the 2nd feature I asked for was to allow UI elements
> to reflect elements of structured data, like a key of a dict!

You can put a trace on a variable containing a dictionary such that some
other variable reflects a value mapped to by a specific key within
whatever dictionary is contained in the first variable. That's not
difficult (harder to describe than to do!) With that, you can then tie
the UI element to variable containing that extracted value and it will
all "just work". And you can do that today.

Or we could enhance the variable-coupling code in Tk so that it can
update its linked variables in ways give a similar effect without
needing to create an intermediate variable. But that's not at all the
same as tracing a value; not even close.

> My use case for these 2 features is to allow to use dicts inside of an
> UI and to react on changes made in such UI.

Reasonable. But it is the UI elements that need enhanced powers of data
manipulation, not the values that need enhanced traceability. (In fact,
I'd not be opposed to enhancing Tk this way at all.)

Donal.

Keith Nash

unread,
Feb 7, 2008, 8:00:06 AM2/7/08
to
I think there is a problem of communication between those who are familiar
with the C implementation of Tcl, and those (like me) who view the
documentation as a set of rules and ask what is logically possible but
without much understanding of the Tcl internals.

set a 1
set b [dict create foo 2 bar 3]

Obviously one cannot trace the value of "1"; but it is possible to trace
reads and writes to a. Equally, one cannot trace the value of "2", but it
is possible to trace reads and writes to b, and if those reads and writes
occur by dictionary commands it is possible to trace whether they occur to
the key "foo". Though it is logically possible it may be at odds with the
way Tcl is implemented.

Keith.

Neil Madden

unread,
Feb 7, 2008, 9:01:11 AM2/7/08
to

That is entirely possible. This is simply a regular trace on the
variable that filters based on the dict key being accessed. However,
you'd have to decide what to do in all the corner cases where the
variable is accessed using something other than the dict commands, or
changed to be a non-dict value. e.g.:

set foo {a 1 b 2}
dict trace foo a write ...
dict trace foo b unset ...
set foo {a b c}

What happens here? What traces fire (if any)? Is an error generated? Do
the traces get removed?

I don't see any of those choices presenting themselves as obviously the
correct approach. I also don't see why dicts need to support this
functionality, given that we already have arrays and namespaces that
support trace-able elements. You can even put a fully-qualified variable
name into a dict and trace that.

-- Neil

Keith Nash

unread,
Feb 7, 2008, 12:57:09 PM2/7/08
to
Neil Madden wrote:

<snip>

> I also don't see why dicts need to support this
> functionality, given that we already have arrays and namespaces that
> support trace-able elements. You can even put a fully-qualified variable
> name into a dict and trace that.

My own motivation is easier use of dictionaries, by giving them the ()
syntax currently used for arrays. Most array operations could then be
simulated with dictionaries:

http://wiki.tcl.tk/1203

Others pointed out that one thing that cannot be simulated is the ability to
trace an array element.

If we could use the () syntax to specify dictionary elements, including
those with key paths longer than 1, then code for a dictionary value stored
in a variable would be greatly simplified: for example if we have

set a [dict create foo 2 bar [dict create fred 3 wilma 4]]

then we could write

# (A)
append a(bar fred) 5
set b $a(bar wilma)

instead of

# (B)
dict set a bar fred [dict get $a bar fred]5
set b [dict get $a bar wilma]

(dict append is not useful for key paths longer than 1). (A) is clearly
much more comprehensible than (B).

This suggestion cuts across the ideas of variables and values, as the
discussion of tracing has shown; maybe this makes it impractical to
implement.

The new dictionary facilities are very useful, but I would like the code to
be easier to read - much easier.

I'm not sure that the extra features of arrays (compared to dicts) are
worthwhile. Put it another way: if Tcl had dictionaries and namespaces but
not arrays, the suggestion of adding arrays to the language would probably
not be well received.

Keith.

Donal K. Fellows

unread,
Feb 8, 2008, 8:15:05 AM2/8/08
to
Keith Nash wrote:
> I'm not sure that the extra features of arrays (compared to dicts) are
> worthwhile. Put it another way: if Tcl had dictionaries and namespaces but
> not arrays, the suggestion of adding arrays to the language would probably
> not be well received.

True. If I was starting from there, I wouldn't go here either. But here
we are anyway. Easier to not speculate on other routes that we might
have taken but didn't. :-)

Donal.

0 new messages