[plt-scheme] iterate over characters in string

From: John David Stone (stone at cs.grinnell.edu)
Date: Tue Aug 13 10:45:26 EDT 2002

        Chris Uzdavinis writes:

 > I need to implement a simple checksum of a string.  The specifications
 > are for the sum of the ASCII values modulo 256.

        Here's how I'd do it:

(define calc-checksum
  (lambda (line)
    (let loop ((remaining (string-length line))
               (checksum 0))
      (if (zero? remaining)
          (modulo checksum 256)
          (let ((next (- remaining 1)))
            (loop next (+ checksum
                          (char->integer (string-ref line next)))))))))

        Uzdavinis also writes:

 > 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.

        If you want FOR-EACH-CHAR to work like FOR-EACH, it should traverse
the string from left to right.  So here's how I'd do that one:

(define for-each-char
  (lambda (proc line)
    (let ((len (string-length line)))
      (let loop ((position 0))
        (if (< position len)
              (proc (string-ref line position))
              (loop (+ position 1))))))))

This meshes correctly with Uzdavinis's definition of CALC-CHECKSUM using
FOR-EACH-CHAR.  (But in the last line of his definition, CK should be
(MODULO CK 256).)

   John David Stone - Lecturer in Computer Science and Philosophy
           Manager of the Mathematics Local-Area Network
           Grinnell College - Grinnell, Iowa 50112 - USA
     stone at cs.grinnell.edu - http://www.cs.grinnell.edu/~stone/

Posted on the users mailing list.