guile-user
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Read n bytes


From: Neil Jerram
Subject: Re: Read n bytes
Date: 21 Dec 2001 08:49:16 +0000
User-agent: Gnus/5.0808 (Gnus v5.8.8) Emacs/20.7

>>>>> "Sam" == Sam Phillips <address@hidden> writes:

    Sam> Hi, I'm slightly new to guile/scheme.  I've been using it
    Sam> heavily for about the past month.

Welcome to the list!

    Sam> Currently I'm trying find (or write) a routine that will read
    Sam> n bytes from a port.  My current failed attempt is

    Sam> (define (read-num-chars port len) (let ((ret "")) (do ((i len
    Sam> (- len 1))) ((eq? 0 i) ret) (set! ret (string-append ret
    Sam> (list->string (list (read-char port))))) ) ) )

    Sam> I'm sure there's an easier way to do this, but with my
    Sam> current knowledge of scheme I can't uncover it.

The problem here is that, in the `do' expression, the stepper for i
should be `(- i 1)'.  You have `(- len 1)', which will set i to the
same value every time, so the `do' never terminates.

Beyond that, a few stylistic suggestions:

- Instead of `(list->string (list CHAR))', you can use the simpler and
  equivalent form `(string CHAR)'.

- Instead of accumulating `ret' as a string, using string-append, you
  could accumulate characters in a list and then convert to a string
  at the end:

     (set! ret (cons (read-char port) ret))
     ...
     (list->string (reverse! ret))

- When comparing numbers, it's more usual to use `=' than `eq?'.  In
  the case of 0, you can also use the primitive `zero?'.

- If you use `let loop' rather than `do', you can avoid the `set!'.
  (set! is often something of an alarm bell in Scheme; a suggestion
  that you're not doing things in the most "schemely" way.)  You'd
  then have:

    (define (read-num-chars port len)
      (let loop ((i len) (ret '()))
        (if (zero? i)
            (list->string (reverse! ret))
            (loop (- i 1) (cons (read-char port) ret)))))

Best regards,
        Neil




reply via email to

[Prev in Thread] Current Thread [Next in Thread]