user8469759
user8469759

Reputation: 2732

tcl scripts, struggling with [...] and [expr ...]

I can't understand how assignments and use of variables work in Tcl.

Namely:

If I do something like

set a 5
set b 10

and I do

set c [$a + $b]

Following what internet says:

You obtain the results of a command by placing the command in square brackets ([]). This is the functional equivalent of the back single quote (`) in sh programming, or using the return value of a function in C.

So my statement should set c to 15, right? If yes, what's the difference with

set c [expr $a + $b]

? If no, what does that statement do?

Upvotes: 2

Views: 1282

Answers (2)

Donal Fellows
Donal Fellows

Reputation: 137637

Tcl's a really strict language at its core; it always follows the rules. For your case, we can therefore analyse it like this:

set c [$a + $b]

That's three words, set (i.e., the standard “write to a variable” command), c, and what we get from evaluating the contents of the brackets in [$a + $b]. That in turn is a script formed by a single command invocation with another three words, the contents of the a variable (5), +, and the contents of the b variable (10). That the values look like numbers is irrelevant: the rules are the same in all cases.

Since you probably haven't got a command called 5, that will give you an error. On the other hand, if you did this beforehand:

proc 5 {x y} {
    return "flarblegarble fleek"
}

then your script would “work”, writing some (clearly defined) utter nonsense words into the c variable. If you want to evaluate a somewhat mathematical expression, you use the expr command; that's it's one job in life, to concatenate all its arguments (with a space between them) and evaluate the result as an expression using the documented little expression language that it understands.

You virtually always want to put braces around the expression, FWIW.


There are other ways to make what you wrote do what you expect, but don't do them. They're slow. OTOH, if you are willing to put the + first, you can make stuff go fast with minimum interference:

# Get extra commands available for Lisp-like math...
namespace path ::tcl::mathop

set c [+ $a $b]

If you're not a fan of Lisp-style prefix math, use expr. It's what most Tcl programmers do, after all.

Upvotes: 3

Dinesh
Dinesh

Reputation: 16428

set c [$a + $b]

Running the above command, you will get invalid command name "5" error message.

For mathematical operations, we should rely on expr only as Tcl treats everything as string.

set c [expr $a + $b]

In this case, the value of a and b is passed and addition is performed.

Here, it is always safe and recommended to brace the expressions as,

set c [expr {$a+$b}]

To avoid any possible surprises in the evaluation.

Update 1 :

In Tcl, everything is based on commands. It can a user-defined proc or existing built-in commands such as lindex. Using a bare-word of string will trigger a command call. Similarly, usage of [ and ] will also trigger the same.

In your case, $a replaced with the value of the variable a and since they are enclosed within square brackets, it triggers command call and since there is no command with the name 5, you are getting the error.

Upvotes: 1

Related Questions