In Scheme, we try to write procedures using the functional programming paradigm. In your example, defining a counter outside the procedure is not a good idea, to change its value you'd need to mutate it inside using the set!
instruction, and we should avoid doing precisely that.
The usual solution (if we're going to solve this "by hand") would be to recursively traverse the list and increment the value at each recursive call, notice that we don't even need to increment variables inside the procedure, like this:
(define (numpos lst)
(cond
((null? lst) 0)
((>= (car lst) 0) (+ 1 (numpos (cdr lst))))
(else (numpos (cdr lst)))))
The key to understand how this works is in here:
(+ 1 (numpos (cdr lst)))
We add one to the result of the recursion, and we keep doing this for every positive number until we reach the end of the list, and add a zero at the end.
In your code, you had written this: (+ num_pos 1)
, but that expression is not changing the value of num_pos
, it's simply adding one to zero, but never storing the result of the addition!
Now we can define the variables with the proper values, we only need to calculate num_pos
with the procedure, the value of num_neg
can be easily inferred:
(define num_pos (numpos lst))
(define num_neg (- (length lst) num_pos))
There are many ways to solve this problem. After you're familiar with recursive procedures, you'll discover that there are tons of built-in procedures that allow you to quickly find a solution to common problems. In fact, the idiomatic way to answer your question would be to use count
:
(define (numpos lst)
(count (lambda (n) (>= n 0))
lst))