Expanding the Expansion prefix - Concept of protocol

This page is to complete the reflexion about a generalization of the braced-prefix syntax.

While existing before, but differently, in cloverfield project, this idea came through some references pages :

In these pages, we saw that this syntax could help in defining new possibilities at many levels.

  • In the parser step, it could help, for instance, to define inline commentaries.
  • For variables, it could help to define their type.
  • For commands, it could help to « tag » the words they recieve, what can be usefull to modulate their algorithm.

Protocol analogy

Protocol come for the ancient greek word « πρωτόκολλον », protókollon, composed of πρῶτος, prỗtos (« first ») et de κόλλα, kólla (« glue »).

Think about how we send a letter : We put the message into an envelope, on which you can glue a label to indicate its correct destination, and eventually other informations (ask for aknowledgment,..etc)

Then we can make this analogy : If a Tcl_Obj is taken like the envelope of a message (which is its value), we can take any « braced-prefix », puts in front of it, like a label glued on top of the envelope : From this point of view, a braced-prefix appear to be, literally, a protocol.

For instance :

  • The {*} expansion prefix is a protocol that indicate the Tcl-Parser to act in a certain manner with what follows it.
  • The type of a variable is like a protocol which indicate how to use a variable : that justifies it could be interesting to use some braced-prefixes to indicate the type of a variable.
  • A command may use its arguments in many ways : It could be convenient to use protocols as algorithm modulators.

Usage of the analogy

Protocol as type of variable

I have expansively explorated the braced-prefix concept seen as variable type in the above related pages.

Protocol as modulation of algorithm - example of the proc command

Now, let's discuss about the other usage of it, as modulation of handling command argument, with an important example.

The one that came into my mind concerns the « proc » command.

The proc command takes 3 arguments : Name, Argument, Body.

Modulating how proc handles its arguments

It exists some TIP to introduce distinct ways of interpreting proc arguments.

Some work has been done to adress these needs. Discussions and works on this subject can be found in these pages :

The problem is that the proc interface is expansively used. Any change in it could drive Tcl in big problems. Many strategies has been imagined. Either create new variants of proc command, either create a command to be called inside the proc. In fact, people just want to modulate the way proc can handle its arguments, but without changing too much its interface.

A very refine way to specify arguments has the drawback that it will complicate it too much for the basic case. Creating new variants of the proc command would increase the number of basic Tcl command to learn.

As the goal is only to modulate the arguments evaluation strategy, it is natural to introduce here the concept of protocol. What protocol should follow the proc command to evaluate its arguments ? As we saw, a braced-prefix, that is a syntax backward-compatible construct, can be thought like a protocol, it seems natural to me that some braced-prefixes could be usefull here. The proc interface could be set as following :

proc name_of_proc {argProtocol}args body

Of course, by default, if no argProtocol braced-prefix is present, the arguments of proc will have to be taken as positionnal, as usual. But if we could define at script-level some additional argProtocol, this could make the job. For example :

protocol config proc args named parse_args
proc MyProc {named}args body

Modulating how proc handle its body

Moreover, it exists on the wiki some variants of proc, whose goal is to change the way the body is compiled. For instance there is :

  • vproc in vecTcl that expect a body written in a mathematical syntax.
  • cproc in Critcl that expect a body written in C.

To say, many ways are possible in the interpretation of a proc body. That could justify the introduction of specific protocols, by braced-prefixes, on the body argument.

If this could be configured at the script level, for instance like :

protocol config proc body = vecTcl::vproc

proc mean array {=}{
   # a VecTcl procedure to compute the mean of a vector possibly having NaN elements
   isNumber = array == array
   length = shape(isNumber)
   j = 0
   for i=0:length-1 {
      if (isNumber[i] == 1) {j = j + array[i]}
   }
   if (j == 0) {
      j
   } else {
      j/sum(isNumber)
   }
}

mean {1 2 3 NaN 5 NaN}

This would allow a whole new kinds of opportunities, like import the body of any procedure or function from any language that Tcl is bridgeable to.

Enforcing the proc return type

Finally, I noticed some demands about getting the possibility to configure the return type of a procedure, to be able to make some optimisations on the fly in the compilation step of the code. This could be set by a braced-prefix put in front of the proc name, it will indicate the protocol to follow to check its return value.

A new proc interface, backward-compatible

At the end, it appears that every arguments of the proc command could be « brace-prefixed ». The interface of the proc command then would be changed like this :

proc {returnType}myProc {argProtocol}myArgs {bodyProtocol}myBody

Whereas this proc command would be backwards-compatible, we could introduced an infintiy of new ways to use it :

  • We could enforced its return type.
  • We could have many manners to configure its calling interface, by modulating its argument handling.
  • We could have many manners to configure its compilation. « Mathematical syntax », « C », « Rust », « Python », « javascript » ... allmost any language where it exists a bridge with Tcl could be used.

Of course, a new chapter would have to be introduced in the documentation, concerning protocols.

Synthesis

Here is a table to summerize the usage of prefix protocols.

Command type arg objc meaning of the prefixexemple command of implementation
name of the current command only 0th namespace {string}append S "hello" in tcl_Eval
expect a new command name to be created * return type proc {int}add {x y} {expr {$x+$y} proc, apply, oo::method, coroutine, ...etc
expect variable * type of var set {list}L e0 e1 e2 e3 set, append, lappend,...etc and also before '$' in Tcl_parser
expect argument * argument parser proc name {named}args {} proc, apply, oo::method, coroutine, ...etc
expect script * script compiler proc add {i j} {c}{i+j} proc, apply, oo::method, coroutine, ...etc ? also before [...] in Tcl_parser ?
expect value * meta information set Radius {mm}6 anywhere


gold 01/19/2026. Added categories, so can find message in Wiki. Original author appears to be FM from history log.



Could this changes be usefull ? Do you think any other command take can advantage of the braced-prefixation concept seen as protocol to modulate their algorithm ?

Examples

Idea of argument parsing protocol

Reference of analysis : parse_args

An idea can be to use prefixes to denote the type of arguments. These prefixes can be nested and also can receive parameters (a comma-separated list of value between parenthesis)

1) The argument object array can be parsed from left to right, or from right to left. Let's denote this by {>} or {<}. This give us the names of two argument parsing protocols :

protocol config proc args > {...}
protocol config proc args < {...}
proc MyProcLR {>}{} {}
proc MyProcRL {<}{} {}

2) There may be some commentary. Let's denote it with a {#} prefix.

proc MyProcLR {>}{
{#}My\ commentary
} {}

3) Some arguments are optional, wheras other are mandatory. Let's use {?} prefix for optional argument, and {!} prefix for mandatory arguments.

proc MyProcLR {>}{
{!}widget
{?}option
} {}

4) Some arguments are flags that expect a value (ie : name argument), while others doesn't expect it (ie boolean flag). Let's denote the fact that we expect a value after this flag by a {@} prefix. {@} wil denote a named argument.

5) Generally, an option name is taken as the variable name, preceded by a minus char "-". As it would be a waste of char to write something like :

{{?}@(-optionName)}optionName

so lets define a prefix whose meaning is "prepend the variable name with a minus to get the option name". There is four cases :

# optional named argument.
{{{?}@}-}optionName
# mandotary named argument.
{{{!}@}-}optionName
# optional boolean flag
{{?}-}optionName
# mandotary boolean flag.
{{!}-}optionName

7) Sometimes many flags refer to one only variable, like, for instance, in defining the lsort modality of comparison. Then, option names and variable names can't be deduced form each other. No, each flag will then indicate a possible value for the variable. Let's denote this by recurring with some parameters added to the {-} prefix.

{#}{4 option flags, 4 possible values for 1 variable}
{{?}-(ascii,dictionnary,integer,real)}compare_as

The meaning of the {-(o1,o2,o3)} is then : look for these options transmited by your parameters, prepending them with a minus char. If you find it, set the option name (without the minus char) as value to the variable which is prefixed. By default, if there is no parameters, take the variable as a boolean value. Above, the variable compare_as can take four values.

8)a° Eventually, the variable could be validated : that justify to introduce a typing on the variable argument. Let's suppose we have an url type value define somewhere in the interpreter.

proc glob {>}{
{#}{optional -directory option : check the url validity and set its value to the directory varname}
{{{{?}@}-}url}directory
...
} $body

8)b° Eventually, the validation of the value could be passed in parameters to the type. Think about a string type enum.

proc entry {>}{
....
{#}{optional "-state" option is to indicate the 3 states of the entry. The value must be either "normal", "disable" or "readonly"}
{{{{?}@}-}string(normal,disable,readonly)}state
...
} $body

9) upvar : Let's denote it by a {&} prefix

proc entry {>}{
{#}{optional option -textvariable : introduce the name of a variable whose value is to be the image of the entry content}
{{{{?}@}-}&}textvariable
} $body

10) The default value : it can be as usual, the second element in the list.

proc entry {>}{
{#}{optional -width option : width of the widget}
    {{{{?}@}-}int}width\ 0
}

11) As there is two much braces, and reasonnably few composition possibilities, let's act a princip of "contraction" of the prefixes that are nested in simple words. It's just about creating new prefixes that are the composition of other For instance :

  • make {?-} equivalent to {{?}-}
  • make {?@-} equivalent to {{{?}@}-}
  • ...etc

Rewriting the examples we can find in parse_args , we get :

proc lsort {>}{
    {#}modality\ of\ comparaison
    {?-(ascii,dictionnary,integer,real)}compare_as\ ascii
    {#}a\ command
    {?@-}command
    {#}order\ of\ sorting
    {?-(increasing,decreasing)}order\ increasing
    {?@-}indices
    {?@-}index
    {?@-}stride
    {?-}nocase\ 0
    {?-}unique\ 0
    {!}list
} $body

proc glob {>}{
    {{?@-}url}directory
    {?-}join
    {?-}nocomplain
    {{?@-}url}path
    {?-}tail
    {{?@-}list}types
    {?-}-\ 0
    {!}pattern
} $body

proc regexp {>}{
    {?-}about
    {?-}expanded
    {?-}indices
    {?-}line
    {?-}linestop
    {?-}nocase
    {?-}all
    {?-}inline
    {?-}start
    {?-}-\ 0
    {!}regexp
    {!}string
    {?}matchvar
    {args}submatchvar
} $body

proc using_parse_args {>}{
    {!@-}title
    {?@-}{category {}}
    {!@-}wiki
    {?@-}rating
} $body

proc entry {>}{
    {!}widget
    {?@-}disabledbackground\ {}
    {?@-}disabledforeground\ {}
    {?@-}invalidcommand\ {}
    {?@-}readonlybackground\ {}
    {{?@-}char}show
    {{?@-}string(normal,disable,readonly)}state\ normal
    {{?@-}string(focus,focusin, focusout, key, all)}validate\ none
    {?@-}validatecommand
    {{?@-}int}width\ 0
    {{?@-}&}textvariable
} $body

Synthesis

Here a table to summerize this proposal of a prefix protocol to parse command arguments

argument prefix meaning of the prefix
{!}varname\ defaultValue mandatory positionnal argument
{!@-}varname\ defaultValue mandatory named argument
{!@-(mode1,mode2,mode3)}varname\ defaultValue enumeration of exclusive mandatory boolean arguments
{?}varname\ defaultValue optional positional argument
{?-}varname\ defaultValue optional boolean argument
{?@-}varname\ defaultValue optional named argument
{?@-(mode1,mode2,mode3)}varname\ defaultValue enumeration of exclusive optional boolean arguments
{&}varname\ defaultValue uplevel variable name
{&(::namespace)}varname\ defaultValue namespace uplevel variable name
{&(2)}varname\ defaultValue uplevel 2 variable name
{#}comment commented argument