8

Im trying to write a simple scheme function that returns the last element of a list. My function looks like it should work, but I managed to fail on something:

(define (last_element l)(
  (cond (null? (cdr l)) (car l))
  (last_element (cdr l))
))

(last_element '(1 2 3)) should return 3

DrRacket keeps on giving me the errors:

mcdr: contract violation
  expected: mpair?
  given: ()

Since (null? '()) is true, I don't get why this doesn't work.

This is a function I think I will need for a homework assignment (writing the function last-element is not the assignment), and the instructions say that I cannot use the built-in function reverse, so I can't just do (car (reverse l))

How do I fix this function?

Greg Hendershott
  • 16,100
  • 6
  • 36
  • 53
calccrypto
  • 8,583
  • 21
  • 68
  • 99
  • What will happen if your function is passed the empty list? Your lecturer may not care, of course. Did he or she say anything about what you could assume about the data? For a homework assignment, I think it could be reasonable to discount non-list data but the empty list is a reasonable thing to expect in a list context. In fact, there is a simple way to deal with it that also deals reasonably with other non-list data... – itsbruce Nov 01 '12 at 13:58

4 Answers4

13

Your syntax is totally wrong. You have an extra set of parentheses around the body of the function, not enough around the cond clauses, and your recursive case isn't even within the cond, so it gets done whether the test succeeds or fails. The following procedure should work:

(define (last_element l)
  (cond ((null? (cdr l)) (car l))
        (else (last_element (cdr l)))))
johankj
  • 1,765
  • 16
  • 34
Barmar
  • 741,623
  • 53
  • 500
  • 612
  • 6
    @calccrypto The glass-half-full version of this answer is that you had nearly all the individual elements correct. Just keep in mind that parentheses aren't the same thing as curly braces; you'll want to break that habit of an "opening `(`" on the first line, and putting `)`s on their own line. Also, let DrRacket guide you with the indentation. You'll get the hang of it soon. – Greg Hendershott Nov 01 '12 at 20:37
8

Just to add: in professional-level Racket, the last function is a part of the racket/list library.

dyoo
  • 11,795
  • 1
  • 34
  • 44
2

you can retrieve the last element of a list by calling

(define (lastElem list) (car (reverse list)))

or, recursively using if built-in

(define (last list) (if (zero? (length (cdr list))) (car list) (last (cdr list))))

majik
  • 128
  • 9
0

You can also do it like this.First find the lenght of a list by cdring it down.Then use list-ref x which gives the x element of the list. For example list-ref yourlistsname 0 gives the first element (basically car of the list.)And (list-ref yourlistsname (- length 1)) gives the last element of the list.

Prethia
  • 1,183
  • 3
  • 11
  • 26