3

I'm having a bit of trouble implementing this program in Scheme, although I think I'm 90% of the way there. Unfortunately I need to be a little vague about it since this is a homework assignment. I want to (A B C D ) to return ( B D) . but i am getting an error that says The object (), passed as an argument to safe-car, is not a pair | " This is my code:

(DEFINE (other_el lis) (COND (( NULL? lis ) '()) ((LIST? lis) (append (CADR lis) (other_el (CDR lis)))) (ELSE (show " USAGE: (other_el [LIST])")))) 
1
  • 1
    are you familiar with the function cddr? Commented Nov 14, 2012 at 12:09

2 Answers 2

2

There are a number of minor issues with this code that should be mentioned before I demonstrate the proper code.

  1. Do not capitalize procedures' names such as cdr and define in Scheme.
  2. Do not display an error message manually. Use exceptions.
  3. You should always indent your code. (edit: it looks like someone has edited the question's code to include indentation)

Anyway, here is the function you are looking for:

(define (evens lst) (if (or (null? lst) ; if the list is empty (null? (cdr lst))) ; or the list has a single element '() ; then return the empty list (cons (cadr lst) ; otherwise `cons` the second element (evens (cddr lst))))) ; and recursively advance two elements 

I tested the function in DrRacket 5.3 and (evens '(A B C D)) returns '(B D), as you specified. If you have any trouble, let me know. Good luck with your homework!

Sign up to request clarification or add additional context in comments.

4 Comments

I want to be able to print a specific error message when a user input a parameter that is not a "list" INSTEAD of letting the interpreter do it . I was trying to follow your logic and do it but I'm lost :) Thanks in advance
The best way to include your own error message would be to have another function check for a list and do the error handling, which then calls the function I gave you (ie, the technique Oscar used in his answer).
It's an awful answer, the solution could easily be O(n) (see this implementation), but the use of length in the condition has made it O(n^2). You should not check the length of a list at each iteration, ever
Thanks Oscar, I changed my code to the code you provided in your implementation (I would have deleted my answer outright, but unfortunately it is already accepted).
2

This one is considerably simpler than the previous question you asked. Bear in mind, you don't have to calculate the length at each step (that could be very inefficient), or use append operations to solve it (use a cons instead); here's the structure of the answer, because it looks like homework I'l let you fill-in the blanks:

(define (every-other lst) (if (or <???> ; if the list is empty <???>) ; or the list has a single element <???> ; then return the empty list (cons <???> ; otherwise `cons` the second element (every-other <???>)))) ; and recursively advance two elements 

If you need to do some error checking first, use another function and call the above procedure after you're certain that the arguments are correct:

(define (other_el lst) (if (list? lst) (every-other lst) (error "USAGE: (other_el [LIST])"))) 

Use it like this:

(other_el '(A B C D E G)) => '(B D G) 

2 Comments

Is there a syntax to check if a list has a single element the way we do (null? lst) to check for empty list? Sorry if this is too basic , I'm still new to the language . Google couldn't help :)
@NathalieD Certainly. Just check if the next element after the current one is the null list: (null? (cdr lst))

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.