[Richard Suchenwirth] 2002-11-07 - Tcl's [upvar] command ties a local variable in a [proc] to another in a higher scope in the call stack - typically the caller's (upvar 1). This way, references (like pointers in C, or literally "call by name") can be implemented. The Tcl Style Guide recommends "Name" as suffix for upvar-ed arguments, e.g. proc example {varName value} { upvar 1 $varName var ...} which is a good convention for readable code. However, after a hard day of adjusting ''*const**'' references in C++, frustration with that baroque language brought me to think of other ways in the freeest language I know - Tcl. I did not want to repeat the ''*const**'' experience, but simple references can be sugared by overloading the [proc] command. For this breakfast fun project, I chose the slightly different name ''pruc'' ("procedure with upvar components"). It is called just like [proc], with the added behavior that arguments declared with prefix * or & are implicitly upvar-ed to a local variable without that prefix, before the original proc body. Simple enough, but again a few lines of code have changed the face of our language considerably: } proc pruc {name argl body} { set prefix "" foreach {upvar var} [regexp -all -inline {[*&]([^ ]+)} $argl] { append prefix "\nupvar 1 \${$upvar} $var;" } proc $name $argl $prefix$body } #------------- Testing: pruc demo {*i j} { set i $j } puts "[demo foo 42]/$foo" pruc demo2 {j &i} { set i $j } puts "[demo2 43 bar]/$bar" puts "generated body: [info body demo2]" if 0 {...which shows on stdout: 42/42 43/43 generated body: upvar 1 ${&i} i; set i $j } See [Pass by reference] for an earlier alternative, and [use_refs] ---- ''[escargo] 15 Dec 2005'' - I wonder if you thought about a different policy: When an argument name ends in "Name" (e.g., varName), automatically insert ''upvar $varName var'' into the synthesized procedure. That would follow the Style Guide. [KPV] wouldn't work for me because I often have parameters with names like ''imageName'', ''fileName'' and ''widgetName''. [AMG]: I wasn't aware that this Name suffix style had been codified, so I made up my own convention: I usually suffix "name" argument names with "_var". For instance, if I wrote a proc that as a side effect would set some variable in the caller's frame to the name of an image, I'd call that parameter imagename_var. To me that name suggests that the caller should pass the name of the variable storing the image name. ---- 2006-04-28 [wdb] -- why so "Perl"ish with these cryptic signs? I prefer it human readable: proc refProc {name varlist body} { set varlist1 {} set upvarBody "" foreach var $varlist { if {[llength $var] > 1 && [lindex $var 0] eq "referenced"} then { set varName [lindex $var end] lappend varlist1 _$varName append upvarBody "upvar \$_$varName $varName" \n } else { lappend varlist1 $var } } uplevel [list proc $name $varlist1 $upvarBody$body] } Example: refProc test {{referenced a} b} { append a $b } % set a Apfel Apfel % test -Baum Apfel-Baum % set a Apfel-Baum The only disadvantage I see is that it is not possible to use the argument name "referenced" with a default value in the arguments list -- which I find acceptable.