Version 3 of pure value

Updated 2016-05-07 14:42:33 by pooryorick

A pure value is a value for which no string representation has yet been generated.

Description

In Tcl, every value is a string, but for efficiency, Tcl only generates those strings as needed. Take, for example,

set a [expr {2 ** 4}]

Here, $a has been given a value that was created in a numeric context, and the value of $a has not actually been used yet, so there has been no reason so far for Tcl to go ahead and generate a string representation of the number 16. Even when $a is passed to another command, there may still be no need to generate the string representation:

lappend list $a

Tcl is perfectly capable of appending $a to a list without looking to see what the string representation of $a might be, so after lappend, $a is still pure. It has no string representation. Since the value of $a came from a numeric context, and Tcl internally cached a numeric representation of $a, it can be passed back into a numeric context, and used efficiently, and still, no string representation is generated:

set b [expr {$a ** 2}]

At this point, neither $a or $b have a string representation. This can be verified with ::tcl::unsupported::representation:

puts [::tcl::unsupported::representation $a]
 value is a int with a refcount of 3, object pointer at 0x600064550, internal representation 0x10:0x600064580, no string representation

At some point, Tcl may decide it needs a string representation of the value. One such point is when the value is used as the key in a dictionary:

dict set dict $a something
puts [::tcl::unsupported::representation $a]
 value is a int with a refcount of 4, object pointer at 0x600064550, internal representation 0x10:0x600064580, string representation "16"

Tcl is a scripting language, after all, so usually it's not necessary to worry about exactly what internal or string representations Tcl has generated for a value, but sometimes it can make a big difference, typically when working with a large list or dictionary.

Making Sure a Value Isn't the Empty String

PYK 2016-05-06: In many contexts, the empty string serves as a special out-of-range value. For example, for an optional argument to a procedure, the empty string is often used as the default value to indicate that no argument was provided. Currently, there is no general way, without causing the string representation of a pure value to be generated, to check that the value is not the empty string. Perhaps the Tcl C API could declare that any Tcl_Obj that has an internal representation must not have the empty string as its string representation, and then proceed to optimize the implementation to keep pure values pure.

In the meantime, to clasify a value which might be numeric or the empty string, without generating a string representation:

expr {$i < -Inf}

or

expr {[string is integer $i] && ![string is integer -strict $i]}

See Also

pure list
pure numbers
Tcl Performance
A guide to this and other such Tcl performance tips.