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 ====== `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. ---- 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