Which one is proper way of using variable with or without dollar sign? I thought that variable (without $) is used only during variable declaration (similar to Bash):
set var 10
In all other cases when variable is referred or used (but not declared) the proper syntax is $variable (with $):
set newVar $var
puts $var
puts $newVar
But then I found code where it is interchanged and seems that this code is working:
# using argv
if {[array exists argv]} {
  puts "argv IS ARRAY"
} else {
  puts "argv IS NOT AN ARRAY"
}
# using $argv
if {[array exists $argv]} {
  puts "\$argv IS ARRAY"
} else {
  puts "\$argv IS NOT AN ARRAY"
}
# using argv
if {[string is list argv]} {
  puts "argv IS LIST"
} else {
  puts "argv IS NOT LIST"
}
# using $argv    
if {[string is list $argv]} {
  puts "\$argv IS LIST"
} else {
  puts "\$argv IS NOT LIST"
}
Output:
argv IS NOT AN ARRAY
$argv IS NOT AN ARRAY
argv IS LIST
$argv IS LIST
Edit in reply to @glenn jackman:
Your reply pointed me to further research and I've found that TCL is capable doing some sort of "self modifying code" or whatever is correct name e.g.:
% set variableName "x"
x
% puts $x
can't read "x": no such variable
% set $variableName "abc"
abc
% puts $x
abc
% puts [set $variableName]
abc
%
%
%
%
%
%
% set x "def"
def
% puts $x
def
% puts [set $variableName]
def
%
Now your answer bring some light to problem, but one question remains. This is excerpt from documentation:
set varName ?value?
array exists arrayName
Documentation says that both functions expect variable name (not value) in other words it expect variable instead of $variable. So I assume (based on above self modifying code) that when I pass $variable instead of variable the variable substitution took place (exactly the same as code above). But what if $variable contains something that is not a list neither array (my arguments during testing was: param0 param1 "param 2" param3). From this point of view the output that says $argv IS LIST is wrong. What am I missing here?
Edit in reply to @schlenk:
Finally I (hope) understand the problematic. I've found great article about TCL, which explain (not just) this problematic. Let me pinpoint a few wise statement from this article:
- In Tcl what a string represents is up to the command that's manipulating it.
 - Everything is a command in Tcl - as you can see there is no assignment operator.
 ifis a command, with two arguments.- The command name is not a special type but just a string.
 
Also following SO answer confirms this statement:
"In Tcl, values don't have a type... they question is whether they can be used as a given type."
The command string is integer $a means:
- "Can I use the value in 
$aas an integer" 
NOT
"Is the value in
$aan integer""Every integer is also a valid list (of one element)... so it can be used as either and both string is commands will return true (as will several others for an integer)."
I believe the same applies also for string is list command:
% set abc "asdasd"
asdasd
% string is list $abc
1
% string is alnum $abc
1
string is list returns 1 because $abc is string and also it is one element list etc. In most tutorials there are said that following snippet is the proper way of declaring and working with lists:
% set list1 { 1 2 3 }
% lindex $list1 end-1
2
But when everything in TCL is string the following is also working in my experience (if I am wrong correct me please).
% set list2 "1 2 3"
1 2 3
% lindex $list2 end-1
2