Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Scheme getting last element in list

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?

like image 708
calccrypto Avatar asked Nov 01 '12 10:11

calccrypto


3 Answers

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)))))
like image 128
Barmar Avatar answered Oct 26 '22 10:10

Barmar


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

like image 38
dyoo Avatar answered Oct 26 '22 09:10

dyoo


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))))

like image 34
majik Avatar answered Oct 26 '22 10:10

majik