Version 6 of DISCUSSION: Argument Expansion Syntax

Updated 2003-07-28 22:30:49

Note that

 eval exec $program $args

is not an adequate substitute for

   eval [linsert $args 0 exec $program]

or

  exec $program {}$args

since it breaks when $program contains spaces.

Option 4: leading @: Larry Smith If you favor a leading character then "@" is easy to see and read, much more so than `.

Option 4: $(<whatever you want expanded>): Larry Smith Personally, I prefer marking a particular string or set of strings for an additional parsing/substitution pass using something that is reminicent of the current syntax. $([cmd]) or $([cmd1] [cmd2]) marks things clearly as being expanded. After all, it is the $ that signifies substitution, not the {}.

  • $([cmd]) is already legal syntax within variable substituition and shouldn't be mixed up with expansion.

Jacob Levy July 28, 2003: What the example above tries to achieve seems to be possible without any new syntax, using a procedure called apply, which behaves as follows:

 set l {a b c d e}
 apply list $l $l
 ==> {a b c d e a b c d e}

The definition of apply is that its first argument is a function that is applied to rest of the arguments which are evaluated and their values are collected into a list.

The definition of apply is probably something like:

 proc apply {fn args} {
     set l ""
     foreach a $args {
         set l [lconcat $l $a]
     }
     return [eval $fn $l]
 }

 proc lconcat {pre el} {
     set l $pre
     foreach e $el {lappend l $e}
     return $l
 }

Now there may be more to TIP #144 that is not covered by this; however, at least for the given example, no new syntax is needed for implementing the functionality in Tcl.

DGP For this specific example, [apply] would be enough, yes.

When you extend things to get a command that can solve all of the problems addressed by the proposed syntax, you end up with the [expand] command proposed in TIP 103.

TIP 103 was considered and rejected.

Can we move on now please?

DGP For that matter, [apply] will not even work for the [exec] example above (when $program contains spaces).

Jacob Levy Fixed the $args handling, above. To handle $prog with spaces in it, you'd need to pass [list $prog] to the invocation of apply.

TP I like the apply option best. I would suggest that the apply command could have it's own mini-language (ala format, regexp, etc) using the {} or ` formatting. E.g.

   apply {somecommand {}$expand_this $but_not_this}

DGP The "special command with its own mini-language" approach was TIP 103.


KBK (2003-07-28) I know that I have code that will break with the backquote syntax.


Setok I know I probably bore people already with my ramblings on the caret expansion syntax but I find it pleasing. Note that expr does not allow double-carets (no logical XOR). So:

  file join ^^$FilePath

or

  exec $program ^^$args

The reason I find it nice is because it actually looks like the operation it is doing. It, to me, feels like real syntax instead of a hack.

The other option I suggested a couple of times was the ability for a command to affect its calling command line. This is somewhat akin to upvar and uplevel in how dangerous it can be, but allows macro-style functionality into Tcl. Other benefits are that no new syntax is added -- only a new capability provided to commands and procedures. I do realise it's somewhat complex.