• Re: Strange behaviour of [dict exists]

    From Steve Bennett@21:1/5 to Alan Grunwald on Thu Jul 28 15:04:22 2022
    % dict exists foo garp
    missing value to go with key

    Maybe you inadvertently caught the exception

    On Friday, July 29, 2022 at 7:37:42 AM UTC+10, Alan Grunwald wrote:
    I've spent several not-so-happy hours today searching for a bug caused
    by someone doing

    [dict exists foo garp]

    instead of

    [dict exists $foo garp]

    I'm surprised that the former code works since, for example [dict get
    foo] and [dict size foo] throw an exception if you miss out the dollar
    sign. Is this a bug? If not, what benefit does this anomalous behaviour
    of [dict exists] bring with it?

    Thanks.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alan Grunwald@21:1/5 to All on Thu Jul 28 22:37:16 2022
    I've spent several not-so-happy hours today searching for a bug caused
    by someone doing

    [dict exists foo garp]

    instead of

    [dict exists $foo garp]

    I'm surprised that the former code works since, for example [dict get
    foo] and [dict size foo] throw an exception if you miss out the dollar
    sign. Is this a bug? If not, what benefit does this anomalous behaviour
    of [dict exists] bring with it?

    Thanks.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Christian Gollwitzer@21:1/5 to All on Fri Jul 29 00:33:52 2022
    Am 29.07.22 um 00:04 schrieb Steve Bennett:
    % dict exists foo garp
    missing value to go with key

    Maybe you inadvertently caught the exception


    (chris) 50 % info patchlevel
    8.6.9
    (chris) 51 % dict exists foo garp
    0


    What is your patchlevel?

    Christian

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From apn@21:1/5 to Alan Grunwald on Fri Jul 29 06:27:29 2022
    On 7/29/2022 3:07 AM, Alan Grunwald wrote:
    I've spent several not-so-happy hours today searching for a bug caused
    by someone doing

            [dict exists foo garp]

    instead of

            [dict exists $foo garp]

    I'm surprised that the former code works since, for example [dict get
    foo] and [dict size foo] throw an exception if you miss out the dollar
    sign. Is this a bug? If not, what benefit does this anomalous behaviour
    of [dict exists] bring with it?

    Thanks.

    See https://core.tcl-lang.org/tcl/tktview/3598385fffffffffffff for the discussion on this. fwiw

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Steve Bennett on Fri Jul 29 02:27:24 2022
    Steve Bennett <[email protected]> wrote:
    On Friday, July 29, 2022 at 7:37:42 AM UTC+10, Alan Grunwald wrote:
    I've spent several not-so-happy hours today searching for a bug caused
    by someone doing

    [dict exists foo garp]

    instead of

    [dict exists $foo garp]

    I'm surprised that the former code works since, for example [dict get
    foo] and [dict size foo] throw an exception if you miss out the dollar
    sign. Is this a bug? If not, what benefit does this anomalous behaviour
    of [dict exists] bring with it?

    Thanks.

    % dict exists foo garp
    missing value to go with key

    Maybe you inadvertently caught the exception

    On 8.6.11 I get what the OP reported:

    $ rlwrap tclsh
    % set tcl_patchLevel
    8.6.11
    % dict exists foo garp
    0
    %

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Steve Bennett@21:1/5 to Rich on Fri Jul 29 00:59:06 2022
    Fair enough. IMHO they broke it.
    Jim Tcl is staying with the old way. What the OP reports is definitely a common scenario.

    On Friday, July 29, 2022 at 12:27:28 PM UTC+10, Rich wrote:
    Steve Bennett <[email protected]> wrote:
    On Friday, July 29, 2022 at 7:37:42 AM UTC+10, Alan Grunwald wrote:
    I've spent several not-so-happy hours today searching for a bug caused
    by someone doing

    [dict exists foo garp]

    instead of

    [dict exists $foo garp]

    I'm surprised that the former code works since, for example [dict get
    foo] and [dict size foo] throw an exception if you miss out the dollar
    sign. Is this a bug? If not, what benefit does this anomalous behaviour
    of [dict exists] bring with it?

    Thanks.

    % dict exists foo garp
    missing value to go with key

    Maybe you inadvertently caught the exception
    On 8.6.11 I get what the OP reported:

    $ rlwrap tclsh
    % set tcl_patchLevel
    8.6.11
    % dict exists foo garp
    0
    %

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Alan Grunwald@21:1/5 to apn on Fri Jul 29 12:00:39 2022
    On 29/07/2022 01:57, apn wrote:
    On 7/29/2022 3:07 AM, Alan Grunwald wrote:
    I've spent several not-so-happy hours today searching for a bug caused
    by someone doing

             [dict exists foo garp]

    instead of

             [dict exists $foo garp]

    I'm surprised that the former code works since, for example [dict get
    foo] and [dict size foo] throw an exception if you miss out the dollar
    sign. Is this a bug? If not, what benefit does this anomalous
    behaviour of [dict exists] bring with it?

    Thanks.

    See https://core.tcl-lang.org/tcl/tktview/3598385fffffffffffff for the discussion on this. fwiw

    Thanks for pointing me at the ticket(s).

    To attempt to answer my second question, the benefit appears to come
    with nested dictionaries. The current implementation allows you to
    wander around such dictionaries when you don't know how deeply nested it is.

    I think that's going to be helpful less often than people forgetting the
    dollar sign, but YMMV.

    May I take some hope from the fact that the resolution is "Wont fix"
    rather than something like "Not a bug"?

    For my money the solution would be for [dict exists] to throw an error
    and there to be a [string is dict] command, as suggested by mistachkin
    on 2012-12-27 in a comment on the ticket.

    FWIW I also agree completely with Donal that thrashing backward and
    forward is unhelpful.

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From heinrichmartin@21:1/5 to Alan Grunwald on Fri Jul 29 04:45:45 2022
    On Friday, July 29, 2022 at 1:01:01 PM UTC+2, Alan Grunwald wrote:
    May I take some hope from the fact that the resolution is "Wont fix"
    rather than something like "Not a bug"?

    For my money the solution would be for [dict exists] to throw an error
    and there to be a [string is dict] command, as suggested by mistachkin
    on 2012-12-27 in a comment on the ticket.

    FWIW I also agree completely with Donal that thrashing backward and
    forward is unhelpful.

    Let me second all that. Throwing an error for invalid data is consistent.
    Imho, https://core.tcl-lang.org/tcl/info/3475264 should have been a TIP (and should probably have been declined).

    "[...] sort out between yourselves what it should be and I'll willingly make it work that way if it doesn't already. Until then, this issue stays closed."

    Independent reporters found this regression in 2012, 2018, and 2022 along with many supporters and hardly anyone opposing; is this representative?
    Without any hidden meaning: what is the expected process (medium and decision criteria) to continue?

    On 7/29/2022 3:07 AM, Alan Grunwald wrote:
    I've spent several not-so-happy hours today searching for a bug caused
    by someone doing

    [dict exists foo garp]

    instead of

    [dict exists $foo garp]


    We have very basic code checkers in place to fail fast. "Basic" refers to "not a full Tcl parser". I cannot paste the full file, but basically I am using regular expressions with sed.

    ...
    # regexp of suspicious code
    # \x24 ... $ (prevent a match in this file known_pitfalls.tcl)
    # \x61 ... a (prevent a match in this file known_pitfalls.tcl)
    # \< ... beginning of a word
    # \> ... end of a word
    set forbidden {
    # for variable names true and false use ${true} and ${false} respectively
    {\x24false\>\|\x24true\>}
    # use return "result" if you really mean it
    {\<return \+result\>}
    # very common spelling mistakes
    {\<\x61dress\>}
    {\<\(Res\|res\|S\|s\)etted\>}
    # string's subcommand concat does not exist in Tcl, was string cat intended?
    {\<string \+concat }
    # these procedures use variable names (override with ${name})
    {\<dict \+\(set\|incr\|append\|lappend\|unset\|update\|with\) \+\$\(\w\|:\)\+}
    {\<\(set\|incr\|append\|lappend\|unset\|vwait\|lset\|info \+exists\|info \+vars\) \+\$\(\w\|:\)\+}
    {::struct::set \+\(include\|exclude\|add\|subtract\) \+\$\(\w\|:\)\+}
    # these procedures take values (use braces)
    {\<dict \+\(get\|exists\|filter\|info\|keys\|merge\|remove\|replace\|size\|values\) \+[^\$\{\[ ][^ ]*}
    {\<\(lreplace\|lassign\|lindex\|linsert\|llength\|lrange\|lreplace\|lreverse\) \+[^\$\{\[ ][^ ]*}
    {::struct::set \+\(empty\|size\|contains\|union\|difference\|symdiff\|intersect3\) \+[^\$\{\[ ][^ ]*}
    # always use the optional argument level, default is 1
    {\<up\(var\|level\) \+[^$#0-9\\]}
    }
    ...
    # erase commented lines in data
    set forbidden [join [regsub -all -line {^\s*#.*$} $forbidden {}] {\|}]
    set deprecated [join [regsub -all -line {^\s*#.*$} $deprecated {}] {\|}]
    set sed [format {
    # find suspicious code in single line
    s/^ *\([0-9]\+\)\t.*\(%s\).*$/\1: suspicious looking code {\2}/p;t
    # if not suspicious, check for deprecated procs
    s/^ *\([0-9]\+\)\t\(\|.*;\|.*\[\|.*%s\) *\(%s\) .*$/\1: DEPRECATED proc {\3}/p;t
    # if not deprecated, check with the previous line (in hold buffer)
    H;x
    # indentation when closing nested blocks
    s/^ *\([0-9]\+\)\t\( *\}\)\n *\([0-9]\+\)\t\2/\1-\3: suspicious looking code {equal indentation at end of block}/p;t
    } $forbidden \{ $deprecated]
    ...
    # - print line numbers
    set result [split [exec cat -n $argv | sed -n $sed] \n]
    ...

    Maybe that helps someone :-)

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