The creation of {*} expansion prefix brought clarity to Tcl.
There is still space in the parser for this kind of annotations. But how can it be usefull for programmers ?
Let's suppose that we add a new rule to Tcl :
These generic annotations should be recognized by the parser and result in immediate actions from it.
These annotations should be recognized by the parser, and result in an annotation token, whose prefixed word is a subsequent component. The future substitution of this kind of Token will result in the object of suffix word linked to the annotation object.
As their effect will be specific to the command that recieved them, we can't gives generic rules on their effect. But we can distinguish some appetitive features for the main Tcl entity :
set {Person}P ... {#}{P is a person}
the SetObjCmd proc will recieved an annoted object as 1st argument. But what will it do with it ?
There should be somewhere a previous definition of what is a person :
define Person { {string}LastName {string}FirstName {index}id }
The SetObjCmd will look at the definition of Person and see that this specific type defines some fields :
Let's say the index type denotes an auto-incremented integer
Now the SetObjCmd knows, that, along the definition of this this type, the variable contains two fields, so he knows what to do with this variable. We can write :
set {Personne}P {LastName}OUSTERHOUT {FirstName}John
The annotation of the objects arguments give the name of the field, with the help of a function : Tcl_GetAnnotationFromObj()
For generic types, we would write directly :
set {list}L 1 2 3 4 5 6 {#}{it's a list !} set {dict}D k1 v1 k2 v2 {#}{it's a dict !}
I would like also to be allowed to "compose" type annotations. For instance, i'd like to specify list of lists or list of dicts or dict of lists or dict of dicts. Maybe it could be done in annotating the annotation.
set {{list}list}LL [list A B C] [list E F G] set {{dict}list}DL key1 [list A B C] key2 [list E F G] set {{list}dict}LD {dict}{k00 v00 k01 v01} {dict}{k10 v10 k11 v11} set {{dict}dict}DD k1 {dict}{k00 v00 k01 v01} k2 {dict}{k10 v10 k11 v11}
I would like also to constraint the length of the list, or to specify the keys of a dict.
define vect { {{list[3]}number}Vi } set {vect}V 1 2 3 define Personne { {dict[{string}Last,{string}First]}Name {dict[{dict[work,home]}mail, {dict[work,home]}tel]}Contact } set {Personne}P \ {Name}{ {Last}OUSTERHOUT {First}John } {Contact}{ {mail}{ {work}{[email protected]} {home}{[email protected]} } {tel}{ {work}{1232343} {home}{3676333} } }
let's define data of a Person P
set P {dict}{ Phone {dict}{Home 45644 Work 435841 Mobile 48344} Mail {dict}{Personal {list}{[email protected] [email protected]} work [email protected]} }
As there is no ambiguities on the type of the values, we can write :
set P(Phone(Home)) {#}{returns Home Phone number : 45644} set P(Mail(Personal(end))) {#}{returns the last element of Personal's Mail : [email protected]}
an arg prefix with an {&} annotation could be sean as a reference, aka :
proc SET {{&}var args} { set var $args } # Should be equivalent to : proc SET {varname args} { upvar #0 $varname var set var $args }
Let'say we have a team of n peoples
# Coming from a database set P1 {Person}{{Nom}{{Last}... {First}...} {Phone}{{Work}... {Home}...}} ... set Pi {Person}{{Nom}{{Last}... {First}...} {Phone}{{Work}... {Home}...}} ... set Pn {Person}{{Nom}{{Last}... {First}...} {Phone}{{Work}... {Home}...}} # We set a team of 3 members set M1 {&}$P1 set M2 {&}$P2 set M3 {&}$P3 set {list}Team {&}$M1 {&}$M2 {&}$M3 # If we want to change a member set M1 {&}$P4 # -> The list would be automatically updated (M1 now refer to P4) # We want to change the phone number of someone # Apply to someone a specified type of data set P4 {Person{Phone{Work}}}0543876787 set {Person{Phone{Work}}}[lindex $Team 0] {#}{return the new work phone number}
Linked list
define node { {string}Name {node}next {node}previous } set {node}n0 {Name}{First Node} set {node}n1 {Name}{Second Node} set {node}n2 {Name}{Third Node} set {node}n0(next) {&}$n1 set {node}n1(next) {&}$n2 set {node}n2(next) {&}$n0 set {node}n1(previous) {&}$n0 set {node}n2(previous) {&}$n1 set {node}n0(previous) {&}$n2
...writing in progress...
Comments Welcome