views:

370

answers:

3

Hi, I'm trying to write a function in scheme that takes a list and squares every item on the list, then returns the list in the form (list x y z). However, I'm not sure how to write a code that will do that. So far, I have

(define (square=list list)
  (cond
    [(empty? list) false]
    [else (list (sqr (first a-list))(square-list (rest a-list)))]))

but it returns the list in the form

(cons x (cons y (cons z empty)))

What can I do to make it return the list just in the form (list x y z)? Thanks!

+2  A: 

The problem is that you're using list in the else statement. You are saying build me a list with this value as the first entry, and a list as the second entry. You want to cons the first entry onto the list created by recursive call.

(list 'a '(b c d))
; gives you
'(a (b c d))

(cons 'a '(b c d))
; gives you
'(a b c d)
z5h
+1  A: 

You're almost there -- make sure you understand the difference between cons and list (the textbook How to Design Programs explains this in Section 13. You can find the online copy here).

cons will take an item as its first element and (usually) a (possibly empty) list for the 'rest' part. As an example, (cons 1 empty) has the number 1 as its first element and the empty list as the 'rest'. (cons 1 (cons 2 empty)) has the number 1 as the first element, and (cons 2 empty) as the 'rest'.

list is just an easy shorthand for making lists, taking an arbitrary number of items. Thus:

(list 1 2 3 4 5)

is the same as...

'(1 2 3 4 5)

which is the same as

(cons 1 (cons 2 (cons 3 (cons 4 (cons 5 empty))))).

But be careful. (list 1 (list 2 (list 3))) is not the same as (cons 1 (cons 2 (cons 3 empty))). In fact, it is (cons 1 (cons 2 (cons 3 empty) empty) empty).

If you're still confused, feel free to post a comment.

Andrew Song
A: 

This is probably not what your TA is looking for, but I'll throw it in anyway because it may help you grok a tiny bit more of Scheme. The idiomatic (in Scheme) way to write what you are trying to do is to use map:

> (map (lambda (x) (* x x)) '(1 2 3 66 102 10403))
(1 4 9 4356 10404 108222409)

map applies a function (here, (lambda (x) (* x x)) - a nameless function that returns the square of its input) to each element of a list and returns a new list containing all of the results. Scheme's map basically does the same iteration you are doing in your code, the advantage being that by using map you never have to explicitly write such iterations (and, nominally at least, a Scheme implementation might optimize map in some special way, though that's not really that important in most cases). The important thing about map is that it reduces your code to the important parts - this code squares each element of the list, this other code takes the square root of each element, this code adds one to it, etc, without having to repeat the same basic loop iteration code again and again.

Jack Lloyd