Typed Tcl

MJ 2016-08-18: After watching Christian Gollwitzer and dkf's talks on EuroTcl I was contemplating an idea for Tcl9. A big reason of Tcl's flexibility is brought by EIAS, however this is a double edged sword.

  • It's slow.
  • It makes intellisense like tools virtually impossible.

So how about a Typed Tcl where you can define and use Tcl_Objs with a specific internal representation and conversion functions to other intreps without passing to string.

You would need to declare the value as a typed value and as soon as you play the EIAS card, you will get an error unless you make the shimmer explicit.

This has a couple of benefits.

  • You wont break EIAS (it just needs to be explicit) so if you use a part of Tcl which is not type aware you need to pass toString $var instead of $var
  • You can go fast if you have a direct intrep_type_a to intrep_type_b function defined.

This approach is complementary to the approach of speeding up Tcl by code analysis. Sometimes I will just know when I don't need EIAS but I will just need speed instead.

DKF: The current diagram of what types we've found in the tclquadcode work is:

Yes, it's a bit complicated. No, not everything is a string, but most things are (the things which aren't don't appear as values you can manipulate and so can be ignored).

How could it look?

settyped a list {a b c d}
puts $a;                  # error, can't use a tped Tcl_Obj as a string
puts [toString $a];       # ok $a is now untyped
dict get $a c;            # error if there is no list->dict conversion
dict get [toString $a c]; # ok, EIAS

On second thought, this will require a library user to cast every returned value to an untyped Tcl value to prevent errors, so this seems to be similar to Java land Object.

FM Now I think about something like a tag on the TCL_token. Ex :

set a {list}{a b c d}; # definition of the variable "a" as a list
puts {string}$a;   # conversion of the "a" value as string, but var "a" remains a list
dict get {dict}$a; # conversion of the "a" value as dict, but var "a" remains a list

How to achieve this ? Maybe in the Tcl Parser, near where the expand {*} operator is checked ? The word could then be defined as a "TCL_TYPED_WORD"

This kind of "decoration" of tcl words could be used in a lot of places.

For instance :

  • if inserted before proc names, it could specify the type of the proc return value,
  • if before proc arguments, it could specify the type of the proc arguments.
proc {int}add {
   {int}a; #first int value
   {int}b; #second int value
} {
   expr {$a+$b}
}

There would be basic types : bool, int, float, number, string, binary, list, dict,...etc

We should also be able to define and compose new types. Ex :

define {dict}node {
   {node}parent key -p default {}
   {{node}list}children key -c default {}
   {number}weight key -w default 0
}

set {node}Tree {}

# node type should inherit methods of dict (since it's a kind of dict)

node create Branch0 -p $Tree -w 1
node create Branch1 -p $Tree -w 0.4
node create Branch2 -p $Tree -w 0.5

# complementary Idea for "dict" : let's grant individual acces to properties with '«' '»'
# Well, the parser needs to be aware of unicode...

set Tree«children» [list $Branch0 $Branch1 $Branch2]

node set leave00 -p Branch0 -w 0.5
node set leave01 -p Branch0 -w 0.7
node set leave02 -p Branch0 -w 1.2

set Branch0«children» [list $leave00 $leave01 $leave02]

node set leave10 -p Branch1 -w 0.8
node set leave11 -p Branch1 -w 0.5
node set leave12 -p Branch1 -w 0.6
set Branch1«children» [list $leave10 $leave11 $leave12]

node set leave20 -p Branch2 -w 0.9
node set leave21 -p Branch2 -w 0.4
node set leave22 -p Branch2 -w 0.7
set Branch2«children» [list $leave20 $leave21 $leave22]

# Now, let's define a proc to Sum the weight along the Tree :

proc {number}totalWeight {
    {node}tree
} {
    set Sum $tree«weight»
    foreach child in $tree«children» {
          set Sum [expr {$Sum+[totalWeight $child]}]
    }
    return $Sum
}

# print out the result as a string
puts {string}[totalWeight $Tree]

See Also

Every Word is a Constructor
More discussion of the same topic.