From: MartinLemburg on
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
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
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
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
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.