Fox
Fox

Reputation: 9444

Printing contents of array LISP

Why does this code not print out the content of the array -


(defun loopfn (state)
       (loop for x from 0 to 2 do
        (loop for y from 0 to 2 do
             (aref state x y))))

Here I am passing a 3x3 matrix which is built like this -

`(setq i (make-array '(3,3) :initial-contents '((0 1 3) (4 2 5) (7 8 6))))`

I am calling - (loopfn i)

Edit-------- @Greg Thanks for pointing that out... I had the following question.. Why does this print the output ...

(defun loopfn ()
   (loop for x from 0 to 3 do
    (if (eq x 2)(return (list x)))))

Where as this prints a nil...

(defun loopfn ()
   (loop for x from 0 to 2 do
    (loop for y from 0 to 2 do
         (if (eq x 2)(return (list x y))))))

I am calling

(loopfn)

Upvotes: 3

Views: 4768

Answers (5)

Paul Richter
Paul Richter

Reputation: 6311

Your call to aref is getting the specified element, but you're not doing anything with it. You could stick it on to a list which is then returned:

(defun loopfn (state)
  (let ((result '()))
    (loop for x from 0 to 2 do
     (loop for y from 0 to 2 do
          (setf result (cons (aref state x y) result))))
   result))

or you could just print it out:

(defun loopfn (state)
  (loop for x from 0 to 2 do
       (loop for y from 0 to 2 do
        (format t "~a~%" (aref state x y)))))

The former is far more useful ; you want to return things which can then be further processed, and anything that gets passed to the top level will be printed out for you.

As long as you are using LOOP you can easily gather up your values with COLLECT, APPEND, etc., which is the idiomatic way to do it.

Upvotes: 1

Will Ness
Will Ness

Reputation: 71119

As for your second question, (return ...) is equivalent to (return-from NIL ...) so you just return from your inner LOOP into the outer one. Use this instead:

[11]> (defun loopfn () 
        (loop for x from 0 to 2 do 
          (loop for y from 0 to 2 do 
            (if (= x 2) (return-from loopfn (list x y))))))
[12]> (loopfn)
(2 0)

Another possibility is to collect more values than just one, as in

[36]> (defun loopfn ()
        (loop for x from 0 to 2 nconc 
          (loop for y from 0 to 2 
                if (= y 2) 
                collect (list x y))) )
LOOPFN
[37]> (loopfn)
((0 2) (1 2) (2 2))

Upvotes: 2

Rainer Joswig
Rainer Joswig

Reputation: 139411

Your code does not print anything. That's also what you want - usually.

But you want functions to return something useful.

So you need to understand the difference between printing and having a REPL printing a return value.

CL-USER > 3
3

Above returns 3. The Read-Eval-Print-Loop prints the return value.

CL-USER > (print 3)

3 
3

Above prints a newline and then two times the 3. Why? The first is the side-effect of the PRINT call which prints the newline and then its argument. The second is the REPL printing the return value.

Note also the EQ is not for numeric comparisons. Use EQL instead. See: http://www.lispworks.com/documentation/lw50/CLHS/Body/f_eql.htm

Upvotes: 2

Greg Hewgill
Greg Hewgill

Reputation: 994817

For your second question, in the loop that doesn't print, (eq x 2) is never true. You have modified the loop bounds from 0 to 3 to 0 to 2, so x never reaches 2. Since there is no explicit (return ...) executed, the function returns nil.

Upvotes: 0

chx
chx

Reputation: 11790

This was neatly covered in this forum topic.

The outer loop has no clause which would cause a return value.

Some code examples from that thread:

(defun print-2d-array-as-table (array)
  (loop for i from 0 below (array-dimension array 0)
    do (loop for j from 0 below (array-dimension array 1)
             do (princ (aref array i j))
                (if (= j (1- (array-dimension array 1)))
                    (terpri)
                    (princ #\Space)))))

and one loop:

(defun print-2d-array-as-table (array)
  (loop for i below (array-total-size array) do
    (if (zerop (mod i (array-dimension array 0)))
      (terpri)
      (princ #\Space))
    (princ (row-major-aref array i))))

Upvotes: 1

Related Questions