This is a read-only archive of lispforum.com. The forum was locked to new users and posts and is preserved here as static HTML from a database snapshot taken on 2019-09-07.

apply, append and collect trouble

2 posts · 1668 views

Hi,

I'm sitting here starting at the book "Land of Lisp" while trying to figure out some "strange" behaviour. There is a function calle make-edge-list, there is nothing wrong with it the function works but there is a little thing I don't understand.
(defun make-edge-list()
  (apply #'append (loop repeat *edge-num* 
                              collect (edge-pair (random-node) (random-node))))
)
The collect-statement aggregates elements during a loop into a list of that elements. I manually I tried that (stripping apply, append from the statement above) and got the following output ( ((3 . 28) (28 . 3)) ((10 . 30) (30 . 10)) )
I looked up apply and append. Apply will apply the provided function onto a list of arguments that have to be lists. And append was described as "result is a list that is the concatenation of the arguments". I also tried those manually onto the given input. Manually applying append onto the result of collect yields the same list ( ((3 . 28) (28 . 3)) ((10 . 30) (30 . 10)) ), thats also what the specs say.But using append in combination with apply#' resulted in ((3 . 28) (28 . 3) (10 . 30) (30 . 10)) ( a list containing pairs).

So my question is. Why is (apply #'append '(((3 . 28) (28 . 3)) ((10 . 30) (30 . 10)))) equal to (append '((3 . 28) (28 . 3)) '((10 . 30) (30 . 10))) but not to (append '(((3 . 28) (28 . 3)) ((10 . 30) (30 . 10))))? I don't see it, hopefully someone can explain this to me.

Re: apply, append and collect trouble

Ah I got it. The desciption about apply was a little unclear, I looked it up elsewhere. Apply uses the "contents" of the list as input for the provided function, which in my case is equivalent to calling (append '((3 . 28) (28 . 3)) '((10 . 30) (30 . 10))).