Tcl Source Code

View Ticket
Login
2024-11-26
12:11
(cherry-pick): Bug [5a1aaa20]: lsearch -stride with -subindices and -inline -all gives unexpected re... check-in: 64cb91acdd user: jan.nijtmans tags: core-8-branch
2024-11-25
18:58 Closed ticket [5a1aaa201d]: lsearch -stride with -subindices and -inline -all gives unexpected result plus 7 other changes artifact: 590af72064 user: oehhar
18:56
Add bug [5a1aaa20] to changes.md check-in: d8e7d48397 user: oehhar tags: trunk, main
18:53
Bug [5a1aaa20]: lsearch -stride with -subindices and -inline -all gives unexpected result check-in: 57bafdc65d user: oehhar tags: trunk, main
2024-11-20
20:15 Ticket [5a1aaa201d] lsearch -stride with -subindices and -inline -all gives unexpected result status still Open with 3 other changes artifact: 8b6f38707a user: pooryorick
2024-11-18
17:58 Ticket [5a1aaa201d]: 4 changes artifact: 107fb81bc1 user: oehhar
17:56
Ticket [5a1aaa20]: adding tests (thanks Julian!) Closed-Leaf check-in: ab992d35ac user: oehhar tags: 5a1aaa20-lsearch-stride
17:04 Ticket [5a1aaa201d] lsearch -stride with -subindices and -inline -all gives unexpected result status still Open with 3 other changes artifact: 5504052c6d user: juliannoble2
16:20 Ticket [5a1aaa201d]: 3 changes artifact: ed2c0c31af user: oehhar
16:13 Ticket [5a1aaa201d]: 4 changes artifact: 078fad33e3 user: oehhar
16:03
Ticket [5a1aaa20] proposed solution by Julian Noble (Thanks !) check-in: 7274285f90 user: oehhar tags: 5a1aaa20-lsearch-stride
03:17 Ticket [5a1aaa201d] lsearch -stride with -subindices and -inline -all gives unexpected result status still Open with 3 other changes artifact: 36103342b0 user: juliannoble2
03:12 Add attachment tclCmdIL.patch to ticket [5a1aaa201d] artifact: 5cc18a131d user: juliannoble2
2024-11-13
03:41 Ticket [5a1aaa201d] lsearch -stride with -subindices and -inline -all gives unexpected result status still Open with 4 other changes artifact: 9285ffa5f8 user: juliannoble2
2024-11-11
12:07 New ticket [5a1aaa201d]. artifact: 9e69074750 user: juliannoble2

Ticket UUID: 5a1aaa201da8bd4ba2b37348c5247c98d192321e
Title: lsearch -stride with -subindices and -inline -all gives unexpected result
Type: Bug Version: 9.0
Submitter: juliannoble2 Created on: 2024-11-11 12:07:48
Subsystem: 17. Commands I-L Assigned To: nobody
Priority: 8 Severity: Important
Status: Closed Last Modified: 2024-11-25 18:58:30
Resolution: Fixed Closed By: oehhar
    Closed on: 2024-11-25 18:58:30
Description:
  %lsearch -stride 3 -index 0 -subindices -inline {a1 b1 c1 a2 b2 c2} a*
  a1

  %lsearch -stride 3 -index 0 -subindices -inline -all {a1 b1 c1 a2 b2 c2} a*
  a1 b1 c1 a2 b2 c2

If we omit the -inline flag the indices are as expected

  %lsearch -stride 3 -index 0 -subindices -all {a1 b1 cc1 a2 b2 c2} a*
  0 3

This second result is unexpected. (and gives the same result as with -subindices omitted)

Tip 351 example 5 indicates some level of consistency with the nested equivalent should be expected.

  %lsearch -index 0 -subindices -inline {{a1 b1 c1} {a2 b2 c2}} a*
  a1

  %lsearch -index 0 -subindices -inline -all {{a1 b1 c1} {a2 b2 c2}} a*
  a1 a2

The second result here is what I would have expected for the stridden version.

This makes certain operations with flattened lists harder to do. It can be worked around by using combinations of lseq, lmap etc instead of lsearch - but nothing seems as performant as a single lsearch -stride operation.

See my example code in bug https://core.tcl-lang.org/tcl/tktview/edebb6a4 regarding empty strings.
In that case - I had to artificially use an extra level of indices to extract what's required - and then ran headlong into that issue regarding empty string members (and also wrong results for members containing spaces)

One workaround I've used is to list protect every member of my flattened list - and then use the double index such as -index {0 0}
The additional prep overhead of doing something like: lmap v $list {list v} on a large list wipes out any performance gains from using lsearch -stride.
User Comments: oehhar added on 2024-11-25 18:58:30:

Merged by commit [57bafdc65d]. Thanks for the bug report, fix, test and review. Harald


pooryorick added on 2024-11-20 20:15:57:

So -inline -subindices is a search-and-extract operation. That makes sense. I've built and reviewed [ab992d35ac], and I think it's ready to be merged to trunk.


oehhar added on 2024-11-18 17:58:58:

Tests are now in with checkin [ab992d35ac].

IMHO, the patch looks good now.

Anybody may review ?

Remark, that this does not concern TCL 8.6, as "-stride" is not present.

Thanks for all, Harald


juliannoble2 added on 2024-11-18 17:04:41:
Thanks for trying this out Harald.
I propose the following tests:

  test lsearch-27.7 {lsearch -stride + -subindices option single index} {
      lsearch -inline -stride 3 -subindices -all -index 1  {{x a} {y b} {x c} {xx a} {xx b} {xx c} {xxx a} {y b} {xxx c}} {y b}
  } {{y b} {y b}}
  test lsearch-27.8 {lsearch -stride + -subindices option single index} {
      lsearch -inline -stride 3 -subindices -all -index end {{x a} {y b} {xc} {xx a} {xx b} {xx c} {xxx a} {y b} {}} *
  } {xc {xx c} {}}

oehhar added on 2024-11-18 16:13:50:

Julian, thank you for the patch. It is now with checkin [7274285f90] in branch [5a1aaa20-lsearch-stride], derived from main (tcl 9).

I tried your examples: Tcl 9.0.0:

% lsearch -stride 3 -index 0 -subindices -inline {a1 b1 c1 a2 b2 c2} a*
a1
% lsearch -stride 3 -index 0 -subindices -inline -all {a1 b1 c1 a2 b2 c2} a*
a1 b1 c1 a2 b2 c2
% lsearch -stride 3 -index 0 -subindices -all {a1 b1 c1 a2 b2 c2} a*
0 3

Branch [5a1aaa20-lsearch-stride]:

% lsearch -stride 3 -index 0 -subindices -inline {a1 b1 c1 a2 b2 c2} a*
a1
% lsearch -stride 3 -index 0 -subindices -inline -all {a1 b1 c1 a2 b2 c2} a*
a1 a2
% lsearch -stride 3 -index 0 -subindices -all {a1 b1 c1 a2 b2 c2} a*
0 3

This looks great and as the expected behavior.

Would you mind to author a test case?

Thank you and take care, Harald


juliannoble2 added on 2024-11-18 03:17:37:
Notes for attached patch:

patch for -stride -index -all -inline -subindices 

Only affects the case where there is a single element in -index 

#before 
  lsearch -stride 2 -index end -all -subindices -inline {a {sub a} b {sub b} c {etc c}} sub*
    a {sub a} b {sub b}

#after
  lsearch -stride 2 -index end -all -subindices -inline {a {sub a} b {sub b} c {etc c}} sub*
  {sub a} {sub b}

juliannoble2 added on 2024-11-13 03:41:51:
Aside from consistency with the nested equivalent, it's not self-consistent.

Another way of looking at this is that -all should always be equivalent to building the list by iterating using -start.

  lsearch -start 0 -stride 2  -index 1  -inline -subindices {abc abc abc bcd abc cde abc def} *c*
    abc

  lsearch -start 2 -stride 2  -index 1  -inline -subindices {abc abc abc bcd abc cde abc def} *c*
    bcd

  lsearch -start 4 -stride 2  -index 1  -inline -subindices {abc abc abc bcd abc cde abc def} *c*
    cde

  lsearch -all -start 0 -stride 2  -index 1  -inline -subindices {abc abc abc bcd abc cde abc def} *c*
    abc abc abc bcd abc cde

This should be: abc bcd cde
but it's returning each matched stride-group instead.

This result is already obtainable by omitting -subindices

  lsearch -all -start 0 -stride 2  -index 1  -inline {abc abc abc bcd abc cde abc def} *c*
    abc abc abc bcd abc cde


I'm not aware of any case other than with a single -index combined with -stride, -subindices -all where this inconsistency occurs.

There aren't many documented examples for -stride, and no test coverage for this specific case.
It took me a while to understand there was an inconsistency, and although the -stride option has been available for a while - I think with the release of Tcl 9 this should be high on the priority list.

Attachments: