Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

Why does 'reverse returns the tail of the block?

 [1/9] from: al::bri::xtra::co::nz at: 12-Nov-2002 16:31


Jan wrote:
> > worst of all 'reverse, which returns empty block.
Gabriele wrote:
> I don't know why REVERSE returns the tail of the block. You can use
HEAD REVERSE in expressions,... I suspect that 'reverse returns the 'tail of the block, because to return the 'head of the block could be wrong, if one is 'reverse-ing only part of a block? For example:
>> reverse next x: [1 2 3 4 5]
== []
>> x
== [1 5 4 3 2] Though I'm not sure why one would want to only reverse part of a block (or series)? Andrew Martin ICQ: 26227169 http://valley.150m.com/

 [2/9] from: brett:codeconscious at: 12-Nov-2002 17:41


> I suspect that 'reverse returns the 'tail of the block, because to return > the 'head of the block could be wrong, if one is 'reverse-ing only part of
a
> block? For example:
Probably a little more accurate to say that reverse returns the tail of the changed sequence. Having reverse return a modified series reference probably gives a little more info than just returning the original series reference, especially when you include the /PART refinement:
>> s2: reverse/part at s1: [1 2 3 4 5] 2 3
== [5]
>> s1
== [1 4 3 2 5]
>> s2
== [5]
> Though I'm not sure why one would want to only reverse part of a block (or > series)?
Insert, Change, Remove, Find, Copy, Uppercase all have a part sequence effect - seems reasonable for REVERSE to have one too :^) Regards, Brett.

 [3/9] from: g:santilli:tiscalinet:it at: 12-Nov-2002 12:39


Hi Andrew, On Tuesday, November 12, 2002, 4:31:00 AM, you wrote: AM> I suspect that 'reverse returns the 'tail of the block, because to return AM> the 'head of the block could be wrong, if one is 'reverse-ing only part of a AM> block? For example: Indeed, it could be useful to chain two or more REVERSE/PART:
>> x: [1 2 3 4 5 6]
== [1 2 3 4 5 6]
>> reverse/part reverse/part reverse/part x 2 2 2
== []
>> x
== [2 1 4 3 6 5] However, maybe it is more common to have it chained with other functions, where returning the series at the same position as the argument would be more useful. What do you think? Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [4/9] from: brett:codeconscious at: 13-Nov-2002 0:07


> However, maybe it is more common to have it chained with other > functions, where returning the series at the same position as the > argument would be more useful. What do you think?
If someone wants to chain it why not define a chainable reverse?
>> reverse0: func [value][reverse value value] >> reverse0 s: [ 1 2 3 4]
== [4 3 2 1] Regards, Brett.

 [5/9] from: joel:neely:fedex at: 12-Nov-2002 7:04


Hi, Andrew, Another wild guess below... Andrew Martin wrote:
> Jan wrote: > > > worst of all 'reverse, which returns empty block.
<<quoted lines omitted: 4>>
> to return the 'head of the block could be wrong, if one is > 'reverse-ing only part of a block?
But those aren't the only two options! IMHO the more intuitive thing would be to return a block reference positioned at the same place as the beginning of the reversed sequence (see below for example). I'm inclined to wonder whether the resulting value is merely an artifact of the way REVERSE is implemented, rather than being carefully chosen for some strategic purpose.
> For example: > > >> reverse next x: [1 2 3 4 5] > == [] > >> x > == [1 5 4 3 2] >
In the variation I'd advocate, your example would behave as the following *H*Y*P*O*T*H*E*T*I*C*A*L* case
>> reverse next x: [1 2 3 4 5]
== [5 4 3 2]
>> x
== [1 5 4 3 2] As it is, we can get roughly the equivalent behavior only at the cost of some extra typing ...
>> reverse y: next x: [1 2 3 4 5]
== []
>> y
== [5 4 3 2] ... to preserve the position of the series (sub-) reference. REBOL seems in general to follow the principle of returning results that are most likely to be useful in a larger expression (e.g. INSERT returns a reference *after* the inserted content, making it easy to "chain" insertions into a single expression). That principle is broken here IMHO as every use I can recall making of REVERSE falls into one of two categories: 1) Imperative - purely for effect, in which case I don't *care* how the resulting value is positioned, or 2) In-line - needing to perform some additional manipulation on the result, in which case I *always* have to write the equivalent of ... head reverse ... to get back to the beginning of the REVERSEd content. I'd much rather have REVERSE return a preserved position.
> Though I'm not sure why one would want to only reverse part of > a block (or series)? >
Most (all?) operations on series values respect the current position within the underlying sequence. Consistency with that rule is A Good Thing IMHO. A specific example of how this could be used is the "line breaking" problem: given an ordered collection of values and a position within the collection, bring the value at that position to the "front of the line" without disturbing the relative order of the rest of the values in the collection. An obvious approach is to insert the designated value (i.e. the value at the designated position) into the front of the line, and remove it from its previous place. This is easy to write: breakline-ins-rem: func [ s [series!] p [integer!] ][ head remove at insert s pick s p p ] It behaves as specified ...
>> breakline-ins-rem [1 2 3 4 5 6 7 8 9] 4
== [4 1 2 3 5 6 7 8 9] ... but we know that INSERTing and REMOVEing (in blocks with many values following the point of action) can be expensive. A subtler approach can be designed as follows: - REVERSEing a subseries at the beginning will put the desired element at the head of the line, but will mess up the relative order of the values that were before it:
>> head reverse/part [1 2 3 4 5 6 7 8 9] 4
== [4 3 2 1 5 6 7 8 9] - We can prevent that by REVERSEingthe *preceding* values first, and then REVERSEing the entire leading subseries:
>> head reverse/part [1 2 3 4 5 6 7 8 9] 3
== [3 2 1 4 5 6 7 8 9]
>> head reverse/part [3 2 1 4 5 6 7 8 9] 4
== [4 1 2 3 5 6 7 8 9] This gives us another design ... breakline-rev-rev: func [ s [series!] p [integer!] ][ head reverse/part head reverse/part s p - 1 p ] ... which only manipulates the part of the series that actually needs to change! This latter version can be *much* faster, depending on the length of the series and how close the desired position is to the front. -jn- -- ; Joel Neely joeldotneelyatfedexdotcom REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] { | e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]

 [6/9] from: rotenca:telvia:it at: 12-Nov-2002 15:13


Hi all, it seems to me always the same behaviour:
>> reverse/part next b: [0 1 2 3] 2
== [3]
>> remove/part next b: [0 1 2 3] 2
== [3]
>> change/part next b: [0 1 2 3] [a a] 2
== [3] Rebol returns the end of the changed/removed/inserted/reversed part of series, if the part is all the serie, then it returns the tail of serie. --- Ciao Romano

 [7/9] from: joel:neely:fedex at: 12-Nov-2002 10:51


Hi, Gabriele, Gabriele Santilli wrote:
> However, maybe it is more common to have it chained with other > functions, where returning the series at the same position as the > argument would be more useful. What do you think? >
I agree with preserving the position in the value yielded by REVERSE as I think that's the most likely value to be relevant in a larger expression. It would be really interesting to examine a reasonably-sized sample of REBOL scripts to see how often REVERSE is preceded by HEAD. -jn- -- ---------------------------------------------------------------------- Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446

 [8/9] from: g:santilli:tiscalinet:it at: 12-Nov-2002 20:41


Hi Romano, On Tuesday, November 12, 2002, 3:13:27 PM, you wrote: RPT> Rebol returns the end of the changed/removed/inserted/reversed part of series, RPT> if the part is all the serie, then it returns the tail of serie. Indeed, but while this is very useful for CHANGE, REMOVE and INSERT, it is not that useful for REVERSE, IMHO. Anyway, there are cases where the current behavior of REMOVE is useful, so I'm not saying that it is broken. Regards, Gabriele. -- Gabriele Santilli <[g--santilli--tiscalinet--it]> -- REBOL Programmer Amigan -- AGI L'Aquila -- REB: http://web.tiscali.it/rebol/index.r

 [9/9] from: jeff:rebol at: 12-Nov-2002 16:15


<[3DCEBE3E--2DDAC72--sympatico--ca]> <[1822275075--20021111113147--tiscalinet--it]> <006f01c289fb$ec2109e0$[4a6036d2--Garfield]> <[892917909--20021112123948--tiscalinet--it]> Howdy, Gabriele:
> Indeed, it could be useful to chain two or more > REVERSE/PART:
<<quoted lines omitted: 4>>
> >> x > == [2 1 4 3 6 5]
As your example suggests, REBOL series functions always return the end of the "affected area" because this might be the result of some computed operation. Always returning the head (or the current series index) would throw away the important information of the affected index. Salutations! -jeff

Notes
  • Quoted lines have been omitted from some messages.
    View the message alone to see the lines that have been omitted