Sujet : Re: Is there a better way to read multiple values from a string
De : Nobody447095 (at) *nospam* here-nor-there.org (B. Pym)
Groupes : comp.lang.lisp comp.lang.schemeDate : 02. Jul 2025, 16:48:19
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <1043kbv$3jfad$1@dont-email.me>
References : 1
User-Agent : XanaNews/1.18.1.6
B. Pym wrote:
Pascal J. Bourguignon wrote:
I have a strings like "0 2 0 1". The number of values may vary, but
they all can be read using READ
Right now I do the following
(loop
:for (x pos) = (multiple-value-list
(read-from-string first-line nil nil :start (or pos 0)))
:while x
:collect x)
Is there a more idiomatic way to read all the tokens in the string and
return them as a list?
(with-input-from-string (in string)
(loop :for n = (read in nil nil)
:while n :collect n))
If we are allowed to use a collector, then the loop
becomes much shorter. Compare:
(loop :for n = (read in nil nil) :while n :collect n))
(until (eof-object? (bag (read))))
Gauche Scheme:
(define bag (mlistbag))
(with-input-from-string "0 4 2 5"
(lambda()
(until (eof-object? (bag (read))))))
;; Remove the eof-object.
(drop-right (bag) 1)
===>
(0 4 2 5)
Given:
A better way.
;; Remove the eof-object.
(bag 1 'drop)
===>
(0 4 2 5)
Given:
(define (mbag init func :optional (pass-through #f))
(let ((val init) (func func) (pass-through pass-through))
(lambda args
(if (null? args)
val
(let ((x (car args)))
(if (null? (cdr args))
(begin
(set! val (func x val))
(if pass-through
x
val))
(let ((kons (cadr args)))
(if (or (eq? 'drop kons) (eq? 'DROP kons))
(do ((n x (- n 1)))
((zero? n) (if (eq? 'drop kons) (reverse val) val))
(set! val (cdr val)))
(begin
(set! val (kons x val))
(if pass-through
x
val))))))))))
(define (mlistbag :optional (raw #f) (pass-through #t))
(let ((bag (mbag '() cons pass-through)))
(lambda args
(if (null? args)
(if raw
(bag)
(reverse (bag)))
(apply bag args)))))