A slice of Nice

Bryn Keller <[email protected]> Thu, 12 Aug 2004 23:25:05 -0700
Newsgroups gmane.comp.lang.nice.general
Message-ID <[email protected]>
Hi folks,

I've just committed a few new features to the Nice CVS repository, and 
I'd like to know what people think about them. Any suggestions for 
improvement would be welcome.

In Nice, as in some other languages, it's possible to override the 
behavior of the [] operator. I've done this for lists, so that the [] 
operator now supports a number of new options, including slicing, 
filtering, and indexing relative to the end of the list, instead of the 
front.

First, we introduce a new symbol, "@", which means, "the last index in 
the list". Sometimes I think of it as "-0". So, given a list of ints 
from 0 to 6 called 'intList':

    intList[@] is 6,
    intList[@-1] is 5

Makes sense? This has the desirable property of making indexing 
reflective: 1 is the second element from the front, @-1 is the second 
element from the back (view the diagram in a monospaced font for best 
results):

from the front:     0    1    2    3    4    5

(or: )              0   0+1  0+2  0+3  0+4  0+5

                 [ "a", "b", "c", "d", "e", "f"]

from the back:     @-5  @-4  @-3  @-2  @-1   @

Next, we add slicing, using the range operator we've had for a while now 
(and even in the manual, in the section on extended for loops).

    intList[1..2] is the list [1,2].
    intList[1..@-1] is a list of all but the first and last
        elements of ints, i.e., [1,2,3,4,5]
    intList[1..] is a list of all but the first element of intList
    intList[..] is a complete copy of intList
    intList[..@-1] is a list of all but the last element of intList
    intList[@-2..@-1] is the third-from-last and second-from-last: [4,5]

Notice that Nice's range is an _inclusive_ range, as opposed to Python's 
half-open range. So where Python would write:

    intList[1:-1]

(where -1 represents the last item in the list) to mean all but the 
first and last items of the list, we write

    intList[1..@-1]

for the same thing. @ means the last item in the list, minus one makes 
it the second to the last item in the list, and ".." is the inclusive 
range operator which takes everything from index 1 to index @-1, 
including the end points.

There are also some more unusual variants, such as filtering:

    intList[int i => i % 2 == 0] is a list of all the even ints in 
intList, i.e.: [0,2,4,6]

Picking out a sequence of arbitrary indices:

    intList[[2,3,0,1, @]] is [2,3,0,1,6]

Assigning to a filter:
    intList[int i => i % 2 == 0] = 27 makes intList into: [27, 1, 27, 3, 
27, 5, 27]

Assigning to arbitrary indices:
    intList[[0,2] = -3 makes intList into: [-3, 1, -3, 3, 4, 5, 6]

Assigning to a slice:
    intList[3..] = 9 makes intList into: [0,1,2, 9, 9, 9, 9]
    intList[3..] = [5,4,3,2] makes intList into: [0,1,2,5,4,3,2]

Removing a slice:
    intList.removeAt(3..) makes intList into: [0,1,2]

We've also debated adding support for a half-open range as "..!", e.g., 
1..!4 to mean the same as 1..3, on the theory that the half-open range 
can be useful too in certain circumstances. Does this come up often 
enough to merit it? I'm not interested in adding "..." for this, as I 
would never be able to keep the meanings of ".." and "..." straight.

So what do you think of these new features? Good? Bad? Ugly? Let me know.

Bryn


-------------------------------------------------------
SF.Net email is sponsored by Shop4tech.com-Lowest price on Blank Media
100pk Sonic DVD-R 4x for only $29 -100pk Sonic DVD+R for only $33
Save 50% off Retail on Ink & Toner - Free Shipping and Free Gift.
http://www.shop4tech.com/z/Inkjet_Cartridges/9_108_r285