3
votes

Would like to take an advice from TCL professionals for best practice.

Say you want to construct a list with a specific data by using a proc. Now which is the best way?

proc processList { myList } {
   upvar $myList list_
    #append necessary data into list_
}

proc returnList {} {
    set list_ {} 
    #append necessary data into list_
    return $list_
}

set list1 {}
processList list1

set list2 [returnList ]

Which one of this practices is recommended?

EDIT: I am sorry but I can't understand consensus (and explanation) of people who answered to this question.

3
For passing an array, the upvar-way is a good best-practice. The upvar may also be useful if you have to return more than one value. However, it's not always clear that you have to pass the variable name instead of the variable itself, so make sure to make a comment about it.Roalt

3 Answers

7
votes

I virtually always use the second method:

proc returnList {} {
    set result {}
    # ... accumulate the result like this ...
    lappend result a b c d e
    return $result
}
set lst [returnList]

There's virtually no difference in memory usage or speed, but I find it easier to think functionally. Also, in Tcl 8.5 you can do the splitting up of the result list relatively simply (if that's what you need):

set remainderList [lassign [returnList] firstValue secondValue]

With that, you'd end up with a in $firstValue, b in secondValue, and c d e in $remainderList.

3
votes

The first option modify an existing list whereas the second create a new list. For a better comparison, I would add a parameter to returnList() and create a return value from that parameter.

Given that, the difference is in the way of passing parameters -- by reference or by value-- and in the memory budget needed by each operation.

There is no side effect with the second method, but it could be very consuming if the list is huge.

There is no general rule for recommending one over the other. My own rule is to start with the second way unless other constraints lead not to do so.

0
votes

What would the syntax be for the equivalent of:

set lst [returnList]

If you wanted to return more than one list at once?

I thought that if you did something like this:

return [$list1 $list2]

It was supposed to return a list of lists, which you could then access with lindex. But, that doesn't appear to be exactly what it does. It really just gives you two lists back, without external curly braces grouping them into a single list. In Perl, you can do something like:

($var1, $var2) = process_that_returns_two_values;

But I don't think "set" allows that in Tcl.