Reputation: 125
I always have problems thinking functionally and here is a typical example.
(define tally_table (make-hash))
(define (process-each-line)
(define actual_percent 5)
(define new_record (list 0))
(define add_record (list 1))
(define (tally-records hash_value to-be-added)
(map (lambda (number1 number2)
(+ number1 number2)) hash_value to-be-added))
(if (hash-has-key? tally_table actual_percent)
(let* ([hash_value (hash-ref tally_table actual_percent)])
hash-set! tally_table actual_percent (tally-records hash_value add_record)
)
(hash-set! tally_table actual_percent new_record)
)
)
What I expected the code to do was add a new value to an empty hash table the first time run (which it does), then add to the hash table value on successive runs (which it doesn't - instead it returns a list of '(1) and the hash table value remains the same). I'm guessing it might be to do with the scope of let*, but I'm certainly confused as to why the two sides of 'if' (appear to) behave differently.
Upvotes: 0
Views: 58
Reputation: 6502
You want to make a function call, but you missed parentheses around hash-set!
in the "then" branch of if
. Parentheses is the syntax for function call. Since you missed it, it doesn't perform function call.
To compare it with other languages like JS, instead of writing f(x, y, z)
, you are (roughly) writing:
f;
x;
y;
return z;
In this case, it evaluates hash-set!
, ..., (tally-records hash_value add_record)
, and returns the evaluation result of (tally-records hash_value add_record)
.
FYI, there's a function hash-update!
which does both hash-set!
and hash-ref
at the same time, and it could also deal with when hash-has-key?
returns #f
, too. That means you don't need that if
expression at all. You could just write this instead:
(hash-update! tally-table actual-percent
(λ (current-value) (tally-records current-value add-record))
new-record)
EDITED: with hash-update!
, tally-records
will be applied when hash-has-key?
is #f
too. You probably need to adjust the value of new-record
to preserve the existing behavior. Alternatively, just use the regular if
that you had before.
Upvotes: 1