4

The basic problem here is, when given a list, to return all elements of that list other than the last element. For example, given (a b c d) --> return (a b c). I essentially have the function, it's just the Scheme syntax that I'm having trouble with and Google isn't being very friendly. I'm not sure if I'm using cons correctly.

(define all-but-last
  (lambda (x)

   (if (null? (cdr x)) 
      ('()))
   (cons ((car x) (all-but-last(cdr x)))
)))

Someone who's knowledgeable with r5rs scheme syntax would be helpful. Thanks!

John Clements
  • 16,895
  • 3
  • 37
  • 52
Chris Arena
  • 1,602
  • 15
  • 17

5 Answers5

3

If you remove the extra parentheses around the '() and arguments to cons, the code will work (for non-empty input lists).

Jeremiah Willcock
  • 30,161
  • 7
  • 76
  • 78
  • Still an error unfortunately: "mcdr: expects argument of type ; given ()" Is there a good resource for this? I've yet to find one with quite a bit of Googling. – Chris Arena Mar 10 '11 at 19:52
  • 1
    @Decency: What do you have so far? Your code is missing the boundary case where x is an empty list. The documentation on http://www.racket-lang.org/ is good; for the kinds of things you are doing, Scheme and Racket are the same. You can also look at R5RS itself as a reference. – Jeremiah Willcock Mar 10 '11 at 19:56
  • In the base case, you need to check if what you are looking at is a list. For example (null? x) must be false as well as (pair? x). car cannot accept either an empty list or non-list, cdr can accept all lists, and cons must have a list in the second argument. – caveman Mar 10 '11 at 19:58
  • 1
    @caveman: I believe you meant "`cdr` can accept all pairs (including non-empty lists)." – Jeremiah Willcock Mar 10 '11 at 20:01
  • Thanks, that'll be helpful in the future. – Chris Arena Mar 10 '11 at 20:20
2

Using DrRacket with Language R5RS, this works:

(define all-but-last
  (lambda (x)
   (if (null? x)
     '()
     (if (null? (cdr x)) 
       '()
       (cons (car x) (all-but-last(cdr x)))))))
dbyrne
  • 59,111
  • 13
  • 86
  • 103
  • This works, thank you. I believe I was ending my if statement too soon, which may have caused the issue. – Chris Arena Mar 10 '11 at 20:22
  • 1
    You had a number of parenthesis placement problems. One was that you were ending your 'if' too soon; however, you also had an extra pair around the empty list '() and around the arguments to 'cons'. I predict that time spent understanding the error messages you got will pay off in the long run. Also, languages like the "Beginning Student" language in DrRacket will give you better error messages, though this may not help if you're taking a class that requires R5RS. – John Clements Mar 10 '11 at 20:26
  • Thankfully I'm happy to be done with Scheme. I've never dealt with a language where parenthesis are anything more than grouping. It's strange and unintuitive to me that 0 and (0) and ((0)) aren't all the same thing. – Chris Arena Mar 12 '11 at 00:00
1

An alternative solution:

(define (all-but-last xs)
  (reverse 
    (rest
      (reverse xs))))
soegaard
  • 30,661
  • 4
  • 57
  • 106
0

if you pass '() to your function, I think you should give error message other than return '()

Alaya
  • 3,287
  • 4
  • 27
  • 39
0

See the answers to this question:

removing last element of a list(scheme)

Also, I'm going to tag this one as "homework". If it's not, let me know and I'll remove it.

Community
  • 1
  • 1
John Clements
  • 16,895
  • 3
  • 37
  • 52
  • It was a test question I was working out afterward. It wasn't homework, but it probably is for someone so I don't really care if it's tagged as such. – Chris Arena Mar 11 '11 at 23:54