Light Yagami
Light Yagami

Reputation: 17

tcl find the max element of a list

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

Answers (1)

Donal Fellows
Donal Fellows

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

Related Questions