[Top][All Lists]
[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
- Read n bytes, Sam Phillips, 2001/12/20
- Re: Read n bytes,
Neil Jerram <=