Version 14 of tcl9var

Updated 2007-02-22 11:59:44

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?)

 }

LES By calling it tcl9var, the summary rather becomes scaring the bejesus out of Tcl users who hope this will never replace set in new versions of Tcl.


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)


MJ - Note that this is very similar to the slot concept in Self. The Self extensions uses slots for both methods and values.


see also Getting rid of the value/command dichotomy for Tcl 9


Category Suggestions | Category Concept