Home   Archive   Permalink



Referring to next/prev series entries

I have a common usage case where I need to iterate through a series, and do something with the current entry and its immediate neighbors - ie the one before or the one after.
    
Unless I am missing something obvious, neither Rebol nor Red have simple syntax for this.
    
Here's an example where I want to find the difference between consecutive values:
    
         ; create a block of objects
     x: [] loop 10 [append x make object! [r: random 100]]
        
         ; iterating through the series is easy
     forall x [print x/1/r]
        
         ; referring to the next entry in the series is possible
     x: head x
     forall x [unless tail? next x [print x/2/r - x/1/r]]
        
         ; referring to the previous entry in the series is awkward
     x: next head x
     forall x [print x/1/r - get in first back x 'r]
    
         ; in an ideal world :)
     x: next head x
     forall x [print x/1/r - x/0/r]
    
    
There are other ways - such as using REPEAT and setting a word to one less than the interation counter - any suggestions for more Reddish ways?

posted by:   Sunanda     4-Nov-2018/5:07:46-8:00



Negative numbers will go back in the series in a similar way in Red and Rebol.
    
forall x [print x/1/r - x/-1/r]
    
Ren-C uses 0 to get the prior value.

posted by:   Chris     4-Nov-2018/12:54:47-8:00



The 0 was a convention introduced in R3-Alpha, which was largely unpopular...and Ren-C ultimately went ahead and changed to have -1 pick the prior value (circa June):
    
https://github.com/metaeducation/ren-c/pull/818

posted by:   Fork     4-Nov-2018/18:29:39-8:00



Thanks Chris - so simple, when you know how :)
    
I was tripped up by expecting Rebol's ordinal number line to have a zeroth.

posted by:   Sunanda     5-Nov-2018/3:23:24-8:00



My bad HF--tested on a slightly older version of Ren-C

posted by:   Chris     5-Nov-2018/16:23:48-8:00



I often used loops with a counter for those sorts of routines:
    
repeat i length? x [print [x/(i) x/(i - 1)]]

posted by:   Nick     5-Nov-2018/23:32:46-8:00



Given:
    
x: [] loop 10 [append x make object! [r: random 100]]
    
From the answers above, this does not work:
    
forall x [print x/1/r - x/-1/r]
    
And yes, Chris caught his error.
    
Proof:
    
>> forall x [print x/1/r - x/-1/r]
** Script Error: Cannot use path on none! value
** Where: forskip
** Near: forall x [print x/1/r - x/-1/r]
    
However, this does:
    
out1: copy []
n: 2
until [
    append out1 reduce [x/(n)/r - x/(n - 1)/r]
    n: n + 1
    n = (1 + length? x)
]
    
    
Proof:
    
out2: copy []
x: head x
forskip x 2 [
    append out2 reduce [negate x/1/r '+ x/2/r]
    if not none? ok: attempt [ reduce [negate x/2/r '+ x/3/r]][append out2 ok]
]
    
print out1
print reduce out2


posted by:   Stone Johnson     23-Aug-2019/18:17:41-7:00