Reputation: 1
my code shows this error - function call: expected a function after the open parenthesis, but received (void)
I dont know why. its on the 3rd line
(define countdown
(lambda (n)
(cond ((zero? n) (( display "Time") (newline)))
(else
((display n) (newline) (countdown ( - n 1)))))))
Upvotes: 0
Views: 722
Reputation: 48735
Here is a definition of abs
:
(define (abs n)
((if (< n 0) - +) n))
When given a negative number the result of evaluating -
is returned else +
so if you were to pass -5
it becomes (- -5)
and in the case 5
is passed it becomes (+ 5)
. Both evaluate to 5
. Do you see that I am using the return of an expression as a function? That is what the parentheses mean.. In a C-like language I might have done something like (n < 0 ? sub : add)(0, n)
In your cond
when disregarding the parentheses that surround each term you have double parentheses several places:
((display "Time") (newline))
((display n) (newline) (countdown ( - n 1)))
Both of them assume the display function returns a function one can apply. It doesn't and it will fail with telling you that is not a function.
If you were looking to group commands together, like {}
in C languages, then you are looking for the special form begin
. eg. (begin 1 2 3) ; ==> 3
cond
has explicit begin
in each of its terms so if you just wanted to get each part evaluated the fix looks like this:
(define (countdown n)
(cond ((zero? n) (display "Time") (newline))
(else (display n) (newline) (countdown (- n 1)))))
An alternative way to format it is this:
(define (countdown n)
(cond
((zero? n)
(display "Time") (newline))
(else
(display n)
(newline)
(countdown (- n 1)))))
Notice parentheses are aligned with the same level so you know when the next term starts. It helps you read the code since your formatting in the question gives no clue. Get a proper editor to do your coding in.
Upvotes: 1
Reputation: 2789
When using cond
statements, you don't need parentheses around consequence expressions. The general structure is:
(cond (condition1 expr1 expr2 expr3 ...) ;; NOT (... (expr1 expr2 expr3 ...))
(condition2 expr1 expr2 expr3 ...)
...
(else ...))
so your specific case can be fixed to:
(cond ((zero? n) (display "Time") (newline))
(else (display n) (newline) (countdown (- n 1))))
and the procedure can be rewritten as:
(define countdown
(lambda (n)
(cond ((zero? n)
(displayln "Time"))
(else
(displayln n)
(countdown (- n 1))))))
If you include parentheses around the consequence expressions by, for example, having
((display "Time") (newline))
then this will be interpreted as a procedure
(procedure-name arg)
where procedure-name
takes the value of (display "Time")
, and arg
takes the value of (newline)
. Since (display "Time")
is only for side effect with no return value, you get the constant #<void>
for procedure and hence the error message: expected a procedure that can be applied to arguments.
Upvotes: 1