Recoba20
Recoba20

Reputation: 324

Get the last element of a list in Scheme

I'm following an introduction to Computer Science using Scheme. I am into the following problem, and I come up with a solution, it seems however that I'm lost in the syntax.

Define a procedure last-pair that returns the list that contains only the last element of a given (nonempty) list: (last-pair (list 23 72 149 34))

Here is my solution:

   (define (last-pair array) 
     ((define (get-last (length array) array)) 
       (if (= (length array) 1) (car array) 
        (get-last (- 1 (length array)) (cdr array))))))

Here is the mistake: Error: Invalid lambda: (lambda ((length array) array))

Upvotes: 1

Views: 1907

Answers (2)

Sylwester
Sylwester

Reputation: 48745

In your procedure you are calling a definition..

+   ; ==> <procedure: +> (how it's printed varies but it  is the value that can be called)
(+) ; ==> 0 
^- this calls the result for evaluation `+` which is `<procedure: +>`

((define something ...)) ; == (undefined-value) == Error!
^- this calls the result of `(define something ...)`. 

define will return some implementation dependent value and in the report it's just says it's undefined. You cannot assume it's the same as value that something is bound to (which would be a nice undefined value)

Also the format of your local define uses no standard extensions that might be ok for some Scheme implementations and it's defined in SRFI-16, but it's not a portable feature.

(define (get-last (length array) array)
  ...)

Thus in a language that does not allow this you would get an error while languages that supports the extension might not.

The difference between the last pair and the pair before it is the value of the cdr. (cdr '(1 . 2)) ; ==> 2 while (cdr '(0 1 . 2)) ; ==> (1 . 2). Thus you can iterate the list until you hit a non pair? value for cdr:

(define (last-pair lst)
  (if (pair? (cdr lst))
      (last-pair (cdr lst))
      lst))

(last-pair '(1 2 3 4 . 5)) ; ==> (4 . 5)

Notice this will fail if you don't give it a pair to start with, just as car and cdr.

Upvotes: 3

Riccardo Marotti
Riccardo Marotti

Reputation: 20348

The error is in:

(define (get-last (length array) array)

When you define a function, you have to list the function name and its arguments:

(define (function-name arg1 arg2 ... argN) ...

(length array) can't be an argument: it's a call to a function.

Anyway, there is no need to define get-last. Something like this is enough:

(define (last-pair array) 
  (if (= (length array) 1) 
      array
      (last-pair (cdr array))))

Upvotes: 2

Related Questions