Introducing Tcl 8.7 Part 5: dictionary enhancements

Published

This is the fifth in our series describing new features in the upcoming Tcl 8.7 release. This post deals with the enhancements related to dictionaries.

To take Tcl 8.7 for a spin, you can download a pre-alpha binary for your platform. Alternatively, you can build it yourself from the core-8-branch branch in the Tcl fossil repository.

Defaults for missing elements with dict getwithdefault

A common need when using dictionaries in Tcl is dealing with missing keys and using a default in such cases. For example, TDBC will represent NULL values in database rows by omitting the key corresponding to that column. Thus the following type of code fragment is frequently encountered in Tcl code:

if {[dict exists $dict_value $key]} {
    set value [dict get $dict_value $key]
} else {
    set value "some default"
}
some_command $value

There are other variants using expr or using if as an expression. All are ugly and verbose. The number of wrappers people write for this fragment are proof enough.

Tcl 8.7 fixes this irritation with the dict getdefault command. This essentially works as dict get but takes an additional argument that will be returned by the command if the key does not exist in the dictionary. The above fragment then simply becomes

some_command [dict getwithdefault $dict_value $key "some default"]

Oh joy!

And like dict get, the command works with nested dictionaries as well.

% set dict {a {x 1} b {y 2}}
a {x 1} b {y 2}
% dict getwithdefault $dict a x 42
1
% dict getwithdefault $dict a z 42
42

Not exactly earth shattering but likely a command that will see maximal use in Tcl 8.7 based code.

Checking dictionary format with string is dict

The string is command can check if the passed value has a valid interpretation as a specific type such as an integer, list etc. However, for whatever reason, it did not provide an option to check for dictionary values. A workaround was to check if a value was a valid list of even length which felt somewhat klugy and also had a performance impact due to internal shimmering of the dictionary to a list form.

Tcl 8.7 now supports the string is dict command for this purpose.

% string is dict {a 1 b 2}
1
% string is dict {a 1 b}
0

Perhaps not a common need, but it fixes an oversight in the string command.

References

  1. TIP 342: Dict Get With Default

  2. TIP 501: string is dict

  3. Dict manpage

  4. string manpage