Version 14 of Pure numbers

Updated 2006-01-07 08:15:08

FW: A "pure number" (compare pure list) is a number with no string representation in memory (though of course it can be manipulated as a string - and as soon as it is, it gains a string form).

Any integer value computed by the Tcl interpreter rather than provided by the user will be in pure integer form. The easy way to attain this is taking a numeric variable (let's call it x) and performing an incr x 0, which will cause Tcl to compute the value of $x plus zero (which is hopefully just $x), and since the result is a number computed by Tcl, there's no need for a string form.

The need for this is relatively rare, though, since invoking expr to perform any calculation on a value will also do this (as long as you do actually perform some operation - if it's just expr {$x} that wouldn't cause Tcl to calculate anything, so it would just return the original value of $x intact). The only time I could think of when doing this would be handy is when one is using a large number of numbers (as in a list), without necessarily changing their value, and wants to save memory.

Donal Fellows (whose explanations were mighty helpful in the creation of this page) points out, however, that if you take into account Tcl_Obj overhead, the most a string representation could add - for an integer, at least - is a 2x gain in memory profile.


DKF - Note that there's not much point in worrying whether a number is pure in Tcl or not. Just use the things. Where you can gain is when you are storing loads of instances of the same value (e.g. a list of zeros, ones and twos) and the way in which you can gain there is by using the same '0', '1' or '2' for each list member, instead of packing in the value you computed. Perhaps like this:

  # Version that uses *lots* of memory
  set mainlist {}
  for {set i 0} {$i<1000000} {incr i} {
     lappend mainlist [expr {$i%3}]
  }

  # Version that uses much less...
  set cache {0 1 2}
  set mainlist {}
  for {set i 0} {$i<1000000} {incr i} {
     lappend mainlist [lindex $cache [expr {$i%3}]]
  }

Tcl uses tricks like this internally when you use [ binary split ] to try to minimise the number of objects generated...

Lars H: Those that worry about this kind of memory usage issues may want to take a look at (and possibly contribute to) the Compact Data Storage page.


RS 2004-09-22: Just today I learnt that Python has a pool of small integers (possibly 0..9) that are shared between uses. Would that be helpful in Tcl too? Those numbers are used most often, and using them might make dkf's above version 1 as efficient as version 2, without explicit caching...


RS As long as they don't get optimized out, here's two ways of producing a pure number, integer or float:

 expr {$x+0}
 expr {$x*1}