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))))