help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Why doesn't nconc change my variable?


From: Pascal J. Bourguignon
Subject: Re: Why doesn't nconc change my variable?
Date: Sun, 05 Oct 2014 20:31:29 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.3 (gnu/linux)

Marcin Borkowski <mbork@wmi.amu.edu.pl> writes:

> (Now that I'm wondering what the implementation might actually be, I'm
> more and more tempted to look at the C source.  This is probably a good
> sign.)

Instead, look at the lisp source! ;-)

(defun .nconc (&rest lists)
  (let ((lists (do ((curlists lists (rest lists)))
                   ((or (null curlists) (first curlists))
                    curlists))))
    (when lists
      (let ((current (first lists)))
        (dolist (next (rest lists) 
          (when next
            (setf (cdr (last current)) next
                  current next)))))))


(.nconc (list 1 2 3) (list 4 5 6) (list 7 8 9))
--> (1 2 3 4 5 6 7 8 9)
(.nconc (list 1 2 3) nil (list 4 5 6))
--> (1 2 3 4 5 6)
(.nconc (list 1 2 3) nil)
--> (1 2 3)
(.nconc nil (list 1 2 3))
--> (1 2 3)
(.nconc nil)
--> nil


> 1. Do I get it correctly that the "destructiveness" of some functions
> (like nconc) does /not/ mean that they /change/ some of their arguments,
> but only that they /may/ do it, and that relying on that is risky?

Yes.


> 2. Do I get it correctly that what Pascal called "a nil symbol" is just
> NUL under the hood? 

No.


> Does it mean that there's no difference between (),
> nil and the result of (list) (as opposed to the results of calling list
> twice with the same arguments)?  (They seem to be `eq', as I've just
> checked.)

If they're eq then there's no difference.

It's the lisp reader that reads () as nil:

  (car (read-from-string "()"))     --> nil
  (car (read-from-string "nil"))    --> nil
  (car (read-from-string "(list)")) --> (list)

It's the lisp evaluator that calls list and have it return nil, just
like nil, since nil is bound to nil:

  (symbol-value 'nil) --> nil
  (eval 'nil)         --> nil
  (eval '(list))      --> nil


> 3. What is the "canonical" way to append an element to a list, in the
> sense that I have a variable containing (=pointing to?) a list, I want
> it to point to a list one element longer?  And, while at that, what is
> the "canonical" way to /prepend/ an element to a list (is it `push'?)

    (setf list (nconc list (list new-element)))


> 4. (This is the suggestion.)  If the above is right, could someone make
> it more clear in the manual (or point me to the place in the manual
> where it is actually stated)?

Your above was wrong, so no. ;-)

I guess these things are explained more pedagogically in (info "(eintr)")
and notably in (info "(eintr) List Implementation")

-- 
__Pascal Bourguignon__                 http://www.informatimago.com/
“The factory of the future will have only two employees, a man and a
dog. The man will be there to feed the dog. The dog will be there to
keep the man from touching the equipment.” -- Carl Bass CEO Autodesk


reply via email to

[Prev in Thread] Current Thread [Next in Thread]