Special name for an argument to a [proc] or [lambda] term - if it's last in the argument list, it will contain a [list] (possibly empty) of all the remaining arguments. The use of a magical ''args'' parameter is common in many other procedure-like methods (e.g. those created by various OO extensions). ====== proc demo {first {second "none"} args} { puts "first = $first" puts "second = $second" puts "args = $args" } demo one demo one two demo one two three four five ====== results in: ====== first = one second = none args = first = one second = two args = first = one second = two args = three four five ====== ---- '''example args''' (using [XOTcl]) ====== Class Club -parameter {id {name unknown}} Class Player -superclass Club -parameter {{name unknown} {position unknown}} Player proc show_players args { if { [string length $args] == 0} { puts "Show players DB" foreach p [my info instances] { puts "[$p name] [$p position]" } return } set pos [string toupper $args] puts "Players with postition $pos:" foreach p [my info instances] { foreach char [split $pos {}] { if {[string first $char [$p position]] == 1} { puts "[$p name] [$p position]" break } } } } ====== ---- Is it just me, or is that a pretty poor example of args? You do [[string length $args]] and [[string toupper $args]] but you firmly established that args is a list, not a string. It is generally accepted as bad practice to perform string operations on lists. [LES] But, if [everything is a string], aren't lists strings too? On the other hand, there has been quite some debate on whether '''everything is a list''' rather than a string... [LV] I don't know that I would go so far as saying that it is ''bad practice to perform string operations on lists''. I would say that it is generally bad practice to perform list operations on variables known only to have strings. And I would say that '''some''' string operations on lists may result in results that , at first blush, one might not expect. [Lars H]: The problem with applying string operations on known [pure list]s like $args is basically [shimmering]. Applying a string operation will require generation of a string representation, and the cost for that (in memory and processing time) is often better avoided whenever possible. If you pass multi-megabyte lists around (something Tcl 8 handles beautifully well), you probably don't want to double the memory footprint by also generating their string representations. An extreme example: set val x for {set n 1} {$n<=64} {incr n} {set val [list $val $val]} puts "Tcl will get this far."; flush stdout string length $val puts "But it runs out of memory before it gets this far.!" [LV] So then the example isn't a poor example of args - but a poor example of good performance. ---- [MG] offers a quick example off the top of his head (and therefore untested), on his way through... ====== proc randomCmd {args} { set error {wrong # args: should be "randomCmd ?-arg value ...? string"} set num [llength $args] if { $num == "0" || ($num%2) == 0 } { error $error; } array set opts [list -width 5 -height 5 -fg [list] -bg [list] -foreground blue -background red] if { $num > 1 } { foreach {x y} [lrange $args 0 end-1] { if { ![info exists opts($x)] } { error "unknown option \"$x\""; } set opts($x) $y } } foreach {x y} [list -fg -foreground -bg -background] { if { [llength $opts($x)] > 0 } { set opts($y) $opts($x) } unset opts($x) } echo "String is \"[lindex $args end]\". Apply these options: [array get opts]" } ====== ---- [LV] Here's where I am trying to use args - maybe someone has a suggestion. My code is this: % proc d {name args} { puts "DEBUG: $name: $args" } % d mainline "this is the first spot in the mainline" DEBUG: mainline: {this is the first spot in the mainline} That is to say, it is intended as a place to control debug statements. I can just return rather than do the puts, to turn off the debugging. HOWEVER, the debugging output looks peculiar. Not a problem - it is just for debugging. But if I were going to use this for something else, I wouldn't want the extra {} in there. [RS]: try [join] $args to get rid of braces :) ---- [dzach] 2018-01-23: [args] seems not to follow the rule the other arguments do: ====== % proc test {a {b 1} {args 2}} { puts "$a $b $args" } % test 0 0 1 ; # <- no default value for 'args' ====== Is there a reason for this, or I just hit a bug? I would expect something like this (workaround): ====== % proc test {a {b 1} {args 2}} { info default [lindex [info level [info level]] 0] args arg if {$args eq {}} { set args $arg } puts "$a $b $args" } % test 0 0 1 2 ====== foo: `args` doesn't seem to follow the same rules because it is never valueless and thus never eligible to receive a default value. Its value is the (possibly empty) list of arguments that overmatch the named parameters, and it always gets that value. [dzach] I still cannot see what it would hurt to have `args` follow the rule, other than adding a few microseconds to the execution time. The docs state "`[[the argument's] value will be the value of corresponding argument in the invoking command or the argument's default value`". Why break a rule when it costs nothing to follow it? I bet, changing it wouldn't break a single `proc` in the tcl universe. foo: it ''does'' follow the rule. The rule says that there must be exactly as many actual arguments in the invocation as formal parameters in the procedure declaration, with two variations: 1) there can be fewer arguments if the difference is made up with defaulted parameters, and 2) there may be more arguments if the last formal parameter is called `args`, in which case that parameter is assigned the list of excess arguments. Allowing a default value for `args` probably wouldn't cause much trouble, but it would be confusing (as it mixes up two different mechanisms) and unnecessary (since every practical use of it can be served by adding another parameter with a default value, or by the usual idiom of checking the length of `args` and taking the appropriate action). ---- See also [magic names]. ---- KPV: I always liked https://core.tcl.tk/tips/doc/trunk/tip/288.md%|%Tip 288 -- Allow "args" Anywhere in Procedure Formal Arguments%|%. I think it would be really useful in handling optional arguments which come before required arguments. But seeing how it's over 11 years old I doubt it will ever be implemented. <> Documentation