From: Andreas L. <av...@lo...> - 2006-11-06 14:34:34
|
TIP #295: ENHANCE ARGUMENTS TO LRANGE ======================================= Version: $Revision: 1.1 $ Author: Andreas Leitgeb <avl_at_logic.at> State: Draft Type: Project Tcl-Version: 8.5 Vote: Pending Created: Monday, 06 November 2006 URL: http://purl.org/tcl/tip/295.html WebEdit: http://purl.org/tcl/tip/edit/295 Post-History: ------------------------------------------------------------------------- ABSTRACT ========== This TIP proposes an enhancement to *lrange* that lets it take more than one start-end index pair. RATIONALE =========== Sometimes you need to extract a non-continuous selection of elements from some list and build a new list from them. This requires the use of multiple calls to *lrange* and a surrounding *concat* to build the final list. However, since the following fails with a syntax error: lrange {a b c d e f} 1 3 5 5 It would seem a reasonable extension for such a usage of *lrange* to return "b c d f". This would also make following pattern of usage feasible: lassign [lrange $someList 0 2 10 12] var0 var1 var2 var10 var11 var12 The index-pairs should /not/ be required to be in ascending order (this might be difficult to determine when one index is end-relative), or even disjoint. Even: lrange {a b c d} 3 3 0 3 0 0 should be made legal and return "d a b c d a". PROPOSED CHANGE ================= Change the implementation of *lrange* to accept any odd number of arguments, with semantics (upon supply of a correct number of arguments) equivalent to: proc lrange-new {list args} { set result [list] foreach {start end} $args { lappend result {*}[lrange $list $start $end] } return $result } DRAFT IMPLEMENTATION ====================== Just the above mentioned procedure, at the moment. COPYRIGHT =========== This document has been placed in the public domain. ------------------------------------------------------------------------- TIP AutoGenerator - written by Donal K. Fellows |
From: Uwe K. <uwe...@fo...> - 2006-11-06 14:42:26
|
Should this support reverse ranges? ie. lrange $list end 0 for inverting a list? fixing/implementing list inversion from that other tip. what about enhancing string range in the same way? uwe -- Uwe Klein [mailto:uwe...@fo...] KLEIN MESSGERAETE Habertwedt 1 D-24376 Groedersby b. Kappeln, GERMANY phone: +49 4642 920 123 FAX: +49 4642 920 125 |
From: Joe E. <jen...@fl...> - 2006-11-06 15:42:33
|
Uwe Klein wrote: > Should this support reverse ranges? > > ie. lrange $list end 0 > for inverting a list? No. There are two ways to interpret [lrange $l $a $b] when $b < $a: return the elements from $b down to $a in reverse order (like you propose), or return the empty list (what Tcl currently does). Some languages do it the first way (Python does, IIRC), and that approach comes in handy in some circumstances. And the way Tcl does it *also* comes in handy, just in different circumstances. I know I've taken advantage of the fact that [lrange $l $a $b] returns the empty list when $b < $a at times; I also doubt that I'd ever be able to find all the places I've done so. This change would replace one useful property with a different, perhaps equally useful property, but at the cost of breaking code that currently relies on the first useful property. Not worth doing. --Joe English jen...@fl... |
From: Andreas L. <av...@lo...> - 2006-11-06 16:40:25
|
On Mon, Nov 06, 2006 at 03:42:06PM +0100, Uwe Klein wrote: > Should this support reverse ranges? No. Not these two TIPs. But I'd welcome an idea (for a third TIP) on how this could be done compatibly. > ie. lrange $list end 0 > for inverting a list? This surely not. :-( > what about enhancing string range in the same way? Yes, indeed, [string range] should be made analoguous to lrange wrt both TIPs 295 & 296. |
From: Uwe K. <uwe...@fo...> - 2006-11-06 16:55:39
|
Andreas Leitgeb wrote: > On Mon, Nov 06, 2006 at 03:42:06PM +0100, Uwe Klein wrote: > >>Should this support reverse ranges? > > > No. Not these two TIPs. > > But I'd welcome an idea (for a third TIP) on how this could > be done compatibly. > > >>ie. lrange $list end 0 >>for inverting a list? > > > This surely not. :-( call it [lselect] and [string select] and allow enumeration, ranges ( forward | reverse ) ? > > >>what about enhancing string range in the same way? > > > Yes, indeed, [string range] should be made analoguous > to lrange wrt both TIPs 295 & 296. uwe |
From: Donald G P. <dg...@ni...> - 2006-11-06 16:44:48
|
Andreas Leitgeb wrote: > On Mon, Nov 06, 2006 at 03:42:06PM +0100, Uwe Klein wrote: >> Should this support reverse ranges? > > No. Not these two TIPs. > > But I'd welcome an idea (for a third TIP) on how this could > be done compatibly. Did you miss TIP 272? -- | Don Porter Mathematical and Computational Sciences Division | | don...@ni... Information Technology Laboratory | | http://math.nist.gov/~DPorter/ NIST | |______________________________________________________________________| |
From: Uwe K. <uwe...@fo...> - 2006-11-06 17:07:26
|
Donald G Porter wrote: > Andreas Leitgeb wrote: > >> On Mon, Nov 06, 2006 at 03:42:06PM +0100, Uwe Klein wrote: >> >>> Should this support reverse ranges? >> >> >> No. Not these two TIPs. >> >> But I'd welcome an idea (for a third TIP) on how this could >> be done compatibly. > > > Did you miss TIP 272? as it is this would then be 3 tips 272 List and String Reversal 295 Allow multiple pairs of arguments for lrange (and string range ?) end < start indices will return an empty {list|string} xxx Allow multiple pairs of arguments for lrange (and string range ?) end < start will return items in reversed order. what about nixing 272 and replace them with what TIP xxx would provide lselect $list {end 0} ~= lreverse $list string select $string {0 end} ~ string reverse $string uwe |
From: Andreas L. <av...@lo...> - 2006-11-06 17:19:06
|
On Mon, Nov 06, 2006 at 05:52:05PM +0100, Uwe Klein wrote: > Andreas Leitgeb wrote: > >But I'd welcome an idea (for a third TIP) on how this could > >be done compatibly. > call it [lselect] and [string select] and allow > enumeration, ranges ( forward | reverse ) ? Reversing indices imho only makes sense, if the ranges were specified as to exclude the end-index: If start==end were to mean the empty selection, then start>end naturally lent itself for reversal, but this doesn't work out for "inclusive-end" ranges. The other way round, if new [lselect] and [string select] specified to be "exclusive-end", then reversing was ok, but then they would be alien to tcl. :-( I do, however, understand that it would be a useful feature, even in addition to already-"yes"-voted Tip 272. perhaps a "step" appended after a slash to the end-index, as in: lrange 0 end/2 --> only every second element lrange $list end 0/-1 --> lreverse was a clean way, but unfortunately also quite an ugly one. PS: forward my message to tcl-core, or full-quote me upon reply-to-all. |
From: Uwe K. <uwe...@fo...> - 2006-11-06 17:59:32
|
Andreas Leitgeb wrote: > On Mon, Nov 06, 2006 at 05:52:05PM +0100, Uwe Klein wrote: > >>Andreas Leitgeb wrote: >> >>>But I'd welcome an idea (for a third TIP) on how this could >>>be done compatibly. >> >>call it [lselect] and [string select] and allow >>enumeration, ranges ( forward | reverse ) ? > > > Reversing indices imho only makes sense, if the ranges were > specified as to exclude the end-index: > > If start==end were to mean the empty selection, then > start>end naturally lent itself for reversal, but this > doesn't work out for "inclusive-end" ranges. isn't every range used in tcl "inclusive-end" ? I'd not deviate from that. > noninclusive-end would lead to some funnies like lselect $list {5 6} {18 end} end some other point l<dwim> $list end-2 2 could well mean the outer elements i.e end-2 end-2 end 0 1 2 but this could well be expressed with lselect {end-2 end} {0 2} > The other way round, if new [lselect] and [string select] specified > to be "exclusive-end", then reversing was ok, but then they would > be alien to tcl. :-( > > I do, however, understand that it would be a useful feature, > even in addition to already-"yes"-voted Tip 272. > > perhaps a "step" appended after a slash to the end-index, as in: > lrange 0 end/2 --> only every second element > lrange $list end 0/-1 --> lreverse hello cron, new outfit? > was a clean way, but unfortunately also quite an ugly one. > > PS: forward my message to tcl-core, or full-quote me upon reply-to-all. > I need to think about this some. uwe |
From: Arjen M. <arj...@wl...> - 2006-11-06 18:18:33
|
>> >> I do, however, understand that it would be a useful feature, >> even in addition to already-"yes"-voted Tip 272. >> >> perhaps a "step" appended after a slash to the end-index, as in: >> lrange 0 end/2 --> only every second element >> lrange $list end 0/-1 --> lreverse > hello cron, new outfit? >> was a clean way, but unfortunately also quite an ugly one. >> What about: lrange $list [list $start $stop $step] where step defines both the step size and direction: - It defaults to 1 - A value of 0 is not allowed - If stop-start is of a different sign than step, the result is empty - If stop-start is of the same sign, the result is at least one element long This can be extended to several ranges and the current syntax is preserved as: lrange $list $start $stop which can also be written: lrange $list [list $start $stop] (Yes, this does resemble the do/for-loops syntax in languages like Fortran) Regards, Arjen |
From: Andreas L. <av...@lo...> - 2006-11-06 18:52:56
|
On Mon, Nov 06, 2006 at 07:19:00PM +0100, Arjen Markus wrote: > What about: > lrange $list [list $start $stop $step] Except for the additional list-level (which I rather dislike, because it means lots of [list]ing in practise), this is a good idea: Actually, as of now, lrange list start end doesn't forbid us to extend it an even different way: lrange list start1 end1 step1 start2 end2 step2 ... Or, what if some yet-to-be-chosen char (':' for now) separated the individual range-specs, which then could be either: one index: for single element, two indices: for a range, three elements: for a stepped range [llength [lrange $list 1 : 4 5 : 6 4 -1]] == 6 Specification for step: > - It defaults to 1 > - A value of 0 is not allowed > - If stop-start is of a different sign than step, the result is empty > - If stop-start is of the same sign, the result is at least one element long add "or 0" to the 4th line, before the comma. Alternatives to colon: '|', '/' (I would strongly discourage the comma, because it is too likely appended to the previous arg, rather than used as a separate one) |
From: Andreas L. <av...@lo...> - 2006-11-06 18:18:23
|
On Mon, Nov 06, 2006 at 06:58:41PM +0100, Uwe Klein wrote: > >Reversing indices imho only makes sense, if the ranges were > >specified as to exclude the end-index: > isn't every range used in tcl "inclusive-end" ? > I'd not deviate from that. Yes! And that's the very reason, why I don't like to use index-reversal for list/string reversal in tcl. > >perhaps a "step" appended after a slash to the end-index, as in: > > lrange 0 end/2 --> only every second element > > lrange $list end 0/-1 --> lreverse > >was a clean way, but unfortunately also quite an ugly one. > hello cron, new outfit? :-) you guessed right as to the motivation for "/" :-) PS: now, I'm subscribed to tcl-core. :-) PPS: in your examples you often brace-enclose these pairs of indices. This is *not* how lrange&co do it. Is this how you would like lselect to be, or is this just a typo ? |
From: Uwe K. <uwe...@fo...> - 2006-11-06 20:28:47
|
Andreas Leitgeb wrote: > On Mon, Nov 06, 2006 at 06:58:41PM +0100, Uwe Klein wrote: > >>>Reversing indices imho only makes sense, if the ranges were >>>specified as to exclude the end-index: > > >>isn't every range used in tcl "inclusive-end" ? >>I'd not deviate from that. > > > Yes! And that's the very reason, why I don't like to > use index-reversal for list/string reversal in tcl. i might be dense but i do not see your problem > > >>>perhaps a "step" appended after a slash to the end-index, as in: >>>lrange 0 end/2 --> only every second element >>>lrange $list end 0/-1 --> lreverse >>>was a clean way, but unfortunately also quite an ugly one. > > >>hello cron, new outfit? > > > :-) you guessed right as to the motivation for "/" :-) the problem here is to stay in style. we might go to perl-hell if we furnish a new selection language at every new place where we come across the need to have one. > > PS: now, I'm subscribed to tcl-core. :-) I am tickled pink to meet you! > > PPS: in your examples you often brace-enclose these pairs of > indices. This is *not* how lrange&co do it. Is this how you > would like lselect to be, or is this just a typo ? want, not typo think of requesting nonconsecutive items from a list lxinedex $list 0 0 3 3 5 5 7 7 9 9 20 30 end end ;# hoho, hoha, they are coming for you, haha lselect $list 0 2 5 6 9 {20 30} end ;# a drink in the eve makes you grin like a thieve. uwe |
From: Andreas L. <av...@lo...> - 2006-11-07 17:41:38
|
On Mon, Nov 06, 2006 at 09:28:25PM +0100, Uwe Klein wrote: > >>isn't every range used in tcl "inclusive-end" ? > >>I'd not deviate from that. > >Yes! And that's the very reason, why I don't like to > >use index-reversal for list/string reversal in tcl. > i might be dense but i do not see your problem Ok. 1.) Tcl philosophy demands, that twice the same index gives that one index'th element. 2.) My own sense for consistency demands, that consequentially {n n-1} would have to give an empty list. 3.) to extend this further, the reversed list would turn out to have to exclude both ends: e.g. {6 3} would then mean the 5th and 4th element. I don't think I could really verbally defend my sense for consistency, but I still think it makes sense ;-) Any other definition negating points 2 and 3, leads to what you have suggested, which would mean that "empty result" can not be specified through indices anymore. This may or may not be seen as a problem, I choose to see it as a problem :-) |