Reputation: 17
i am new to tcl , i am trying to get the max element in a given list i wrote a function that prints the max but it is not working properly here is the code
proc findmax { items } {
set max 1
foreach i $items {
if { $i > $max } {
set $max $i
}
}
puts "max is = $max"
}
and i called the function like this :
findmax $items
this is the list i passed :
set items { 12 2 5 4 2 6 7 55 8 9 6 4}
but it outputs 1 and not 55 as expected
Upvotes: 1
Views: 18753
Reputation: 137717
Your problem is this line:
set $max $i
In Tcl, the $
character means read from the named variable and use that value as (possibly part of) the argument to a command. It means this always. No exceptions (unless backslash-quoted or in {
braces}
, of course). Thus, on the first iteration of the loop you're getting (after substitution):
set 1 12
The variable name 1
is legal, but unusual and not what you want. For the algorithm to work, you instead want to give the set
command the name of the variable to set, max
, resulting in this:
set max $i
which will be substituted to this on the first iteration:
set max 12
That looks right! A good rule of thumb for future programming is that if a command manipulates a variable (setting it or updating it) then you need to pass the name of the variable, not the value retrieved from it.
The standard method of getting the maximum value of a list is a one-liner:
set max [tcl::mathfunc::max {*}$items]
This uses the built-in function max
(which is in the ::tcl::mathfunc
namespace) and passes the contents of the list in items
as multiple arguments, all as one step. The {*}$
sequence is a combination of the variable-read syntax rule with the list-expansion rule, which you've probably not really thought about yet. However it's still a good exercise to write your own maximum finder as a learning exercise.
Upvotes: 7