Tcl Source Code

View Ticket
Login
Ticket UUID: bc4ac0dd5f4c87677ea45fb5b480894630e3c5fb
Title: lsearch -sorted -inline -subindices incorrect result
Type: Bug Version: 9.0
Submitter: juliannoble2 Created on: 2024-11-18 16:10:19
Subsystem: 17. Commands I-L Assigned To: nobody
Priority: 5 Medium Severity: Minor
Status: Open Last Modified: 2024-11-18 18:01:16
Resolution: None Closed By: nobody
    Closed on:
Description:
I've marked this as minor because the -inline -subindices result is often not particularly useful.

It might be worth addressing because:
a) -inline is a handy way to debug or try to understand/verify what is going on and the incorrect results shown below can be confusing
b) Example 2 below is a possibly valid usecase - although somewhat contrived.
c) The underlying cause isn't clear to me - and possibly indicative of some deeper problem

  ##  example 1 (of no practical use anyway)
  #correct result
  lsearch -sorted -subindices -inline -index 0 {{a 1} {a 2} {b 3} {c 4}} b
  b 
  #incorrect result with an extra list member
  lsearch -sorted -subindices -inline -index 0 {{a 1} {a 2} {b 3} {c 4} {c 5}} b
  a


  ## example 2
  #list of real values with different precision - attempt to retrieve value to see number of decimal places
  lsearch -real -sorted -inline -index 0 -subindices {{1.0 one} {2.0 two} {3.000 three} {4.00 four} {5.0 five} {6.000 six}} 1
  1.0
  lsearch -real -sorted -inline -index 0 -subindices {{1.0 one} {2.0 two} {3.000 three} {4.00 four} {5.0 five} {6.000 six}} 2
  2.0
  #surprising result
  lsearch -real -sorted -inline -index 0 -subindices {{1.0 one} {2.0 two} {3.000 three} {4.00 four} {5.0 five} {6.000 six}} 3
  2.0
  lsearch -real -sorted -inline -index 0 -subindices {{1.0 one} {2.0 two} {3.000 three} {4.00 four} {5.0 five} {6.000 six}} 4
  4.00
  #another suprising result
  lsearch -real -sorted -inline -index 0 -subindices {{1.0 one} {2.0 two} {3.000 three} {4.00 four} {5.0 five} {6.000 six}} 5
  4.00
  lsearch -real -sorted -inline -index 0 -subindices {{1.0 one} {2.0 two} {3.000 three} {4.00 four} {5.0 five} {6.000 six}} 6
  6.000
User Comments: oehhar added on 2024-11-18 18:01:16:

Thanks, Sebres, I see. Sorry for the stupid words. It is all so complicated...

Thanks, Harald


sebres added on 2024-11-18 17:56:53:

And it would break a use case I often use ;-(

Well, it'd not (directly): you just not need to use -subindices together with -inline (see example at end), it was never anticipated to use it in this way (since the option -subindices was only considered without -inline), so one can consider it as a regression, but rather it is consistent now and it was just never documented and rather unexpected previously.

Now since -stride and -subindices (with -inline) is considered to be documented (and TIPed) behaviour, it also affected -inline without -stride.

I guess it is expected behaviour now (and better now), but needs to be fixed in any case (to return correct sub-element).

I'll fix it soon...

Back to your particular example, you have to use it simply without -subindices (since it was and is a bit unexpected):

- set help [lindex [lsearch -index 0 -inline -subindices $helplist $switch] 1]
+ set help [lindex [lsearch -index 0 -inline $helplist $switch] 1]

Of course this will belong to the migration notes too.


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

Sebres,

thanks for the comment and that you engage yourselft, great !

I would call it a big incompatibility, if -inline -subindices in 8.6 would return the top list item and the sub list item in TCL 9.

And it would break a use case I often use ;-(

Thanks anyway, Harald


juliannoble2 added on 2024-11-18 17:37:14:
I tried some 8.7 bawt distributions..

8.7a1 behaves as you describe for 8.6
8.8a5 shows the bug the same as 9

>And also your mentioned correct ones are incorrect, as only the first sublist item is returned and not the whole sublist.

I think that the whole sublist should only be returned if you drop the -subindices option
Without the -subindices option - the bug doesn't appear though



Regarding your example - I don't think you should be using the -subindices option there.
On 8.6 you get the same result with or without -subindices and I believe that with -subindices it should return only the matched portion as it does on 9

This another of the reasons I'd like to see some of these things tidied up. Reading the docs is one thing - but I've occasionally (mis)learned some of the behaviour by experimentation. Sometimes I've used constructs that I've only later realised were only necessary because of a bug. 
(e.g I was using a double index where it should have only required one)

The error only occurs with both -sorted and -subindices - 
e.g 
  lsearch -index 0 -inline -sorted -subindices  {{-con "show console"} {-log "set log level"} {-zzz "blah ok"}} -log
  -con

As this search only returns (when it works!) what you were searching for anyway - that's why I think it's not all that useful aside from my contrived example

sebres added on 2024-11-18 17:30:31:

Option -subindices didn't matter by -inline in 8.6, it was only important if lsearch returns indices (without -subindices it'd return the index of element, with it'd return the index of found sub-element). With -inline the option won and the return value was always the whole element itself. I guess it was "repaired" in 8.7 in order to return sub-element only, so it may be expected now, but then the second case is anyway wrong (found 2.0 instead of 3.000 by search for 3). Without -inline it looks correct.

The blame shows [7ac44158fa45398f] (TIP 351 Implementation) as candidate, however then I'm unsure it is intended (basically the TIP was only about -stride option).


oehhar added on 2024-11-18 16:28:32:

I tried your example with TCL 8.6. The result is quite different:

  • the whole item is returned "b 3", not only "b"
  • the right one is returned

So, this is a tcl 9 only bug.

And also your mentioned correct ones are incorrect, as only the first sublist item is returned and not the whole sublist.

tcl 8.6:

% lsearch -sorted -subindices -inline -index 0 {{a 1} {a 2} {b 3} {c 4} {c 5}} b
b 3

I suppose, the code was optimized to return the found item emideately but did not take into account, that this is not the total item.

And I don't see this as not useful. I often use this as a lookup method like this:

% set switch "-con"
% set helplist {{-con "Show console"} {-log "Set log level"}
# set help [lindex [lsearch -subindices -index 0 -inline $helplist $switch] 1]


oehhar added on 2024-11-18 16:19:01:

Thanks for debugging this. The answer is wrong and should be fixed.

Harald