user1438567
user1438567

Reputation:

Please explain for me what is being done in this Common Lisp Code....?

I get all the rest of the code so I would really appreciate it if you would explain this section of the following function:

(mapcar (lambda (x y)
          (aref cells y x))
        (list l x r l r l x r)
        (list u u u y y d d d))

I.e. I get mapcar at least what it's doing here in this unrelated statement:

(mapcar #'car '((1 a) (2 b) (3 c)))

and I understand lambda is a generic (defun)

Here is the function the above code section came from:

(defun neighbours (cells x y)
  (let* ((mx (1- (array-dimension cells 1)))
         (my (1- (array-dimension cells 0)))
         (l (if (zerop x) mx (1- x)))
         (r (if (= x mx) 0 (1+ x)))
         (u (if (zerop y) my (1- y)))
         (d (if (= y my) 0 (1+ y))))
    (mapcar (lambda (x y)
              (aref cells y x))
            (list l x r l r l x r)
            (list u u u y y d d d))))

Upvotes: 0

Views: 114

Answers (2)

Joshua Taylor
Joshua Taylor

Reputation: 85913

Elements of an array are retrieved using aref. The call (aref cells y x) returns the element at position (y,x) from the two dimensional array cells. mapcar applies a function to argument lists constructed from the sequences passed to it, and returns a list of the function's return value. So,

(mapcar (lambda (x y)
          (aref cells y x))
        (list l x r l r l x r)
        (list u u u y y d d d))

returns a list of the result of calling the lambda function with l u, with x u, r u, and so on. The result is equivalent to

(list (aref cells u l)
      (aref cells u x)
      (aref cells u r)
      ...
      (aref cells d x)
      (aref cells d r))

Upvotes: 1

momo
momo

Reputation: 1045

aref is similar to the function nth or elt in that it allows you to access elements in an array (the latter two work on lists).

CL-USER> (setf test (make-array 3 :initial-contents '(1 2 3)))   
#(1 2 3)
CL-USER> test
#(1 2 3)
CL-USER> (aref test 0)
1
CL-USER> (aref test 1)
2

It also works on multi-dimensional arrays:

CL-USER> (setf test (make-array '(2 3) :initial-contents '((1 2 3) (4 5 6))))
#2A((1 2 3) (4 5 6))
CL-USER> test
#2A((1 2 3) (4 5 6))
CL-USER> (aref test 0 1)
2
CL-USER> (aref test 0 2)
3
CL-USER> (aref test 1 0)
4
CL-USER> (aref test 1 1)
5
CL-USER> 

In your case, because the call to array has two subscripts, it is a multi-dimensional array, arrays within arrays.

Hyperspec on aref

Upvotes: 0

Related Questions