wowpatrick
wowpatrick

Reputation: 5180

Racket - output content of a list

I have defined a list (in Racket/Scheme):

(define myList (cons 'data1 (cons 'data2 (cons 'data3 (cons 'data4 empty)))))

or

(list 'data1 'data2 'data3 'data4)

And I want to write a function that cycles through the list and outputs all values of the list.

(define (outputListData list)
  (cond 
    [(null? list) list]
    [else (getListData)]))

With what function can I cycle through the content of the list? I know one can use first & rest to get list data, but I guess that's not the right way here.

BTW: Is there a good, compact racket reference like php.net? I find the official Racket docs very confusing ...

Upvotes: 3

Views: 14268

Answers (4)

user725091
user725091

Reputation:

dyoo's solution is nice and succinct in a Scheme like Racket that has useful iteration routines built in. Just FYI, though, your 'outputListData' is not far from being the standard recursive way to do this. You just need to change a couple of lines:

(define (outputListData list)
  (cond 
    [(null? list) #f]             ; actually doesn't really matter what we return
    [else (printf "~s\n" (first list))    ; display the first item ...
          (outputListData (rest list))])) ; and start over with the rest

Since this is an "imperative" kind of procedure that isn't designed to return a value, it doesn't really matter what we do with an empty list so long as we stop recurring (to avoid an infinite loop). If the list isn't empty, we output the first element and start over recursively with the rest of the list.

BTW, here's another way you could write something almost identical if you just needed a "for" loop in the middle of some other function:

(let loop ((l (list 'foo 'bar 'baz 'quux))) ; or put whatever input you need
   (cond ((null? l) #f)
         (else
           (printf "~s\n" (first l))
           (loop (rest l)))))

One way to think about this "named let" is that it defines a temporary function called loop, which works just like outputListData above. Scheme has the nice property that it won't grow the stack for "tail calls" like these, so you can always write what would be an "iterative" for or while loop in this recursive style.

I highly recommend The Little Schemer by Friedman and Felleisen for a quick intro to this style of function writing! I found it through Douglas Crockford's page here.

Upvotes: 4

pygumby
pygumby

Reputation: 6790

I think the solution that is the easiest to understand it to come up with a so called "list-eater" function. This is the way my university introduced recursion and lists in Racket. Also most books on Racket (i.e. "How To Design Programs" or "Realm Of Racket") explain it this way. This is the code:

(define my-list (list 'data1 'data2 'data3 'data4)) 

(define (print-list a-list-of-data)
  (when (not (empty? a-list-of-data))
    (print (first a-list-of-data))
    (print-list (rest a-list-of-data))))

If you call the function with the example list my-list, you will get the following output:

(print-list my-list)

'data1'data2'data3'data4

The function does the following: As long as the given list is not empty, it grabs the first element of that list and passes it to the function print. Then, it tells itself to do the exact same thing with the rest of the list. (It calls itself on the rest of the list.) This second part is what they call recursion.

However, you can shorten that by using a function called map:

(define (print-list a-list-of-data)
  (map print a-list-of-data))

This basically says that you want the function print to be called on each element of the given list. The output is exactly the same.

Hope it helped!

Upvotes: 1

Cam
Cam

Reputation: 15234

Edit as per comments: Use for-each

(for-each display myList)

Try this:

(void (map display myList))

Breaking it down:

  • (void x) causes x to be ignored instead of returned to the REPL/parent expression as a value.
  • (map function lst): For a list '(a1 a2 ... an) returns the list '((function a1) (function a2) ... (function an)).

So we use map to display all the items, but since we only care about the side-effect and not the return value, we call void on the returned list.

Official docs:

Upvotes: 2

dyoo
dyoo

Reputation: 12023

You can use a for loop. Example:

(for ([x (list 1 2 3)])
    (printf "~s -> ~s\n" x (* x x)))

There are more functional ways to do this, of course, but this way works too. You'll probably want to look at a textbook like How To Design Programs to do the recursive approach. See: http://www.ccs.neu.edu/home/matthias/HtDP2e/

Upvotes: 7

Related Questions