Reputation: 324
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
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
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