• The best way to copy a list?

    From Mark Summerfield@m.n.summerfield@gmail.com to comp.lang.tcl on Wed Jun 18 07:19:45 2025
    From Newsgroup: comp.lang.tcl

    Is using `lmap` the best way to copy a list? For example:

    package require struct::list 1
    set a {a bc def ghij klmno}
    # is the following the best way to copy a list?
    set b [lmap x $a {expr {$x}}]
    puts "a={$a} b={$b} a==b=[struct::list equal $a $b]"

    Output:

    a={a bc def ghij klmno} b={a bc def ghij klmno} a==b=1
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Wed Jun 18 13:20:26 2025
    From Newsgroup: comp.lang.tcl

    Am 18.06.2025 um 09:19 schrieb Mark Summerfield:
    Is using `lmap` the best way to copy a list? For example:

    package require struct::list 1
    set a {a bc def ghij klmno}
    # is the following the best way to copy a list?
    set b [lmap x $a {expr {$x}}]
    puts "a={$a} b={$b} a==b=[struct::list equal $a $b]"

    Output:

    a={a bc def ghij klmno} b={a bc def ghij klmno} a==b=1

    Stupid question:

    set b $a

    to copy list b to a ?


    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Ashok@apnmbx-public@yahoo.com to comp.lang.tcl on Wed Jun 18 17:03:36 2025
    From Newsgroup: comp.lang.tcl

    Not sure I understand the question. Why not just

    set b $a

    ?

    Also, your code will not always give identical results using
    expr ([expr {$x}] is not always $x). For example,

    % set a {a 0x10 b}
    a 0x10 b
    % set b [lmap x $a {expr {$x}}]
    a 16 b

    You could use one of the following forms instead

    % set b [lmap x $a {lindex $x}]
    a 0x10 b
    % set b [lmap x $a {string cat $x}]
    a 0x10 b
    % set b [lmap x $a {return -level 0 $x}]
    a 0x10 b

    but as I said, why not just set a $b ?

    /Ashok

    set a {a 0x10 b}
    On 6/18/2025 12:49 PM, Mark Summerfield wrote:
    Is using `lmap` the best way to copy a list? For example:

    package require struct::list 1
    set a {a bc def ghij klmno}
    # is the following the best way to copy a list?
    set b [lmap x $a {expr {$x}}]
    puts "a={$a} b={$b} a==b=[struct::list equal $a $b]"

    Output:

    a={a bc def ghij klmno} b={a bc def ghij klmno} a==b=1

    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Mark Summerfield@m.n.summerfield@gmail.com to comp.lang.tcl on Wed Jun 18 11:59:04 2025
    From Newsgroup: comp.lang.tcl

    On Wed, 18 Jun 2025 17:03:36 +0530, Ashok wrote:

    Not sure I understand the question. Why not just

    set b $a

    ?

    Also, your code will not always give identical results using expr ([expr {$x}] is not always $x). For example,

    % set a {a 0x10 b}
    a 0x10 b % set b [lmap x $a {expr {$x}}]
    a 16 b

    You could use one of the following forms instead

    % set b [lmap x $a {lindex $x}]
    a 0x10 b % set b [lmap x $a {string cat $x}]
    a 0x10 b % set b [lmap x $a {return -level 0 $x}]
    a 0x10 b

    but as I said, why not just set a $b ?

    /Ashok

    set a {a 0x10 b}
    On 6/18/2025 12:49 PM, Mark Summerfield wrote:
    Is using `lmap` the best way to copy a list? For example:

    package require struct::list 1 set a {a bc def ghij klmno}
    # is the following the best way to copy a list?
    set b [lmap x $a {expr {$x}}]
    puts "a={$a} b={$b} a==b=[struct::list equal $a $b]"

    Output:

    a={a bc def ghij klmno} b={a bc def ghij klmno} a==b=1

    I'm coming to Tcl from Python & Go. In Python saying `a = [1, 2, 3]` and
    then `b = a` makes `b` a _reference_ to `a` rather than an independent variable. Now I realise that Tcl doesn't do it that way and that `set a
    $b` works fine.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Harald Oehlmann@wortkarg3@yahoo.com to comp.lang.tcl on Wed Jun 18 14:10:13 2025
    From Newsgroup: comp.lang.tcl

    Am 18.06.2025 um 13:59 schrieb Mark Summerfield:

    I'm coming to Tcl from Python & Go. In Python saying `a = [1, 2, 3]` and
    then `b = a` makes `b` a _reference_ to `a` rather than an independent variable. Now I realise that Tcl doesn't do it that way and that `set a
    $b` works fine.

    Well, internally you also get only a reference, in the sense, that the reference count of the data is incremented instead of copied.
    But if you modify b, you will not modify a, as then, a copy will be done.

    % set a {a bc def ghij klmno} ; ::tcl::unsupported::representation $a
    value is a pure string with a refcount of 4, object pointer at
    0x239caf217d0, string representation "a bc def ghij..."
    % set b $a ; ::tcl::unsupported::representation $b
    value is a pure string with a refcount of 5, object pointer at
    0x239caf217d0, string representation "a bc def ghij..."
    % lset b 0 b;::tcl::unsupported::representation $b
    value is a list with a refcount of 2, object pointer at 0x239cc358760, internal representation 0x239ccac9410:0x0, no string representation

    You see, that:
    set b $a: only recount incremented, a and b have same data address
    lset b 0 b: now, a copy is made, as b is different to a.

    Sorry, could not resist to copy satupid internals...
    Harald
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Colin Macleod@user7@newsgrouper.org.invalid to comp.lang.tcl on Wed Jun 18 12:19:19 2025
    From Newsgroup: comp.lang.tcl

    Mark Summerfield <m.n.summerfield@gmail.com> posted:

    I'm coming to Tcl from Python & Go. In Python saying `a = [1, 2, 3]` and then `b = a` makes `b` a _reference_ to `a` rather than an independent variable. Now I realise that Tcl doesn't do it that way and that `set a
    $b` works fine.

    When I had to do some Python for work, after being familiar with Tcl,
    I was quite shocked to find that Python shares values in that way! 😲
    --
    Colin Macleod ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ https://cmacleod.me.uk

    Warning: Gumption level low, top-up when possible!
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From Christian Gollwitzer@auriocus@gmx.de to comp.lang.tcl on Wed Jun 18 21:47:19 2025
    From Newsgroup: comp.lang.tcl

    Am 18.06.25 um 13:59 schrieb Mark Summerfield:
    I'm coming to Tcl from Python & Go. In Python saying `a = [1, 2, 3]` and
    then `b = a` makes `b` a _reference_ to `a` rather than an independent variable. Now I realise that Tcl doesn't do it that way and that `set a
    $b` works fine.

    I suspected something like this, when reading your question. In Python
    terms, Tcl has only immutable values. Whereas in Python, the outcome of
    a[2] = 'x' depends on what exact type this "a" thing is, in Tcl it is
    either impossible or it creates a copy on write (lset).

    This is part of the bigger "EIAS" concept ("everything is a string")
    which also means that values can be type-casted automatically - however,
    in good practice Tcl, you try to stick with a type nonetheless.

    Christian
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From et99@et99@rocketship1.me to comp.lang.tcl on Wed Jun 18 18:40:29 2025
    From Newsgroup: comp.lang.tcl

    On 6/18/2025 5:19 AM, Colin Macleod wrote:
    Mark Summerfield <m.n.summerfield@gmail.com> posted:

    I'm coming to Tcl from Python & Go. In Python saying `a = [1, 2, 3]` and
    then `b = a` makes `b` a _reference_ to `a` rather than an independent
    variable. Now I realise that Tcl doesn't do it that way and that `set a
    $b` works fine.

    When I had to do some Python for work, after being familiar with Tcl,
    I was quite shocked to find that Python shares values in that way! 😲


    Me too!

    This python feature goes against my favorite rule of language design:

    "The principle of least astonishment"

    I'd have to say that python gets a low score on that one!

    especially how with a=b, you don't even know the type (and thus immutability) of b without looking elsewhere, which can lead to some nasty runtime surprises.


    --- Synchronet 3.21a-Linux NewsLink 1.2