• request new command "lstride"

    From aotto1968@21:1/5 to All on Fri May 17 08:22:45 2024
    request new command lstride (ref: https://wiki.tcl-lang.org/page/request+new+command+lstride)


    The following code is used:

    proc lib_ME__copy_what {whatRef old new} {
    upvar $whatRef whatDEF
    global attributeDEF ARG_TYPE_ATTRIBUTE RET_TYPE_ATTRIBUTE ARG_DEFAULT

    set mapL [list $old $new]

    array set attributeDEF \
    [concat {*}[lmap {k v} [array get attributeDEF $old,*] {list [string map $mapL $k] $v} ]]
    array set ARG_TYPE_ATTRIBUTE \
    [concat {*}[lmap {k v} [array get ARG_TYPE_ATTRIBUTE $old,*] {list [string map $mapL $k] $v} ]]
    array set RET_TYPE_ATTRIBUTE \
    [concat {*}[lmap {k v} [array get RET_TYPE_ATTRIBUTE $old,*] {list [string map $mapL $k] $v} ]]
    array set ARG_DEFAULT \
    [concat {*}[lmap {k v} [array get ARG_DEFAULT $old,*] {list [string map $mapL $k] $v} ]]
    set whatDEF($new) $whatDEF($old)
    }

    the syntax I recommend is

    proc lib_ME__copy_what {whatRef old new} {
    upvar $whatRef whatDEF
    global attributeDEF ARG_TYPE_ATTRIBUTE RET_TYPE_ATTRIBUTE ARG_DEFAULT

    set mapL [list $old $new]

    array set attributeDEF [lmap {k v} [array get attributeDEF $old,*] {lstride [string map $mapL $k] $v} ]
    array set ARG_TYPE_ATTRIBUTE [lmap {k v} [array get ARG_TYPE_ATTRIBUTE $old,*] {lstride [string map $mapL $k] $v} ]
    array set RET_TYPE_ATTRIBUTE [lmap {k v} [array get RET_TYPE_ATTRIBUTE $old,*] {lstride [string map $mapL $k] $v} ]
    array set ARG_DEFAULT [lmap {k v} [array get ARG_DEFAULT $old,*] {lstride [string map $mapL $k] $v} ]
    set whatDEF($new) $whatDEF($old)
    }

    The new command lstride has the same effect as {*} this mean create a flat list

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From aotto1968@21:1/5 to All on Fri May 17 11:52:58 2024
    more easy example


    lappend a {*}[list 1 2 3]
    1 2 3

    lappend b [lstride 1 2 3]
    1 2 3

    lappend c [list 1 2 3]
    {1 2 3}


    On 17.05.24 08:22, aotto1968 wrote:
    request new command lstride (ref: https://wiki.tcl-lang.org/page/request+new+command+lstride)


    The following code is used:

    proc lib_ME__copy_what {whatRef old new} {
      upvar $whatRef whatDEF
      global attributeDEF ARG_TYPE_ATTRIBUTE RET_TYPE_ATTRIBUTE ARG_DEFAULT

      set mapL  [list $old $new]

      array set attributeDEF \
        [concat {*}[lmap {k v} [array get attributeDEF $old,*]        {list [string map $mapL $k] $v} ]]
      array set ARG_TYPE_ATTRIBUTE \
        [concat {*}[lmap {k v} [array get ARG_TYPE_ATTRIBUTE $old,*]  {list [string map $mapL $k] $v} ]]
      array set RET_TYPE_ATTRIBUTE \
        [concat {*}[lmap {k v} [array get RET_TYPE_ATTRIBUTE $old,*]  {list [string map $mapL $k] $v} ]]
      array set ARG_DEFAULT \
        [concat {*}[lmap {k v} [array get ARG_DEFAULT $old,*]         {list [string map $mapL $k] $v} ]]
      set whatDEF($new) $whatDEF($old)
    }

    the syntax I recommend is

    proc lib_ME__copy_what {whatRef old new} {
      upvar $whatRef whatDEF
      global attributeDEF ARG_TYPE_ATTRIBUTE RET_TYPE_ATTRIBUTE ARG_DEFAULT

      set mapL  [list $old $new]

      array set attributeDEF       [lmap {k v} [array get attributeDEF $old,*]        {lstride [string map $mapL $k] $v} ]
      array set ARG_TYPE_ATTRIBUTE [lmap {k v} [array get ARG_TYPE_ATTRIBUTE $old,*]  {lstride [string map $mapL $k] $v} ]
      array set RET_TYPE_ATTRIBUTE [lmap {k v} [array get RET_TYPE_ATTRIBUTE $old,*]  {lstride [string map $mapL $k] $v} ]
      array set ARG_DEFAULT        [lmap {k v} [array get ARG_DEFAULT $old,*]         {lstride [string map $mapL $k] $v} ]
      set whatDEF($new) $whatDEF($old)
    }

    The new command lstride has the same effect as {*} this mean create a flat list

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Gollwitzer@21:1/5 to All on Fri May 17 19:14:09 2024
    Am 17.05.24 um 11:52 schrieb aotto1968:

    more easy example


    lappend a {*}[list 1 2 3]
    1 2 3

    OK

    lappend b [lstride 1 2 3]
    1 2 3

    impossible. This would violate the basic rules of Tcl


    Christian

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Gollwitzer@21:1/5 to All on Sat May 18 09:12:24 2024
    Am 18.05.24 um 08:21 schrieb aotto1968:
    On 17.05.24 19:14, Christian Gollwitzer wrote:
    Am 17.05.24 um 11:52 schrieb aotto1968:

    more easy example


    lappend a {*}[list 1 2 3]
    1 2 3

    OK

    lappend b [lstride 1 2 3]
    1 2 3

    impossible. This would violate the basic rules of Tcl


    I don't understand the problem of tcl the "Tcl_Obj" just need an
    *flat-flag* and
    if you build the argument-list of a function-call you check this flag.

    The rule is, if you can't write a proc lstride {args} that does what you
    want, you're working against the basic rules as spelled out here: https://www.tcl-lang.org/man/tcl/TclCmd/Tcl.htm
    Rule 5 ({*}) has been added for Tcl 8.6 to cover the use case you described.

    I don't even require that the *flat-flag* is persistent (convert to
    string and back)

    That would violate another one of the basic rules of Tcl - EIAS. You are
    of course free to fork Tcl and create your own language that works
    differently - go ahead and have fun, the license is very permissive.
    However, don't be surprised that others will not adopt such fundamental
    changes into mainline Tcl.

    Christian

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From aotto1968@21:1/5 to Christian Gollwitzer on Sat May 18 08:21:05 2024
    On 17.05.24 19:14, Christian Gollwitzer wrote:
    Am 17.05.24 um 11:52 schrieb aotto1968:

    more easy example


    lappend a {*}[list 1 2 3]
    1 2 3

    OK

    lappend b [lstride 1 2 3]
    1 2 3

    impossible. This would violate the basic rules of Tcl


        Christian

    I don't understand the problem of tcl the "Tcl_Obj" just need an *flat-flag* and
    if you build the argument-list of a function-call you check this flag.

    I don't even require that the *flat-flag* is persistent (convert to string and back)

    mfg.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From aotto1968@21:1/5 to All on Sat May 18 14:07:56 2024
    #funny

    #!/usr/bin/env tclsh

    proc myproc {} {
    string cat "{*}" [list 1 2 3]
    }

    lappend a [myproc]

    puts $a

    {{*}1 2 3}

    the "secret" is just that TCL does NOT look into the value of the argument to decide how to process

    → the "{*}" prefix would be also fulfill the last "basic" rule

    mfg

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andreas Leitgeb@21:1/5 to [email protected] on Sat May 18 14:04:08 2024
    aotto1968 <[email protected]> wrote:
    request new command lstride (ref: https://wiki.tcl-lang.org/page/request+new+command+lstride)
    current:
    array set attributeDEF \
    [concat {*}[lmap {k v} [array get attributeDEF $old,*] {list [string map $mapL $k] $v} ]]
    suggestion:
    array set attributeDEF [lmap {k v} [array get attributeDEF $old,*] {lstride [string map $mapL $k] $v} ]

    Ignoring the further thread as it went straightforward against the
    spirit of Tcl, there would still be a different (and tcl-conform)
    way to achieve that:

    The focus would need to go to lmap: it could interpret a specific
    return-code (aside from "break" and "continue") - lets take 42 just
    for now - and handle it such, that the value returned from
    the lmap body is treated as a list and concated to the accumulator.

    It would be possible to implement "lmap" as a tcl-procedure based
    on foreach, uplevel, try&catch and lappend. Then a procedure "lstride"
    could also be written: proc lstride {args} {return -code 42 $args}
    and lmap would have a handler for code 42 to do "lappend acc {*}$value"
    rather than the normal "lappend acc $value".

    Now for a little twist: command "continue" cannot currently "return" a non-empty value, it always returns an empty string or empty list.
    So, we could interpret it already as a list of objects to add
    individually to the accumulator - it would effectively be the same
    as lmaps current response to a call of "continue" from the lmap-body.

    In the end, by defining lstride such:
    proc lstride {args} {return -code continue $args}
    and having lmap handle "continue" to lappend'ing all elements
    of the body's return value individually to its accumulator,
    we would exactly have the requested behaviour fo lstride wrt. lmap.

    PS: that's just brainstorming... I'm aware that changing "continue"
    handling is not to be taken that lightly... - although the number
    of people already having procedures to "continue with value" and
    calling that from an lmap-body, relying on the value to be ignored,
    might be diminishingly small.
    I just found it cute, that current "continue"-handling would be just
    a special case of that presented change.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Gollwitzer@21:1/5 to All on Sat May 18 17:14:23 2024
    Am 18.05.24 um 16:04 schrieb Andreas Leitgeb:
    aotto1968 <[email protected]> wrote:
    request new command lstride (ref: https://wiki.tcl-lang.org/page/request+new+command+lstride)
    current:
    array set attributeDEF \
    [concat {*}[lmap {k v} [array get attributeDEF $old,*] {list [string map $mapL $k] $v} ]]
    suggestion:
    array set attributeDEF [lmap {k v} [array get attributeDEF $old,*] {lstride [string map $mapL $k] $v} ]

    Ignoring the further thread as it went straightforward against the
    spirit of Tcl, there would still be a different (and tcl-conform)
    way to achieve that:

    The focus would need to go to lmap: it could interpret a specific return-code (aside from "break" and "continue") - lets take 42 just
    for now - and handle it such, that the value returned from
    the lmap body is treated as a list and concated to the accumulator.

    I agree that changing lmap would be the way to go forward here -
    however, the whole lstride thing seems overcomplicated to me. How about
    an additional option for lmap, say, "-flat" or "-join" that makes lmap
    concat the results instead of lappending? If one wishes to switch inside
    the loop, one could easily wrap arguments into [list] :


    lmap -join {k v} [array get attributeDEF $old,*] {list [string map $mapL $k] $v} ]]

    Christian

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Andreas Leitgeb@21:1/5 to Christian Gollwitzer on Sat May 18 15:53:19 2024
    Christian Gollwitzer <[email protected]> wrote:
    Am 18.05.24 um 16:04 schrieb Andreas Leitgeb:
    aotto1968 <[email protected]> wrote:
    request new command lstride (ref: https://wiki.tcl-lang.org/page/request+new+command+lstride)
    current:
    array set attributeDEF \
    [concat {*}[lmap {k v} [array get attributeDEF $old,*] {list [string map $mapL $k] $v} ]]
    suggestion:
    array set attributeDEF [lmap {k v} [array get attributeDEF $old,*] {lstride [string map $mapL $k] $v} ]
    The focus would need to go to lmap: it could interpret a specific
    return-code (aside from "break" and "continue") - lets take 42 just
    for now - and handle it such, that the value returned from
    the lmap body is treated as a list and concated to the accumulator.
    I agree that changing lmap would be the way to go forward here -
    however, the whole lstride thing seems overcomplicated to me. How about
    an additional option for lmap, say, "-flat" or "-join" that makes lmap
    concat the results instead of lappending?

    Indeed, that would be ways simpler in the end, and it would save us from
    a command that only ever makes sense within an lmap body. ;-)

    Also, lmap currently cannot accept an even number of arguments, so it would
    be safely distinct from a call with a single iterator variable named "-flat".

    Only downside: each lmap invocation can only ever accept a single option.
    Once there is "-flat" [btw. imho "-join" would be misleading] then
    no further options can be added later (at least none that could ever be combined with -flat).

    lmap -join {k v} [array get attributeDEF $old,*] {list [string map $mapL $k] $v} ]]
    Christian

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