• Squashing behaviour of [concat] since Tcl8.6.12

    From Erik Leunissen@21:1/5 to All on Sat Nov 6 13:36:29 2021
    List elements having a leading "#" character are handled specially if they are the first element of
    a list:

    % set lst1 [list a]
    a
    % set lst2 [list #b #c]
    {#b} #c
    %


    With Tcl8.6.11, joining these two lists using [concat] squashes one level of grouping (as
    documented) and gives the result (as I expected):

    % concat $lst1 $lst2
    a #b #c
    %

    However, with Tcl8.6.12 (and Tcl8.7a5) I get:

    % concat $lst1 $lst2
    a {#b} #c
    %


    Which of these two behaviours is correct, and why?

    Thanks in advance,
    Erik Leunissen
    --
    elns@ nl | Merge the left part of these two lines into one,
    xs4all. | respecting a character's position in a line.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Sat Nov 6 13:57:33 2021
    * Erik Leunissen <look@the.footer.invalid>
    | List elements having a leading "#" character are handled specially if
    | they are the first element of a list:

    | % set lst1 [list a]
    | a
    | % set lst2 [list #b #c]
    | {#b} #c
    | %


    | With Tcl8.6.11, joining these two lists using [concat] squashes one
    | level of grouping (as documented) and gives the result (as I
    | expected):

    | % concat $lst1 $lst2
    | a #b #c
    | %

    | However, with Tcl8.6.12 (and Tcl8.7a5) I get:

    | % concat $lst1 $lst2
    | a {#b} #c
    | %


    | Which of these two behaviours is correct, and why?

    Both are. What you see as the result of 'concat' is the string
    representation of the list, and obviously 8.6.12 decides to add more
    quoting for some reason.

    If you inspect the list, you get identical contents in 8.6.11 and 8.6.12:

    % info patchlevel
    8.6.11
    % set lst1 [list a]
    a
    % set lst2 [list #b #c]
    {#b} #c
    % set lst3 [concat $lst1 $lst2]
    a #b #c
    % foreach elt $lst3 { puts $elt }
    a
    #b
    #c

    % info patchlevel
    8.6.12
    % set lst1 [list a]
    a
    % set lst2 [list #b #c]
    {#b} #c
    % set lst3 [concat $lst1 $lst2]
    a {#b} #c
    % foreach elt $lst3 { puts $elt }
    a
    #b
    #c

    HTH
    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Erik Leunissen@21:1/5 to Ralf Fassel on Sat Nov 6 16:04:03 2021
    On 06/11/2021 13:57, Ralf Fassel wrote:

    Both are. What you see as the result of 'concat' is the string representation of the list, and obviously 8.6.12 decides to add more
    quoting for some reason.


    That's all well, but consider the following test
    (the test is taken from a Tk package where it
    is important to verify correct colour selection) :


    package require tcltest
    tcltest::test exercise {check colour selection} -body {
    set result [list black black black]
    # do other stuff
    concat $result [list #00ff00 #00ff00 #00ff00]
    } -result [list black black black #00ff00 #00ff00 #00ff00] tcltest::cleanupTests


    When this test is exercised by a user running Tcl < 8.6.12 the test passes. Suppose this test comes
    from a stable package, that doesn't receive frequent updates anymore. Now users are going to install
    Tcl8.6.12, run the test and it suddenly fails.

    Something is very awkward here (a missed *** POTENTIAL INCOMPATIBILITY *** ?), or would you say that
    the test was incorrect all along?

    Erik
    --

    If you inspect the list, you get identical contents in 8.6.11 and 8.6.12:

    % info patchlevel
    8.6.11
    % set lst1 [list a]
    a
    % set lst2 [list #b #c]
    {#b} #c
    % set lst3 [concat $lst1 $lst2]
    a #b #c
    % foreach elt $lst3 { puts $elt }
    a
    #b
    #c

    % info patchlevel
    8.6.12
    % set lst1 [list a]
    a
    % set lst2 [list #b #c]
    {#b} #c
    % set lst3 [concat $lst1 $lst2]
    a {#b} #c
    % foreach elt $lst3 { puts $elt }
    a
    #b
    #c

    HTH
    R'



    --
    elns@ nl | Merge the left part of these two lines into one,
    xs4all. | respecting a character's position in a line.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Erik Leunissen@21:1/5 to Erik Leunissen on Sat Nov 6 16:23:31 2021
    On 06/11/2021 16:04, Erik Leunissen wrote:
    ..
        concat $result [list #00ff00 #00ff00 #00ff00]
    ...

    I forgot to mention that [concat] was chosen on purpose for this test.
    It was meant to remove one level of grouping.

    Erik.
    --
    elns@ nl | Merge the left part of these two lines into one,
    xs4all. | respecting a character's position in a line.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Harald Oehlmann@21:1/5 to All on Sat Nov 6 17:51:29 2021
    Am 06.11.2021 um 13:36 schrieb Erik Leunissen:
    List elements having a leading "#" character are handled specially if
    they are the first element of a list:

    % set lst1 [list a]
    a
    % set lst2 [list #b #c]
    {#b} #c
    %


    With Tcl8.6.11, joining these two lists using [concat] squashes one
    level of grouping (as documented) and gives the result (as I expected):

    % concat $lst1 $lst2
    a #b #c
    %

    However, with Tcl8.6.12 (and Tcl8.7a5) I get:

    % concat $lst1 $lst2
    a {#b} #c
    %


    Which of these two behaviours is correct, and why?

    Thanks in advance,
    Erik Leunissen

    Dear Eric,
    afaik, concat has special features to build TCL commands.
    I suppose, that is the reason, why the "#" is handled in a special way.

    Perhaps, this special treatments got broken in TCL 8.6.12, or it is only
    the string representation which is wrong.
    I would prefer to open a bug on TCL to get more comments.

    Take care,
    Harald

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Don Porter@21:1/5 to Erik Leunissen on Sun Nov 7 08:47:49 2021
    See ticket https://core.tcl-lang.org/tcl/info/26649439c7

    You are correct this would have been better marked with a POTENTIAL INCOMPATIBILITY.

    [concat] is a string operation that follows a prescribed algorithm of
    joining strings together with single intervening spaces after trimming
    extra whitespace away. Honestly, it's very weird. It does not reliably produce canonical lists and never has.

    % concat {foo bar } " x y\tz\ngrok"
    foo bar x y z
    grok
    % concat foo \{
    foo {

    Until 8.6.12, the implementation of [concat] contained some
    optimizations when arguments were internally of the list type, but those optimizations were producing different results from a non-optimized
    approach. Since Tcl commands must treat all equal values (viewed as
    strings) the same, independent of internal representation and type, this violation was fixed.

    Note that your example use of [concat] still produces a list, a list
    containing all the same elements. Only the element formatting has
    changed.

    To get the same result you are accustomed to...

    % concat $lst1 $lst2
    a {#b} #c
    % list {*}$lst1 {*}$lst2
    a #b #c


    On 11/6/21 8:36 AM, Erik Leunissen wrote:
    List elements having a leading "#" character are handled specially if
    they are the first element of a list:

    % set lst1 [list a]
    a
    % set lst2 [list #b #c]
    {#b} #c
    %


    With Tcl8.6.11, joining these two lists using [concat] squashes one
    level of grouping (as documented) and gives the result (as I expected):

    % concat $lst1 $lst2
    a #b #c
    %

    However, with Tcl8.6.12 (and Tcl8.7a5) I get:

    % concat $lst1 $lst2
    a {#b} #c
    %


    Which of these two behaviours is correct, and why?

    Thanks in advance,
    Erik Leunissen


    --
    | Don Porter Applied and Computational Mathematics Division |
    | donald.porter@nist.gov Information Technology Laboratory |
    | http://math.nist.gov/~DPorter/ NIST | |______________________________________________________________________|

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Erik Leunissen@21:1/5 to Don Porter on Sun Nov 7 15:54:15 2021
    On 07/11/2021 14:47, Don Porter wrote:

    See ticket https://core.tcl-lang.org/tcl/info/26649439c7

    You are correct this would have been better marked with a POTENTIAL INCOMPATIBILITY.


    Thanks very much Don, for this entirely complete explanation:

    [concat] is a string operation that follows a prescribed algorithm of
    ... etc

    And for this recommended remedy (which is exactly what I already had in place as a solution for this
    case):


    To get the same result you are accustomed to...

    % concat $lst1 $lst2
    a {#b} #c
    % list {*}$lst1 {*}$lst2
    a #b #c


    It left absolutely not a single loose end for my understanding.

    Erik.
    --


    On 11/6/21 8:36 AM, Erik Leunissen wrote:
    List elements having a leading "#" character are handled specially if they are the first element
    of a list:

    % set lst1 [list a]
    a
    % set lst2 [list #b #c]
    {#b} #c
    %


    With Tcl8.6.11, joining these two lists using [concat] squashes one level of grouping (as
    documented) and gives the result (as I expected):

    % concat $lst1 $lst2
    a #b #c
    %

    However, with Tcl8.6.12 (and Tcl8.7a5) I get:

    % concat $lst1 $lst2
    a {#b} #c
    %


    Which of these two behaviours is correct, and why?

    Thanks in advance,
    Erik Leunissen




    --
    elns@ nl | Merge the left part of these two lines into one,
    xs4all. | respecting a character's position in a line.

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