[plt-scheme] iterate over characters in string
I need to implement a simple checksum of a string. The specifications
are for the sum of the ASCII values modulo 256. Below is my first
implementation. I am not a student (even though this sounds like
homework, it's actually for the FIX specification -- a standard format
used to represent stock transactions, and it really does specify this
for the checksum.) However, I am learning Scheme on my own (I always
like learning new things) but all I have are books with no practical
guidance except for lurking on these groups.
A few questions:
* is string->list O(n)? (I think it is, but maybe some internal
magic makes it constant?)
* is there any kind of for-each function that works on a string at
the byte level?
In Ruby (another language) iteration is as easy as this:
def calc-checksum(msg)
c = 0
msg.each_byte { |b| c += b }
return c % 256
end
In DrScheme, this is the best I have come up with yet:
(define (calc-checksum line)
(let loop ([checksum 0]
[chars (string->list line)])
(cond [(null? chars) (modulo checksum 256)]
[else (loop (+ checksum
(char->integer (car chars)))
(cdr chars))]))))
It seems a bit verbose (for my taste) and possibly inefficient due to
calling string->list if it really is O(n). Does anyone have
suggestions for how to improve this code? I feel the above is a bit
naive, but I don't know what the "best" way is, and usually there
really is a better way.
I'm hoping some mechanism does exist that I just overlooked. Ideally
I'd do something like this:
(define (calc-checksum line)
(let ([ck 0])
(for-each-char (lambda (c)
(set! ck (+ ck (char->integer c))))
line)
ck))
This is called frequently enough to justify performance
considerations. Thanks for any advice.
--
Chris