Maybe it would have been better if the manual had said instead: "If int-length is negative, slice will take the parameter as offset counting from the end and copy up to
but not including that offset."
As far as the answer to your second question, I believe that all you need to do is transform the index and length arguments, when the length argument is negative.
Code: Select all
(define (myslice xs idx len)
(if (< len 0)
(slice xs (+ 1 idx len) (abs len))
(slice xs idx len)))
Here's another version with implicit slicing. It's supposed to be faster, but arguably less readable.
Code: Select all
(define (myslice xs idx len)
(if (< len 0)
((+ 1 idx len) (abs len) xs)
(idx len xs)))
Beware, though, when your calling code exceeds the ends of the string or list argument -- sometimes you get errors, other times it wraps.
Code: Select all
> (myslice "newLISP" 4 -6)
"P"
> (myslice "newLISP" 4 -7)
"SP"
> (myslice "newLISP" 4 -75)
ERR: invalid string index
called from user function myslice
Of course, you can add checks for these conditions to
myslice, if you want.
(λx. x x) (λx. x x)