tags:

views:

54

answers:

2

Hi !

I am writing a program in scheme, that uses recursion to walk through the list, and stop at certain pointer, when counter reaches a certain number N

(define (functX N lst)
  (define counter 1)
  (cond
    [(empty? lst) empty]
    [(negative? N) empty]
    [(< (length lst) N) empty]
    [(<= counter N) ((set! counter (+ counter 1))(cons (first lst) (functX N (rest lst)))))]
    [else empty]))

I don't understand, why the second line from the bottom is giving me trouble: the error I am getting is "procedure application: expected procedure, given: '(1) (no arguments)"

+1  A: 

You should consider decrementing N in the recursive call and removing the counter variable altogether.

Adam Byrtek
don't understand why ?
My idea is that counter should increase as we go along the list, and then counter reaches N, it stops !
If you use N to count down you'll be able to avoid a separate counter variable and the program will become much cleaner and stateless.
Adam Byrtek
oki, now it makes sense
(< 0 N) (set! (-N 1))
Don't use set! unless you have to, simply recurse using (functX (- N 1) (rest lst))
Adam Byrtek
+7  A: 

You have it enclosed in parentheses twice. Expressions in Scheme have the form (func-expr arg-expr ...), so the first expression must evaluate into a function. So if you did:

(define (f n) n)
((f 5))

It would evaluate (f 5) then it would try and evaluate (5) which is an error.

Edit: Some clarification.

You have the following enclosed in brackets twice:

((set! counter (+ counter 1))(cons (first lst) (functX N (rest lst)))))

So first it evaluates set! and reduces down to (where n is a number):

(n (cons ...))

cons is then evaluated along with its arguments (where x is the result):

(n x)

It then tries to apply the argument x to the function n, but since n is a number this results in an error. If you wanted to do two separate computations and only return the value of one, you can use begin.

(begin (set! counter (+ counter 1)) (cons (first lst) (functX N (rest lst))))

Update:

Here is a function that appears to do what you want without voodoo (since mutation is evil).

(define (take n xs)
  (cond
    [(empty? xs) empty]
    [(negative? n) empty]
    [(eq? n 0) empty]
    [else (cons (first xs) (take (- n 1) (rest xs)))]))
Paul
It's worth noting that if (f 5) returned a function ((f 5)) would actually to execute it. Just to show that a nested function call isn't always an error.
EmFi
I am sorry, this is answer adds more confusion
You mean (set! counter (+ counter 1)) is twice parenthesized ?
@user465292: There, I added some clarification.
Paul
Cool, now it works !!!!!!!!
@user465292: I added a better version of your function.
Paul