glockm15
glockm15

Reputation: 245

Adding an element to the end of a list in Scheme

Tasked with adding a to end of (b c) to make (b c a)

So far when I try

(print (cons 'a '(b c))) 

I get (a b c)

but when I do

(print (cons '(b c) 'a)) 

I get ((b c) . a)

All the other similar questions on Stack seem to be more complicated than this problem so I was wondering if there was an easy fix.

Upvotes: 3

Views: 548

Answers (1)

Barmar
Barmar

Reputation: 780818

A list is a chain of pairs. The elements are the cars of each pair, the cdr is a reference to the next pair in the chain, or an empty list for the last pair in the chain.

When you use (cons 'a '(b c)) you create a new pair in front of the existing list (b c), so the result is still a list.

But when you use (cons '(b c) 'a), you're creating a pair whose cdr is the symbol a, not a list. And the last pair in the list (b c) still has its cdr pointing to the empty list.

You need to copy the first list, and when you get to the end, you have to make the cdr point to a list containing a. You can do this with a recursive procedure.

(define (list-append old-list new-el)
  (if (null? old-list) 
      (list new-el)
      (cons (car old-list) 
            (list-append (cdr old-list) new-el))))
(list-append '(b c) 'a)

The logic is:

  • If we try to append to an empty list, just return a list containing the new element
  • Otherwise, append the new element to the tail of the original list with the recursive call, and then put the first element in front of that (using the (cons new-element old-list) method that you showed in your first example).

Upvotes: 2

Related Questions