Reputation: 945
So I have 3 functions defined in scheme, sumlist adds up all numbers in a list, and mean gives me the mean of the list. mean2 calls mean and does the same thing, but i get an error. It says the error is coming from sumlist function.
(define (sumlist lst)(if(null? lst)0 (+(car lst)(sumlist(cdr lst)))))
(define mean (lambda x(/(sumlist x)(length x))))
(define mean2 (lambda x(mean x)))
This is how i call the functions
(mean 1 2 3 4 5)
=>3 ;it works
(mean2 1 2 3 4 5)
+: contract violation
expected: number?
given: '(1 2 3 4 5)
argument position: 1st
other arguments...:
0
I'm still new too scheme just got introduced to it last week, but it is really frustrating..what am i doing wrong?
Upvotes: 1
Views: 14554
Reputation: 48745
Because (define (x . y) ...)
is the same as (define x (lambda y ...))
,
the following implementations of identity
are the same
(define (fun arg1)
arg1)
(define fun
(lambda (arg1)
arg1)
While the following implementation of list
are the same
(define (fun . args)
args)
(define fun
(lambda args
args)
So when you apply (mean2 2 3 4 5)
x
is the list (2 3 4 5)
, and (mean '(2 3 4 5))
also wraps all arguments into a list so the call to sumlist
turns into (sumlist '((2 3 4 5)))
. In sumlist you try to do (+ '(2 3 4 5) 0)
which won't work since +
expects numbers as arguments, not lists. To fix this you need to define mean2
as one of:
;; Just make an alias to mean
(define mean2 mean)
;; wrap mean
(define (mean2 x)
(mean x))
;; use apply
(define (mean2 . x)
(apply mean x)) ; apply undoes list
I'd use the methods in the order of appearance. Sometimes using apply is the best but not if you can just alias or wrap.
Upvotes: 6