• Length of a joined list

    From Simon Geard@21:1/5 to All on Wed Jul 12 21:04:09 2023
    Are all these results correct? To my simple mind the result should
    always be 1 irrespective of the string used in the concatenation.

    % set li {1 2 3}
    1 2 3
    % llength $li
    3
    % llength [join $li ,]
    1
    % llength [join $li \t]
    3
    % llength [join $li x]
    1
    % llength [join $li { }]
    3
    % llength [join $li {xox}]
    1
    % llength [join $li]
    3

    The man page doesn't seem to explain this inconsistency so I'm
    struggling to understand it. Thanks for any ideas.

    Simon

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From mango@21:1/5 to Simon Geard on Wed Jul 12 13:18:25 2023
    On Wednesday, July 12, 2023 at 1:04:16 PM UTC-7, Simon Geard wrote:
    Are all these results correct? To my simple mind the result should
    always be 1 irrespective of the string used in the concatenation.
    [snip]
    The man page doesn't seem to explain this inconsistency so I'm
    struggling to understand it. Thanks for any ideas.

    Simon
    The results are correct. The key to understanding is two fold. Lists in Tcl are just specially formatted strings. The join command creates a string from elements of a list. But, when llength is invoked on the join result (which is a string), it parses
    the string into a list. When the join is with a whitespace character (e.g. \t) then when llength parses the joined string, it finds that it looks just like a list. Mixing string operations, i.e. join, with list operations, i.e. llength, is often a recipe
    for confounding results. Printing out the intermediate join results may help you see that.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Simon Geard on Wed Jul 12 21:55:22 2023
    Simon Geard <[email protected]> wrote:
    Are all these results correct? To my simple mind the result should
    always be 1 irrespective of the string used in the concatenation.

    % set li {1 2 3}
    1 2 3
    % llength $li
    3
    % llength [join $li ,]
    1
    % llength [join $li \t]
    3
    % llength [join $li x]
    1
    % llength [join $li { }]
    3
    % llength [join $li {xox}]
    1
    % llength [join $li]
    3

    The man page doesn't seem to explain this inconsistency so I'm
    struggling to understand it. Thanks for any ideas.

    Simon

    To add to what mango said, the simplest string representation that Tcl
    uses to represent a list as a string is simply to separate groups of
    non-white space characters with a white space character (the actual
    format is by far more complex, and describing it would only further
    confuse you).

    Add to that the fact that if you presently have a string, and ask for a
    "list operation" to be performed on the string, Tcl will parse the
    string into a list (if it can) or error out with an error message about
    being unable to convert to list form.

    Your first set is of a string, the string 1[space]2[space]3[space]
    (where [space] means a single ASCII space character). Tcl's
    string-to-list parser will convert that into a three eleement list if
    you ask for "list operations" upon it.

    So directly asking for the length results first in conversion to a
    list, and then returning the length of the list, so you get three.

    Joining with a comma however leaves no whitespace behind, so you get
    1,2,3 which the parser then converts to a one element list, and you get
    one as the answer.

    The rest of the answers all follow by applying this rule to the
    intermediate string that enters 'llength'. If there is whitespace,
    multiple list elements result, if there is no whitespace, only one
    list element results.

    And, the warning mango gave is something to keep in mind. Mixing lists
    and strings freely can be the source of weird data dependent bugs.
    Things can work properly for months until just the right string comes
    along to cause the string-to-list parser to error out.

    It is much better to only use list commands on lists, only use string
    commands on strings, and explicitly use the two conversion commands
    (split and join) to convert one to the other yourself.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)