Luc <
n...@no.no> wrote:
> When I left the scene, dict was a pretty new addition and I never got
> around to learning it. I just read the man page and found it very
> confusing. I don't see how it's much different from a list. Looks like
> it's a list-like array or an array-like list. Whatever. I need to put
> some time aside to study it carefully.
One way of viewing it is as an array with "ordering" -- the ordering
being the insertion order of the keys.
The big difference between dicts and array's is that arrays as they
were built way back in the beginning of Tcl, are logically collections
of variables (each array entry is as if it was a separate variable
underneath).
That is why you can't use $array to get all of the contents of an
array, and why you can't use $array to pass an entire array into a proc
as a parameter. You have to pass the name of the array, and then use
upvar to link the passed in name to a variable within the proc.
Dicts are arrays that do not have that restriction of being
"collections of variables". Because of that, one can do "puts $dict" to
obtain the string representation of the dict on an output channel, and
one can use $dict to pass a dict to a proc as a parameter, instead of
having to pass in the name of the dict.
Now, one could argue that the 'definition' of arrays could have also
changed to allow $array to retreive the string rep., and to allow
passing entire arrays into a proc via $array syntax. My *guess* as to
why that was not done is doing so was likely seen as to much of a risk
of a breaking change to very old Tcl syntax, so the definiton of arrays
was unchanged and [dict] was added.
> With that said, in my ignorance, I suppose you can traverse the entire
> content of a dict, can't you? It would seem useless to me if you can't.
You can.
> So it must be possible and not even very difficult to write a proc
> that will "gut" or "disassemble" a dict in multiple parts that can then
> be compared directly with the counterparts of another dict, one to one.
For your own dicts that you create in your own programs, yes, this is
quite possible. Because you know what each leg of the tree is supposed
to be.
But creating a generic "equal" procedure, that operates on any two
arbitrary dicts from any coder's piece of code, is what is not
possible. Because any value could itself be another dict, or a plain
list, or just a string. But because Tcl is typeless, there is no way
for a generic Tcl "dict equals" to know, when encountering "this might
be a dict here" whether that is just a string of characters, a list of
six words, or a dict with three keys and three values. More often than
not, the distinction won't matter, but there will be enough instances
where the distinction does matter than a generic 'dict equals' can't be
created that works for all possible inputs.
> A little bit like comparing two directories, each one with multiple
> subdirectories and files.
Except, imagine that you can't know when you encounter something at
level 3, whether it is a file or a directory. If you don't know which
are directories, you don't know which ones to further descend into.
That's the problem with a generic 'dict equals' intended to work on any
possible input.