Surprisingly, nobody in this thread has suggested that lists/strings in functional position could accept two arguments. This would replace the current cut function. Additionally, negative numbers should mean index from the end, and 0 as second argument could mean "to the end". Here's Python, Ruby, arc1, and lastly my suggested semantics:
The i'th item of s
s[i]
s[i]
(s i)
(s i)
The i'th item of s from the end
s[-i]
s[-i]
(s (- (len s) i))
(s (- i))
The first x items of s
s[:x]
s[0,x]
(cut s 0 x)
(s 0 x)
The last x items of s
s[-x:]
s[-x..-1]
(cut s (- (len s) x))
(s (- x) 0)
The items from position i to the end
s[i:]
s[i .. -1]
(cut s i)
(s i 0)
The items from position i to position j (inclusive)
s[i:j+1]
s[i .. j]
(cut s i (+ 1 j))
(s i (+ 1 j))
The items from position i to position j (exclusive)
s[i:j]
s[i ... j]
(cut s i j)
(s i j)
i items beginning at position j.
s[j:j+i]
s[j,i]
(cut s j (+ i j))
(s j (+ i j))
The items from position i to the end minus the last j items
s[i:-j]
s[i ... -j]
(cut s i (- -1 j))
(s i (- j))
i items beginning at the j'th position from the end
s[-j:-j+i]
s[-j,i]
(cut s (- (len s) j) (+ (- (len s) j) i))
(s (- j) (+ i (- j)))
$s[i] # A scalar at index i
@s[<something complex>] # An array slice (i.e. multiple values)
$#s # The last index of the array s
a .. b # In list context, a list of numbers or letters from a to b, inclusive (can be used outside array indexing)
Are you aware that x..y and x...y notation is a Range literal in Ruby? I like Pythons syntax better but range notation isn't special syntax for slices.
obj[a,b,...] is sugar for a method call in Ruby (you can define a [] method for your own classes). So there's really only two syntactic forms here, and arguably no special syntax for slices.
Your "items from position 1 to the end minus the last 2 items" can actually be achieved in a nicer manner in Arc:
(cut s 1 -2)
(Note that that's using the Anarki negative-end semantics, which PG has said are better; in arc1.tar, that would be (cut s 1 -3). See http://arclanguage.org/item?id=2225)
Maybe there should be another version of cut that takes a length instead of an index as argument. Together with allowing negative second arguments, that should reduce the last example from:
It seems a little weird that the second parameter switches meaning from "end" to "length" if the first parameter is negative, but I suppose it's more useful than the alternative...