Prev: Is there a IPTC and/or XMP tcl package (scripted or binary) out in the wild?
Next: How to profile a Tcl/Tk extension?
From: MartinLemburg on 14 Jan 2010 09:50 Hi, I know ... 1000s of times it is said ... don't care, while scripting in tcl, about the internal type of the data you are working with. But ... I care, because handling bigger structured data (dicts with nesting dicts, lists (containing dicts, ...), ...) it is not that nice, if shimmering occurs. And if producing e.g. a report of a complex, high precision calculation and its parameters and suddenly all the numerical data lost its numerical representation? For me a "Ooh NOO". So what's about this: % info patchlevel 8.6b1.1 % proc objtype {arg} {return [string map {"pure" "string"} [lindex [split [::tcl::unsupported::representation $arg]] 3]];} % set d [dict create a 1 b 2 c 3] a 1 b 2 c 3 % set d2 $d a 1 b 2 c 3 % set l [lrepeat 3 $d] {a 1 b 2 c 3} {a 1 b 2 c 3} {a 1 b 2 c 3} % objtype $d dict % objtype $d2 dict % objtype $l list % objtype [lindex $l 0] dict % format {%30s} $d; # expecting that the string representation of d will be formatted, ... a 1 b 2 c 3 % objtype $d; # ... but the data itself is converted to a string for formatting string % objtype $d2; # even the connection from d to d2 was not cut, while converting to a string string % objtype [lindex $l 0]; # even the values in the list are not "duplicated" to save their internal type string % set d [dict create {*}$d] a 1 b 2 c 3 % objtype $d dict % objtype $d2; # wow, the connection from d to d2 still existed while expanding d list So, why "format" converts the data to be formatted instead of using the string representation? Using "format" I never expected that the data I want to format will shimmer! I expected the result to be a string, not the format argument to be converted to a string. So I really recommend not to use format on numbers directly for output purposes, that shouldn't loose their internal representation and "exactness": % set r [expr {double(1)}] 1.0 % objtype $r double % format %s $r; # expecting the number not to convert to a string, but to format it to a string 1.0 % objtype $r string % set r [expr {double(1)}] 1.0 % format %s [expr {$r}] 1.0 % objtype $r double And I wouldn't like to loose the dict representation while doing something like the following: % set fontSpec [font configure TkDefaultFont]; # returns a list of options -family Tahoma -size 8 -weight normal -slant roman -underline 0 - overstrike 0 % dict set fontSpec -size 12; # converting the options list to a dict -family Tahoma -size 12 -weight normal -slant roman -underline 0 - overstrike 0 % font create TkFont12Pt {*}$f; # implicitly converting the dict to a list again TkFont12Pt What kind of pitfalls are hidden in tcl, that causes shimmering in unexpected cases? And ... a good news: % set l [list 1 2 3] 1 2 3 % set arr($l) [list A B C]; # using a list as name of an array element (a variable name), ... A B C % objtype $l; # ... does not convert the list to a "parsedVarName" list % set $l $arr($l); # while using the list as name of a scalar variable, ... A B C % objtype $l; # ... shimmers the list to a "parsedVarName" parsedVarName The only conclusion from this confusion for me is - really try to forget about the internal representation, concentrate on the EIAS rule and hope, that my tcl application does not consume to much time in restructuring "structured" data or destroys too much calculation precision. Greetings, Martin
From: Andreas Leitgeb on 14 Jan 2010 09:55 MartinLemburg(a)Siemens-PLM <martin.lemburg.siemens-plm(a)gmx.net> wrote: > % proc objtype {arg} {return [string map {"pure" "string"} [lindex > [split [::tcl::unsupported::representation $arg]] 3]];} Why that string map??
From: Andreas Leitgeb on 14 Jan 2010 10:12 MartinLemburg(a)Siemens-PLM <martin.lemburg.siemens-plm(a)gmx.net> wrote: > % format {%30s} $d; # expecting that the string representation of d will be formatted, ... > a 1 b 2 c 3 > % objtype $d; # ... but the data itself is converted to a string for formatting > string The problem with format lies in the %s "conversion". It's not really a conversion *to string*, but rather formatting "of a string". That is, it expects a string argument and will make whatever it gets into one. Unfortunately, I don't know any way to tell tcl to generate a string for some (arbitrary) object without adding the string rep to the obj. Well, The problem would not show up with numbers directly formatted to string with e.g. a "%f" conversion: % set d [expr {atan(1)*4}] ;# -> 3.141592653589793 % objtype $d ;# -> double % format %f $d ;# -> 3.141593 % objtype $d ;# (still) double But then again, there must be some way, because printing out the results of the assignments to d,d1,l in your original example didn't immediately turn them into strings. PS: my question about the mapping in objtype wasn't really relevant to the problem, but I'm still curious.
From: MartinLemburg on 14 Jan 2010 11:04 Hi Andreas, the mapping is only "useful", because for strings "::tcl::unsupported::representation" returns "pure string", so that the 3rd word of the result string is "pure", not "string". The other internal object types seems to be "one worded". That's all! Greet's, Martin On 14 Jan., 15:55, Andreas Leitgeb <a...(a)gamma.logic.tuwien.ac.at> wrote: > MartinLemburg(a)Siemens-PLM <martin.lemburg.siemens-...(a)gmx.net> wrote: > > % proc objtype {arg} {return [string map {"pure" "string"} [lindex > > [split [::tcl::unsupported::representation $arg]] 3]];} > > Why that string map??
From: MartinLemburg on 14 Jan 2010 11:14
Hi Andreas, so "format {%s} ..." causes the generation of a string representation, where none is found, and replaces the original internal object representation by the new generated string representation? % interp alias {} rep {} ::tcl::unsupported::representation % set n [expr {3.0}] 3.0 % rep $n value is a double with a refcount of 2, object pointer at 00DCCAE8, internal representation 00000000:40080000, string representation "3.0". % format {%s} $n 3.0 % rep $n value is a string with a refcount of 2, object pointer at 00DCCAE8, internal representation 00D8C0B8:40080000, string representation "3.0". Even if "format {%s} ..." formats "of a string", it may take the, probably new generated, string representation, but should not need to destroy the objects internal representation! If every data in tcl, no matter how it is internally represented, has a string representation - and may it be built dynamically - than no tcl command should have the need to throw away the internal represetation, because it excepts only strings as input. Every tcl data has its string representation as input for every tcl command expecting strings. I always thought this could be one way of EIAS. Greet's Martin On 14 Jan., 16:12, Andreas Leitgeb <a...(a)gamma.logic.tuwien.ac.at> wrote: > MartinLemburg(a)Siemens-PLM <martin.lemburg.siemens-...(a)gmx.net> wrote: > > % format {%30s} $d; # expecting that the string representation of d will be formatted, ... > > a 1 b 2 c 3 > > % objtype $d; # ... but the data itself is converted to a string for formatting > > string > > The problem with format lies in the %s "conversion". It's not really a > conversion *to string*, but rather formatting "of a string". That is, it > expects a string argument and will make whatever it gets into one. > > Unfortunately, I don't know any way to tell tcl to generate a string > for some (arbitrary) object without adding the string rep to the obj. > > Well, The problem would not show up with numbers directly formatted to > string with e.g. a "%f" conversion: > % set d [expr {atan(1)*4}] ;# -> 3.141592653589793 > % objtype $d ;# -> double > % format %f $d ;# -> 3.141593 > % objtype $d ;# (still) double > > But then again, there must be some way, because printing out the results > of the assignments to d,d1,l in your original example didn't immediately > turn them into strings. > > PS: my question about the mapping in objtype wasn't really relevant to > the problem, but I'm still curious. |