Yes, you likely have not reached that part of the book yet. The "args"
parameter is special on Tcl procs. It provides you a "list" of all
remaining arguments, rather than a "string" holding the value of just
one argument.
In your second example, where you quote the string "This is from tclsh"
you receive in "args" a list containing one element, that one element
being the string "This is from tclsh". Then when you do lindex--end on
args, you get the last element of the list, which is the string "This
is from tclsh".
In your first example, you passed a string directly into lindex. When
you do that, Tcl will attempt to convert the string into a list, and
when it does that automatically, it converts each run of non-whitespace
characters into a separate list element [1]. So what you have given
lindex, after Tcl converts the string to a list for you, is a list with
four elements:
s[0] = This
s[1] = is
s[2] = from
s[3] = tclsh
And when you ask for the "end" element, you get s[3]'s contents, which
is "tclsh".
If you change your "textIndex" proc's definition to "proc testIndex {s}
{" [1] and then change "$args" to "$s" inside the lindex, you'll get
the same result both times.
[1] This is not the "full" story, but it good enough for the point you
have reached in your Tcl book at this time.
Also, you should be warned that relying on Tcl's magic conversion from
string to list can be dangerous, and while it does happen, you should
be careful to only make it happen when you really know it is what you
truly want. You can achieve some odd, input data dependent, error
messages if it happens and you had not planned for it to happen.