Type checking

Richard Suchenwirth 2002-11-15 - Tcl is mostly very relaxed about types (everything is a string), while other languages can spend much labor just on such classifications. Only where needed do value types matter - e.g. list functions don't accept any arbitrary string, incr wants a variable with integer value, etc.

However, if you wish you can introduce type declarations that restrict the values being assigned to a variable, via write traces. They just do a harmless operation that would raise an error if the argument is not of specified type. As Tcl's error messages are so so clear mostly, I don't bother to catch them and raise my own instead, which makes these code snippets very simple:

proc integer args {
    foreach arg $args {
        uplevel 1 "trace add variable $arg write {incr $arg 0 ;#}"
    }
}
% integer i
% set i x
can't set "i": expected integer but got "x"

proc List args {
    foreach arg $args {
        uplevel 1 "trace add variable $arg write {llength \[set $arg\] ;#}"
    }
}
% List foo
% set foo {bar "grill}
can't set "foo": unmatched open quote in list

proc number args {
    foreach arg $args {
        uplevel 1 "trace add variable $arg write {expr 0+$$arg ;#}"
    }
}
% number p
% set p 5
5
% set p 5.4
5.4
% set p hello
can't set "p": syntax error in expression "0+hello": variable references require preceding $

This error message isn't as clear as the others - maybe one should catch it and replace with a clearer. But the smallness of the traces would get lost in this process...


JCG: The Simple Library uses that mechanism on steroids, so that the error message is pretty explanatory:

% ::Simple::Variable::configure -monitortype true
1
% ::Simple::Variable::create ::foo -type integer
% set ::foo 23
23
% set ::foo kk
can't set "::foo": invalid value "kk" for variable "::foo" of type "integer"

See also