Path: news.eternal-september.org!eternal-september.org!.POSTED!not-for-mail From: "B. Pym" Newsgroups: comp.lang.lisp,comp.lang.scheme Subject: Re: Is there a better way to read multiple values from a string Date: Wed, 2 Jul 2025 15:48:19 -0000 (UTC) Organization: A noiseless patient Spider Lines: 85 Message-ID: <1043kbv$3jfad$1@dont-email.me> References: <1043329$3fmlt$1@dont-email.me> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Injection-Date: Wed, 02 Jul 2025 17:48:19 +0200 (CEST) Injection-Info: dont-email.me; posting-host="6c5e8e07840a8af6611f1600370a083a"; logging-data="3784013"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX189Ww0eKkAwh/dHFt+FIS2i" User-Agent: XanaNews/1.18.1.6 Cancel-Lock: sha1:bANYYwW0AdNBaXuVETuzxSvsWoc= 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)))))