• Re: Reference to dictionary variable name in dict commands seems incons

    From et99@21:1/5 to All on Tue Apr 25 11:59:17 2023
    On 4/25/2023 11:51 AM, saitology9 wrote:
    On 4/25/2023 2:26 PM, Lawrence Emke wrote:
    I understand the syntax to create a dict variable:
        set dname [ dict create a b ]
    Now compare these two commands:

        dict append dname  d e
    and
        dict get $dname d

    in the first  case the dict name does not require the de-reference $ character.
    In the second command it does require the deference $ character.

    This seems to be confusing. Don't force me to remember which case requires the de-reference $ character and which does not accept the $ character.

    Maybe there is a hidden explanation (reason) other than the implementation of the command that does not just pop up to a new student.  Please make it consistent. It will save time and effort to learn the language syntax.

    I agree dict is hard to get used to.

    Think of dict not as some new data structure in Tcl but rather as an interface consisting of a set of commands that operate on lists with an even number of elements.  In fact, I suspect that many dict use cases are on lists that happen to have this
    structure. You can use on any literal lists or variable that satisfies this condition.

    Under this light, the first one makes sense: you don't want to append to a literal list, i.e., a constant value.  This will be like doing "5 = x + y" in C for example.

    The second makes sense too because it acts as a get-method on a list that has an even number of elements.  You don't want to be forced into creating a temporary dict variable out of your normal lists just to get some elements out of it.







    Commands that modify an existing variable, are call by name
    if the variable's value is needed, then it's by value $value

    that's how I remember them. Similar to say, lappend, lset etc.
    which modify a current list are by name vs. lindex, lrange,
    which take a list and return a new one or part of one are by value.

    Incidentally, the dict append manual entry does not say that
    if the variable doesn't exist, then it is created first as
    an empty dict. But that is consistent with such commands as
    [incr]. And so too [dict incr] which also doesn't mention that
    a non existent key is treated as a 0 and then incremented.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From saitology9@21:1/5 to Lawrence Emke on Tue Apr 25 14:51:07 2023
    On 4/25/2023 2:26 PM, Lawrence Emke wrote:
    I understand the syntax to create a dict variable:
    set dname [ dict create a b ]
    Now compare these two commands:

    dict append dname d e
    and
    dict get $dname d

    in the first case the dict name does not require the de-reference $ character.
    In the second command it does require the deference $ character.

    This seems to be confusing. Don't force me to remember which case requires the de-reference $ character and which does not accept the $ character.

    Maybe there is a hidden explanation (reason) other than the implementation of the command that does not just pop up to a new student. Please make it consistent. It will save time and effort to learn the language syntax.

    I agree dict is hard to get used to.

    Think of dict not as some new data structure in Tcl but rather as an
    interface consisting of a set of commands that operate on lists with an
    even number of elements. In fact, I suspect that many dict use cases
    are on lists that happen to have this structure. You can use on any
    literal lists or variable that satisfies this condition.

    Under this light, the first one makes sense: you don't want to append to
    a literal list, i.e., a constant value. This will be like doing "5 = x
    + y" in C for example.

    The second makes sense too because it acts as a get-method on a list
    that has an even number of elements. You don't want to be forced into
    creating a temporary dict variable out of your normal lists just to get
    some elements out of it.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence Emke@21:1/5 to All on Tue Apr 25 14:27:36 2023
    On Tuesday, April 25, 2023 at 1:59:22 PM UTC-5, et99 wrote:
    On 4/25/2023 11:51 AM, saitology9 wrote:
    On 4/25/2023 2:26 PM, Lawrence Emke wrote:
    I understand the syntax to create a dict variable:
    set dname [ dict create a b ]
    Now compare these two commands:

    dict append dname d e
    and
    dict get $dname d

    in the first case the dict name does not require the de-reference $ character.
    In the second command it does require the deference $ character.

    This seems to be confusing. Don't force me to remember which case requires the de-reference $ character and which does not accept the $ character.

    Maybe there is a hidden explanation (reason) other than the implementation of the command that does not just pop up to a new student. Please make it consistent. It will save time and effort to learn the language syntax.

    I agree dict is hard to get used to.

    Think of dict not as some new data structure in Tcl but rather as an interface consisting of a set of commands that operate on lists with an even number of elements. In fact, I suspect that many dict use cases are on lists that happen to have this
    structure. You can use on any literal lists or variable that satisfies this condition.

    Under this light, the first one makes sense: you don't want to append to a literal list, i.e., a constant value. This will be like doing "5 = x + y" in C for example.

    The second makes sense too because it acts as a get-method on a list that has an even number of elements. You don't want to be forced into creating a temporary dict variable out of your normal lists just to get some elements out of it.




    Commands that modify an existing variable, are call by name
    if the variable's value is needed, then it's by value $value

    that's how I remember them. Similar to say, lappend, lset etc.
    which modify a current list are by name vs. lindex, lrange,
    which take a list and return a new one or part of one are by value.

    Incidentally, the dict append manual entry does not say that
    if the variable doesn't exist, then it is created first as
    an empty dict. But that is consistent with such commands as
    [incr]. And so too [dict incr] which also doesn't mention that
    a non existent key is treated as a 0 and then incremented.


    The problem is that the dict "name" is hard coded in the append command
    without the $ de-reference action. In the get sub command it must contain
    a reference variable syntax. If you switch the $ syntax on the both statements,
    neither statement executes correctly.

    My goal is to separate the application data namespace from the proc/methods. By that I mean, having all of the app data in one namespace and the methods
    in one or more other namespaces. I want to avoid little namespaces hanging off the applications data namespace. This means the dict append sub-command executed in a proc
    that receives the data via a parameter should use a reference to the dict structure rather than coding its name.
    The append sub-command needs receive the dict structure via a proc parameter variable. In this
    way the dict structure can be passed as a parameter. The unset sub-command takes either the DictName
    or a de-reference variable to the dict element. Both work. The same should be for the append sub-command

    I have tried several configurations in proc calls. None of them work. I have considered the
    level command. However, the actual dict structure may be a member of the caller's
    namespace. I assume in this situation, the search for the parameter in the caller's namespace would fail, because it is a variable in the namespace passed to the caller. It might work? Don't know. Still the dict append sub-command needs to allow
    reference the dict data via de-reference, to make it
    simpler and more consistent. I have not tried the "set" sub-command, but if it is like you said, then
    it also needs to be able to refer to the dict element via de-referenced variable name.

    If I am not clear in my response, let me know.

    thanks for the help. I will say no more.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Lawrence Emke@21:1/5 to Lawrence Emke on Tue Apr 25 16:16:17 2023
    On Tuesday, April 25, 2023 at 4:27:39 PM UTC-5, Lawrence Emke wrote:
    On Tuesday, April 25, 2023 at 1:59:22 PM UTC-5, et99 wrote:
    On 4/25/2023 11:51 AM, saitology9 wrote:
    On 4/25/2023 2:26 PM, Lawrence Emke wrote:
    I understand the syntax to create a dict variable:
    set dname [ dict create a b ]
    Now compare these two commands:

    dict append dname d e
    and
    dict get $dname d

    in the first case the dict name does not require the de-reference $ character.
    In the second command it does require the deference $ character.

    This seems to be confusing. Don't force me to remember which case requires the de-reference $ character and which does not accept the $ character.

    Maybe there is a hidden explanation (reason) other than the implementation of the command that does not just pop up to a new student. Please make it consistent. It will save time and effort to learn the language syntax.

    I agree dict is hard to get used to.

    Think of dict not as some new data structure in Tcl but rather as an interface consisting of a set of commands that operate on lists with an even number of elements. In fact, I suspect that many dict use cases are on lists that happen to have this
    structure. You can use on any literal lists or variable that satisfies this condition.

    Under this light, the first one makes sense: you don't want to append to a literal list, i.e., a constant value. This will be like doing "5 = x + y" in C for example.

    The second makes sense too because it acts as a get-method on a list that has an even number of elements. You don't want to be forced into creating a temporary dict variable out of your normal lists just to get some elements out of it.




    Commands that modify an existing variable, are call by name
    if the variable's value is needed, then it's by value $value

    that's how I remember them. Similar to say, lappend, lset etc.
    which modify a current list are by name vs. lindex, lrange,
    which take a list and return a new one or part of one are by value.

    Incidentally, the dict append manual entry does not say that
    if the variable doesn't exist, then it is created first as
    an empty dict. But that is consistent with such commands as
    [incr]. And so too [dict incr] which also doesn't mention that
    a non existent key is treated as a 0 and then incremented.
    The problem is that the dict "name" is hard coded in the append command without the $ de-reference action. In the get sub command it must contain
    a reference variable syntax. If you switch the $ syntax on the both statements,
    neither statement executes correctly.

    My goal is to separate the application data namespace from the proc/methods. By that I mean, having all of the app data in one namespace and the methods in one or more other namespaces. I want to avoid little namespaces hanging off
    the applications data namespace. This means the dict append sub-command executed in a proc
    that receives the data via a parameter should use a reference to the dict structure rather than coding its name.
    The append sub-command needs receive the dict structure via a proc parameter variable. In this
    way the dict structure can be passed as a parameter. The unset sub-command takes either the DictName
    or a de-reference variable to the dict element. Both work. The same should be for the append sub-command

    I have tried several configurations in proc calls. None of them work. I have considered the
    level command. However, the actual dict structure may be a member of the caller's
    namespace. I assume in this situation, the search for the parameter in the caller's namespace would fail, because it is a variable in the namespace passed to the caller. It might work? Don't know. Still the dict append sub-command needs to allow
    reference the dict data via de-reference, to make it
    simpler and more consistent. I have not tried the "set" sub-command, but if it is like you said, then
    it also needs to be able to refer to the dict element via de-referenced variable name.

    If I am not clear in my response, let me know.

    thanks for the help. I will say no more.

    I found out how to do it. just place the name of the dict variable in a variable and pass that variable as the dict element name proc parameter. Then the "dict append $n a b" gets executed with the correct DictName

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From heinrichmartin@21:1/5 to Lawrence Emke on Wed Apr 26 00:32:47 2023
    On Wednesday, April 26, 2023 at 1:16:21 AM UTC+2, Lawrence Emke wrote:
    On 4/25/2023 2:26 PM, Lawrence Emke wrote:
    I understand the syntax to create a dict variable:
    set dname [ dict create a b ]
    Now compare these two commands:

    dict append dname d e
    and
    dict get $dname d

    in the first case the dict name does not require the de-reference $ character.
    In the second command it does require the deference $ character.

    This seems to be confusing. Don't force me to remember which case requires the de-reference $ character and which does not accept the $ character.
    I found out how to do it. just place the name of the dict variable in a variable and pass that variable as the dict element name proc parameter. Then the "dict append $n a b" gets executed with the correct DictName

    As you were looking at Tcl basics, maybe these comments help:
    * [set] is actually also a "get" when called with a single arg, i.e. [dict get [set $n] a] is the corresponding syntax to [dict append $n a b].
    * I am using the suffix "var" for "indirect variables" (similar to arg names of e.g. dict sub-commands), i.e. [dict get [set $nvar] a] but [dict get $n a].
    * Just to be sure: [dict append] appends a string to the existing value (or to the empty string if the key did not exist); [dict set] replaces the existing value.
    * Unifying the syntax of reading and writing sub-commands will not happen, because passing a value - that is not in a variable - is a valid use case when reading.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Wed Apr 26 10:55:09 2023
    * Lawrence Emke <[email protected]>
    | > I have tried several configurations in proc calls. None of them work. --<snip-snip>--
    | > If I am not clear in my response, let me know.

    Generally when asking for help, it is advisable to show what you have
    tried so far, what the results were, and what you expect them to
    be. (copy/paste the code, do *not* type it in the message again,
    copy/paste the results, do *not* paraphrase them in the message).

    That way another person might catch a coding error or suggest an
    alternate solution. You know it how it is: as soon as the administrator
    looks over your shoulder... ;-)

    HTH
    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Emiliano@21:1/5 to All on Wed Apr 26 15:35:41 2023
    El martes, 25 de abril de 2023 a las 15:26:20 UTC-3, Lawrence Emke escribió:
    I understand the syntax to create a dict variable:
    set dname [ dict create a b ]
    Now compare these two commands:

    dict append dname d e
    and
    dict get $dname d

    in the first case the dict name does not require the de-reference $ character.
    In the second command it does require the deference $ character.

    This seems to be confusing. Don't force me to remember which case requires the de-reference $ character and which does not accept the $ character.

    Maybe there is a hidden explanation (reason) other than the implementation of the command that does not just pop up to a new student. Please make it consistent. It will save time and effort to learn the language syntax.

    A good rule of thumb is that if the command has
    * "set" (set, unset, dict set, dict unset, array set, array unset, lset),
    * "append" (append, lappend, dict append, dict lappend)
    * "incr" (incr, dict incr)
    in its name, then it takes a *variable name* as argument.

    The "inconsistent" commands that break these "rules" are [array get], [dict update]
    and [dict with]. Also [lpop], which is a new command in the upcoming 8.7 release.

    Hope this helps

    Emiliano

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From et99@21:1/5 to Emiliano on Wed Apr 26 16:55:40 2023
    On 4/26/2023 3:35 PM, Emiliano wrote:
    El martes, 25 de abril de 2023 a las 15:26:20 UTC-3, Lawrence Emke escribió:
    I understand the syntax to create a dict variable:
    set dname [ dict create a b ]
    Now compare these two commands:

    dict append dname d e
    and
    dict get $dname d

    in the first case the dict name does not require the de-reference $ character.
    In the second command it does require the deference $ character.

    This seems to be confusing. Don't force me to remember which case requires the de-reference $ character and which does not accept the $ character.

    Maybe there is a hidden explanation (reason) other than the implementation of the command that does not just pop up to a new student. Please make it consistent. It will save time and effort to learn the language syntax.

    A good rule of thumb is that if the command has
    * "set" (set, unset, dict set, dict unset, array set, array unset, lset),
    * "append" (append, lappend, dict append, dict lappend)
    * "incr" (incr, dict incr)
    in its name, then it takes a *variable name* as argument.

    The "inconsistent" commands that break these "rules" are [array get], [dict update]
    and [dict with]. Also [lpop], which is a new command in the upcoming 8.7 release.

    Hope this helps

    Emiliano

    One of my favorite features about tcl is the console for doing
    testing. Nearly all (some exceptions) commands can provide a very
    useful 1 line summary as an error message. And to get a brief summary
    of subcommands, just enter the command and something like zzz.

    If it says ....Name then you supply the name of a variable. Easy Peasy.

    1 % dict append
    wrong # args: should be "dict append dictVarName key ?value ...?"
    2 % lappend
    wrong # args: should be "lappend varName ?value ...?"
    3 % lindex
    wrong # args: should be "lindex list ?index ...?"
    4 % dict
    wrong # args: should be "dict subcommand ?arg ...?"
    5 % dict zzz
    unknown or ambiguous subcommand "zzz": must be append, create, exists, filter, for, get, incr, info, keys, lappend, map, merge, remove, replace, set, size, unset, update, values, or with

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