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

dict string representation rant

256 views
Skip to first unread message

Christian Gollwitzer

unread,
Jul 13, 2011, 4:22:05 PM7/13/11
to
Hello,

I'd like to propose an alternate string representation for dicts. The
standard representation is compact and good for small dicts, but in my
application I serialize objects to nested dicts that go 3-4 levels deep,
and the standard representation "$dict" becomes very unreadable. But the
list format allows to insert any whitespace/tabs/linebreaks without
changing the semantics; for a nested dict with known dimension, the
below code produces a much more readable output:

55 % dict set d Section1 key1 value1
Section1 {key1 value1}

56 % dict set d Section1 key2 newvalue
Section1 {key1 value1 key2 newvalue}

57 % dict set d Section2 key "string with spaces"
Section1 {key1 value1 key2 newvalue} Section2 {key {string with spaces}}

58 % dict_format $d 2
Section1
{ key1 value1
key2 newvalue
}
Section2
{ key {string with spaces}
}

This output is itself a valid dict with the same contents as the
original. But this is bound to the knowledge of the dimension (nesting
depth) of the dict -- especially when the different branches end on
different levels, there is no luck:(
One could, in principle, hack something with
tcl::unsupported::representation, but that's discouraged with good reason.

So, now its too late to change the standard string serialization of
dicts, I would propose a "dict format" subcommand. This dict format
would properly indent to show the structure of the dict, and decide by
looking at the internal representation, whether the current value is a
dict and should be unpacked one more level, or simply quoted as a string.

Christian

=================code=======================

proc dict_format {dict {dimension 1}} {
dictformat_rec $dict $dimension "" "\t"
}

## helper function - do the real work recursively
# use accumulator for indentation
proc dictformat_rec {dict dimension indent indentstring} {
# 1D is special
if {$dimension==1} {
return [dictformat1D $dict $indent]
}


# more than one dimension left
# unpack this dimension
dict for {key value} $dict {
lappend result "$indent[list $key]"
lappend result "$indent[list [dictformat_rec $value [expr
{$dimension-1}] "$indentstring$indent" $indentstring]]"
}

return [join $result "\n"]
}

## helper function for 1D
# insert newlines between keys
# prepend indentation
proc dictformat1D {dict indent} {
set result ""
set first true
dict for {key value} $dict {
append result "$indent[list $key] [list $value]\n"
}
return $result
}

Donal K. Fellows

unread,
Jul 13, 2011, 5:29:19 PM7/13/11
to
On Jul 13, 9:22 pm, Christian Gollwitzer <aurio...@gmx.de> wrote:
> I'd like to propose an alternate string representation for dicts.
[...]

No. :-)

In short, human readability wasn't a design goal. Interchangeability
with lists was.

> So, now its too late to change the standard string serialization of
> dicts, I would propose a "dict format" subcommand.

The [dict] command is an ensemble that you can modify (using the -map
option). Splice that subcommand in yourself. ;-) Also consider
rendering it as JSON; that's moderately readable.

Donal.

cattaghia

unread,
Jul 14, 2011, 8:43:20 AM7/14/11
to
Hi, Christian! I don't know if you have an immediate need on nested
dicts, or if you are just trying to propose an improvement to the
language, but you might be interested to know that I am just finishing
a simple visual editor for nested dicts and lists. I hope I can post
the code and tutorial in the Tclers Wiki until Sunday. I have been
experimenting with configuration and data files which are nothing more
than dicts saved to ASCII files with [puts], and the "bracing hell"
inspired me to create something on these lines...

Regards!

Fabricio Rocha
Brasilia, Brasil

Christian Gollwitzer

unread,
Jul 14, 2011, 1:20:27 PM7/14/11
to
Am 13.07.11 23:29, schrieb Donal K. Fellows:

> On Jul 13, 9:22 pm, Christian Gollwitzer<aurio...@gmx.de> wrote:
>> I'd like to propose an alternate string representation for dicts.
> [...]
>
> No. :-)
>
> In short, human readability wasn't a design goal. Interchangeability
> with lists was.

Point taken, but the proposed format is also compatible with lists - in
fact, it is the old format, but with tabs and newlines inserted such
that it looks nice. However, you are right that shimmering the value
from dict to list would change its serialization, which is bad.

>> So, now its too late to change the standard string serialization of
>> dicts, I would propose a "dict format" subcommand.
>
> The [dict] command is an ensemble that you can modify (using the -map
> option). Splice that subcommand in yourself. ;-) Also consider
> rendering it as JSON; that's moderately readable.

Challenge accepted; the below code produces:

------------------- dict creation snipped ------------------
(Programmieren) 144 % puts $m
key1 value1 key2 value2 key3 {nested value2 nested1 value1 nested2
value2 nested3 {value with spaces} nest1 {nest2 {value on 3rd level}
nest3 {value on 3rd level}}}
(Programmieren) 145 % dict format $m
key1 value1
key2 value2
key3
{
nested value2
nested1 value1
nested2 value2
nested3 {value with spaces}
nest1
{
nest2 {value on 3rd level}
nest3 {value on 3rd level}

}

}

(Programmieren) 146 % dict get [dict format $m] key3 nest1 nest2
value on 3rd level
(Programmieren) 147 %

I have tested this formatter with binary data both as a key and as a
value, no problems so far, I could successfully store a PNG image in the
formatted dict and retrieve it.
JSON is another option, but is more strongly typed than dicts, so I
prefer to stay with dicts.

Christian

=============code=============================
namespace eval DictUnsupported {
package require Tcl 8.6
#########################
## dict format dict
#
# convert dictionary value dict into string
# hereby insert newlines and spaces to make
# a nicely formatted ascii output
# The output is a valid dict and can be read/used
# just like the original dict
#############################

proc dict_format {dict} {
dictformat_rec $dict "" "\t"
}

proc isdict {v} {
string match "value is a dict *"
[::tcl::unsupported::representation $v]
}

## helper function - do the real work recursively
# use accumulator for indentation

proc dictformat_rec {dict indent indentstring} {


# unpack this dimension
dict for {key value} $dict {

if {[isdict $value]} {
append result "$indent[list $key]\n$indent\{\n"
append result "[dictformat_rec $value "$indentstring$indent"
$indentstring]\n"
append result "$indent\}\n"
} else {


append result "$indent[list $key] [list $value]\n"
}
}

return $result
}


namespace ensemble configure dict -map \
[linsert [namespace ensemble configure dict -map] end format
[namespace current]::dict_format]

}

Christian Gollwitzer

unread,
Jul 14, 2011, 1:27:38 PM7/14/11
to
Hello cattaghia,

Am 14.07.11 14:43, schrieb cattaghia:


> Hi, Christian! I don't know if you have an immediate need on nested
> dicts, or if you are just trying to propose an improvement to the
> language, but you might be interested to know that I am just finishing
> a simple visual editor for nested dicts and lists.

my use case is a storage file format. I serialize my internal objects
(larger program) into nested dicts (might be 3-4 levels deep, 2 levels
guaranteed), and dump the dict to a file, to be read back later. For
debugging purposes, it would be nice to have a human readable version of
that file. The main problem is, where does the knowledge of the
structure of the dict come from? Using unsupported::representation
works, but seems too brittle (See my other response to Donal). Currently
I have restricted the depth to 2 levels, which are guaranteed. So yes,
my current problem is considered "solved".
In any case it would be nice to have a visual tool.

Christian

cattaghia

unread,
Jul 16, 2011, 12:03:17 PM7/16/11
to
Hello, Christian and Tclers! The editor is there: http://wiki.tcl.tk/28552
. There are also some basic instructions. You'll also have copy to a
file the code of the valuepanel megawidget at http://wiki.tcl.tk/28551
. I'd be glad if you'd want to test it with your data files and give
some feedback.

Regards!

Fabricio Rocha
Brasilia, Brasil


On Jul 14, 2:27 pm, Christian Gollwitzer <aurio...@gmx.de> wrote:
> Hello cattaghia,

0 new messages