I've updated the range function to accept a step parameter:
(def range (start end (o step 1))
"Return a range of numbers from `start' to `end', by `step'. Default `step' is 1."
(if (is step 0) (list start)
(if ((if (> step 0) > <) start end)
nil
(cons start (range (+ start step) end step)))))
EDIT: added some error-checking, changing a step from 0 to 1 probably isn't the right thing to do, but I didn't feel like figuring out how to throw an error.
(def range (default (o end) (o step 1))
(with (st (if end default 0)
en (if end end default))
(if (is step 0) (= step 1) (zap abs step))
(let (stp-fn test) (if (> st en) `(,- ,<) `(,+ ,>))
((afn (i accum)
(if (test i en) (rev accum)
(self (stp-fn i step) (push i accum))))
st nil))))