chicken-hackers
[Top][All Lists]
Advanced

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

[Chicken-hackers] A suggested extension to grep: accessor argument


From: Tony Sidaway
Subject: [Chicken-hackers] A suggested extension to grep: accessor argument
Date: Fri, 2 Oct 2009 03:53:05 +0100

The grep procedure provided in regex is useful if you want to operate
on a list of strings only. Providing it with an optional accessor
argument would abstract its functionality to operate on arbitrary
structures having string components, without affecting its current
behavior.

Current: (grep rx lst)

Proposed (grep rx lst . maybe-acc)

If provided, the third argument must be a closure which acts as an
accessor for the desired field to be grepped.

A typical use of this extended functionality would be to grep the
result of sxpath to find XML elements one of whose values or
attributes matches a regular expression pattern.

While one can do the same job using SRFI-1 filter, using the grep
syntax is more natural.

>From chicken-4.1.0 source regex.c:

(define grep
  (let ([string-search string-search])
    (lambda (rx lst)
      (##sys#check-list lst 'grep)
      (let loop ([lst lst])
        (if (null? lst)
            '()
            (let ([x (car lst)]
                  [r (cdr lst)] )
              (if (string-search rx x)
                  (cons x (loop r))
                  (loop r) ) ) ) ) ) ) )

A possible implementation of the extension based on the above code:

(define grep
  (let ([string-search string-search])
    (lambda (rx lst . maybe-acc)
      (##sys#check-list lst 'grep)
      (let ((accessor (if (null? maybe-acc) (lambda(x) x) (car maybe-acc))))
        (##sys#check-closure accessor 'grep)
        (let loop ([lst lst])
          (if (null? lst)
              '()
              (let ([x (car lst)]
                    [r (cdr lst)] )
                (if (string-search rx (accessor x))
                    (cons x (loop r))
                    (loop r) ) ) ) ) ) ) ) )

Thus:

> (grep "a" '((tram . "b")(bus . "c")(bicycle . "a")) cdr)
((bicycle . "a"))

> (grep "a" '((tram . "b")(bus . "c")(bicycle . "a"))
             (lambda(x) (->string (car x))))
((tram . "b"))




reply via email to

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