Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

re: Idiom for gathering pairs from a list?

21 views
Skip to first unread message

WJ

unread,
May 18, 2012, 10:22:20 AM5/18/12
to
Rob Warnock wrote:

> or even this:
>
> (flet ((stepper (list)
> (case (car list)
> ((:one) (cddr list))
> ((:two) (cdddr list))
> ((:three) (cdddr list))
> (otherwise (cdr list)))))
> (loop for (key a b c) on list by #'stepper ...))
>
> which can parse lists like this:
>
> (:one 123 :two 234 453 :three 7 5 8 :special :other 99 22 :two 34 54)


Racket:

(define lst
'(one 123 two 234 453 three 7 5 8 special other 99 22 two 34 54))

(match-loop
((list (? symbol? sym) (? (negate symbol?) non) ... more ...)
lst)
((printf "~a ~a\n" sym non)
more))

==>
one (123)
two (234 453)
three (7 5 8)
special ()
other (99 22)
two (34 54)


Using the macros:

(define-syntax-rule (do-match-loop
(sym ...) (pat ...) (lst ...) (expr ...))
(let loop ((sym lst) ...)
(when (andmap cons? (list sym ...))
(match-let ((pat sym) ...)
(call-with-values (lambda () expr ...) loop)))))

(define-syntax match-loop-aux
(syntax-rules ()
[(_ () (sym ...) pats lsts form)
(do-match-loop (sym ...) pats lsts form)]
[(_ (x x* ...) (sym ...) pats lsts form)
(match-loop-aux (x* ...) (tmp sym ...) pats lsts form)]))

(define-syntax-rule (match-loop (pat lst) ... form)
(match-loop-aux (pat ...) () (pat ...) (lst ...) form))

WJ

unread,
May 18, 2012, 10:49:29 AM5/18/12
to
Zach Beane wrote:

> "bradb" <brad.beveri...@gmail.com> writes:
> > I'm using CL-PPCRE, and some functions return lists of start and end
> > matches, so a return might be
> > (0 2 4 7 10 15), three matches.
> > Right now I loop over the matches like
> > (loop :for match :on (all-matches scanner text :start start) :by
> > #'cddr
> > :do (let ((start (first match))
> > (end (second match)))
> > (subseq text start end))
>
> > Is there a nicer way to gather the pairs than that?
>
> LOOP destructures. Try this:
>
> (loop for (start end) on (all-matches ...) by #'cddr do ...)


Arc has "pair", which is easily defined in Racket.

(pair '(2 3 4 5 6))
=> '((2 3) (4 5) (6))
(pair '(2 3 4 5 6) +)
=> '(5 9 6)

(define text "abcdefghijklmnop")

(pair '(0 2 4 7 10 15) (curry substring text))
=> '("ab" "efg" "klmno")


The definition:

(define (pair xlist [func list] [accum '()])
(match xlist
[(list a b more ...) (pair more func (cons (func a b) accum))]
[(list a) (reverse (cons (func a) accum))]
[_ (reverse accum)]))

kodifik

unread,
May 21, 2012, 7:39:31 AM5/21/12
to
You could use here the loop macro.
0 new messages