Push doesn't accept Reverse as a valid Place


Please let me know if I’m doing things wrong or unconventionally. I’m teaching myself lisp and would appreciate critical feedback.

I noticed that ‘push’ doesn’t accept the return value of ‘reverse’ as a legitimate ‘place’…

15462> (defvar l (list 1 2 3 4 5))                                              
15457> (push 6 (reverse l))                                                     
Error: 'push' illegal place

But if I put that same result from ‘reverse’ into a variable, I can use it as ‘place’…

15457> (setq l (reverse l))                                                     
(5 4 3 2 1)                                                                     
15457> (setq l (reverse (push 6 l)))                                            
(1 2 3 4 5 6)              

Let me know if this isn’t typically how a Lisper would append a value to an existing list.

Thanks! and I’m loving uLisp!! Kudos on all your work. You’ve done a very diligent job with your code and website. It’s awesome!


The in-place operations setf, push, pop, incf, and decf are special because they do surgery on an existing place in a list, modifying it. If you do:

> (defvar l (list 1 2 3 4 5))

> (push 6 (cdr l))
(6 2 3 4 5)

the function cdr is showing where in the list to do the push. The original list l is also modified by this:

> l
(1 6 2 3 4 5)

Because of this there is a limited set of functions that make sense to define the place: uLisp supports car, cdr, nth, and aref.

If you just want to add an item on the front non-destructively, do:

> (defvar l (list 1 2 3 4 5))

> (cons 6 (reverse l)
(6 5 4 3 2 1)

When in doubt, avoid the destructive in-place functions - they can cause unexpected side-effects!


Ah, and this is why only those in-place functions have ‘signatures’ referring to place. Got it. Thanks.