> (rprn (list 'a 2 "c"))
(a 2 "c") ; prints this
(a 2 "c") ; returns this
Edit: The above are just very slightly modified versions of the code used to implement pr and prn, the difference is that Scheme's print is used instead of display, to give READable output.
This would also allow things like a splice operator (mentioned here: http://arclanguage.org/item?id=540); if we had this (assuming that @x expands to (splice x)), you could write (let arglist '(4 5 6) (list 1 2 3 @arglist 7 8 9)) and get (1 2 3 4 5 6 7 8 9). This would actually be superior to apply in certain cases: (and x y @arglist) wouldn't have to evaluate y or the parts of arglist, whereas (apply and x y arglist) has the same effect in most cases, but does evaluate y, which can be problematic. I suppose one way to solve this would be to give values a "cer" (Current EnclosuRe) or some such; if lst were '(1 2 (a b) 3 4), then (cer x) = nil, (cer (car x)) = x, and (cer (car (list-ref 2))) = (list-ref 2). It's not clear what (cer (cdr x)) would be, but it would probably also be x.
Personally I'd still implement this as a macro form, such that we would have a (spliceable ...) form which would scan its contents for splice-macros. So the syntax would look approximately like:
(spliceable ...) would essentially be a generalization of the `() operator, except that ` will only scan for , while (spliceable ...) would scan for any splice-macros.
So far, I'm not too keen on = for setf. Mainly for the negative reason that I like = with its comparison of numbers meaning. Perhaps (! a 0) for assignment?
The other short names for commonly used operators I find a big win though. I've already copied a lot of them to my own pet Lisp - that's how much I like them.
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))))
Thanks for your reply! My confusion stemmed from the fact that I thought that def behaved like define in Scheme (i.e. establishing a new binding), which apparently was not the case.
that and ^ do the same thing (but there's also ^^, ^^^).
thatexpr is like CL + .
But (%) is like (eval thatexpr), except % is a macro that gives you what the last thing entered expanded into. And so, since % is a macro, it itself is expanded away. Hence
arc> 2
2
arc> (* ^ 2)
4
arc> (%) ; equivalent to entering (* ^ 2) again
8
arc> (%) ; and again
16
arc> (%) ; and again
32
Whereas
arc> 2
2
arc> (* ^ 2)
4
arc> (eval thatexpr) ; i.e. (eval (* ^ 2))
8
arc> (eval thatexpr) ; i.e. (eval (eval thatexpr)) i.e. (eval (eval (eval thatexpr))) etc.
[infinite loop]