if false {
wdb Inspired by If we had no variables, and some ideas found in Tcl 9.0 WishList, I have some day-dreams of getting rid of set, where instead of the procedure set the variable itself is a procedure.
instead of saying
% set a apple apple %
we could say
% tcl9var a apple apple %
and instead of saying
% puts "my $a is red" my apple is red %
we could say
% puts "my [a] is red" my apple is red %
and instead of changing the variable a by saying
% set a ${a}tree appletree %
we could say
% a becomes [a]tree appletree %
Here is a toy implementation of such behaviour:
} set persistentCounter 0 array set persistent {} proc tcl9var {name value} { variable persistentCounter variable persistent set persistent([incr persistentCounter]) $value uplevel 1 [subst { proc $name {{cmd get} args}\ {eval ::handleVar $persistentCounter \$cmd \$args} }] set persistent($persistentCounter) } proc handleVar {count cmd args} { variable persistent switch -exact -- $cmd { get { set persistent($count) } set - = - <- - becomes { eval set persistent($count) $args } append - lappend { eval $cmd persistent($count) $args } + - - - * - / - % - ** - < - <= - > - >= - == - != { expr "$persistent($count) $cmd $args" } default { eval $cmd $persistent($count) $args } } } if false {
Possibilities -- see source of proc handleVar above. Variables behave like objects.
Consequences -- closures must handle namespace of procedures instead of variables. Differs from current behaviour where procedures defined globally and procedures defined in current namespace are visible.
Incompatibilities with set -- variables and procedures use the same namespace, so it is not possible to give a var the name of an existing procedure. that's a pretty HUGE incompatibility!
Summary -- just a day-dream. (What's wrong with day-dreams? Who said, man will never fly?)
}
NEM Added a -exact to the switch, to avoid treating * etc as glob characters. Nicely done -- this is exactly the sort of thing I'd like to see. The main problem, as you state in your "consequences" section, is that procs have local vars, but not local commands. I think Lars H may have suggested proc-local commands at one point, and to my shame I think I thought they were a bad idea!
- RS From 8.5 we can have local procs, sort of:
proc f y { set square {x {expr {$x*$x}} apply $square $y }
The lambda named square is cleaned up on return But this way of using a variable to hold a lambda runs of course in the opposite direction of using procs to replace variables :^)
GN here is a small XOTcl implementation:
Class tcl9var tcl9var instproc init {{value ""}} {my set _ $value} tcl9var instproc defaultmethod {} {my set _} tcl9var instproc unknown {args} {my set _ $args} tcl9var a 123 puts [a] puts [a 4711] puts my-[a]-value puts my-[a 1 2 3]-value
depending on the type of the variable, different methods can be provided (e.g. for lists, numbers, whatever)
Category Suggestions | Category Concept | Getting rid of the value/command dichotomy for Tcl 9