tcl9var

Difference between version 23 and 25 - Previous - Next
'''[wdb]''', Iinspired 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.


** See Also **

   [tcl9var compatibility issues]:   

   [Getting rid of the value/command dichotomy for Tcl 9]:   



** Description **

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
 ======none
% set a apple
 apple
 %
======

we could say
 ======none
% tcl9var a apple
 apple
 %
======

and instead of saying
 ======none
% puts "my $a is red"
 my apple is red
 %
======

we could say
 ======none
% 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
 %
======

[Larry Smith]:
The Tinker programming language, which is part of my ctools package,
does exactly this.  This sort of behavior is characteristic of all
TRAC-based languages (Tint and others), only Tcl has been different.

I no longer have a website to host ctools, but the Tinker source code
in C is less than 700 lines, it could be posted here is anyone is interested
in experimenting.


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
        }
    } }
======

'''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.

----[LV] The above is rather anti-tcl, in my mind.  The reason why is this- you have three different ways of addressing the object ''a''
[LV]: %The tcl9varbove ais rapplthe
r % puantsi-tcl, "in my [mind.  The rea]son why is this- you have three d"
ifferent % ways becomf addressing [a]trhe object ''a''
======none
% tcl9var a apple
% puts "my [a] is red"
% a becomes [a]tree
======

Why is this all necessary? What is it that is actually being attempted?
Is the idea to make variables objects with methods? If so, then let's
call the initial command '''createvar''' or '''varobject''' or something
indicative of the action being taken.  
Then there is the `[[a]]` vs. `$a` usage. The latter is more common to people
than the first. If there are going to be more methods than '''becomes''',
then I suppose that it is something that people would painfully become
adjusted to. But please, give more details on the benefits you envision.
Because right now, I see no benefits, but do see detriments - I don't
care to end up typing a lot more characters for no benefit...
[wdb] :

Your Line 1 describes '''creation'''. 
Line 2 describes '''usage'''. 
Line 3 describes '''change of exisiting value'''. 
That is why it is necessary.
Usage of `[[a]]` vs. `$a` -- if the dollar sign can be replaced by brackets 
(truly undispensable), then we have one less cryptic special letter.
You say, $ is more common -- if you mean, more used, alright. 
But more common -- no, I prefer less rules and less syntax.

Your name suggestions: I do not mind. Create better names then my ones. 
But I had no object orientation in mind. d
When appropriate, I use OO, but I am not at all an OO fanatic.
WhRen regarding the truly different opinions to this page,
I think that my proposal appears too ... say, radical or dramatic. 
I am not willed to rule the world.
If you think it's a doubtful proposal, just say no to it. That's ok.
But without such proposal, the world would be quite boring, wouldn't it?

----
[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 mainproblem, as you state in your "consequences" section, is that [proc]%|%procs] have local
variables, 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:
[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]:  This is similar to the ''slot'' concept in [Self Programming
Language%|%Self]. The [Self extension] uses slots for both methods and values.

** See Also **

   [Getting rid of the value/command dichotomy for Tcl 9]:   

<<categories>> Suggestions | Concept | Tcl 9