• Re: Lost in Loop

    From B. Pym@Nobody447095@here-nor-there.org to comp.lang.lisp,comp.lang.scheme on Fri Aug 15 07:22:32 2025
    From Newsgroup: comp.lang.lisp

    Pascal Bourguignon wrote:

    it to learn Lisp. Basically, for a list of book titles I wanted to
    return a list of position in text and the book title, so
    (build-book-index "wjhedbwjhbMarkajbdadbGenesis" *books*)

    gave: ((21 "Genesis") (10 "Mark")).

    I had an approach working but it looked horrid so I thought I would try loop. I came up with this:

    (defun build-book-index (text books)
    (loop for book in books
    when (search (string-downcase book) (string-downcase text)) collect
    (list it book)))

    Of course, ...collect it ... worked but the version above gave:

    in: LAMBDA NIL
    ; (LIST IT BOOK)
    ; caught WARNING: undefined variable: IT

    Is this expected?

    Yes.

    How can I get round it?

    Not using IT.

    (defun build-book-index (text books)
    (loop
    for book in books
    for my-it = (search (string-downcase book) (string-downcase text))
    when my-it collect (list my-it book)))

    Gauche Scheme

    (use srfi-13) ;; string-contains-ci

    (define (build-book-index text books)
    (filter-map~ book
    (let1 p (string-contains-ci text book)
    (and p (list p book)))
    books))

    (build-book-index "foo.tiger lillies.bar.dead calm.what"
    '("whammo" "Tiger Lillies" "Dead Calm"))

    ===>
    ((4 "Tiger Lillies") (22 "Dead Calm"))

    Given:

    (define-syntax fn*
    (syntax-rules ()
    [(_ (a b c ... . d) . z)
    (lambda (xs)
    (let-values (((a b c ... . d) (apply values xs))) . z))]
    [(_ (v ...) . z)
    (lambda (xs) (let-values (((v ...) (apply values xs))) . z))]
    [(_ (a . b) . z)
    (lambda (xs) (let ((a (car xs)) (b (cdr xs))) . z)) ]
    [(_ a . z) (lambda (a) . z) ] ))

    (define-syntax filter-map~
    (syntax-rules ()
    [(_ (v0 v1 ...) expr seq0 seq1 seq2 ...)
    (filter-map (lambda(v0 v1 ...) expr) seq0 seq1 seq2 ...) ]
    [(_ v expr seq) (filter-map (fn* v expr) seq) ] ))
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From B. Pym@Nobody447095@here-nor-there.org to comp.lang.lisp,comp.lang.scheme on Fri Aug 15 08:03:00 2025
    From Newsgroup: comp.lang.lisp

    B. Pym wrote:

    Pascal Bourguignon wrote:

    it to learn Lisp. Basically, for a list of book titles I wanted to return a list of position in text and the book title, so (build-book-index "wjhedbwjhbMarkajbdadbGenesis" books)

    gave: ((21 "Genesis") (10 "Mark")).

    I had an approach working but it looked horrid so I thought I would try loop. I came up with this:

    (defun build-book-index (text books)
    (loop for book in books
    when (search (string-downcase book) (string-downcase text)) collect
    (list it book)))

    Of course, ...collect it ... worked but the version above gave:

    in: LAMBDA NIL
    ; (LIST IT BOOK)
    ; caught WARNING: undefined variable: IT

    Is this expected?

    Yes.

    How can I get round it?

    Not using IT.

    (defun build-book-index (text books)
    (loop
    for book in books
    for my-it = (search (string-downcase book) (string-downcase text))
    when my-it collect (list my-it book)))

    Gauche Scheme

    (use srfi-13) ;; string-contains-ci

    (define (build-book-index text books)
    (filter-map~ book
    (let1 p (string-contains-ci text book)
    (and p (list p book)))
    books))

    (build-book-index "foo.tiger lillies.bar.dead calm.what"
    '("whammo" "Tiger Lillies" "Dead Calm"))

    ===>
    ((4 "Tiger Lillies") (22 "Dead Calm"))

    Given:

    (define-syntax fn*
    (syntax-rules ()
    [(_ (a b c ... . d) . z)
    (lambda (xs)
    (let-values (((a b c ... . d) (apply valuevs xs))) . z))]
    [(_ (v ...) . z)
    (lambda (xs) (let-values (((v ...) (apply values xs))) . z))]
    [(_ (a . b) . z)
    (lambda (xs) (let ((a (car xs)) (b (cdr xs))) . z)) ]
    [(_ a . z) (lambda (a) . z) ] ))

    (define-syntax filter-map~
    (syntax-rules ()
    [(_ (v0 v1 ...) expr seq0 seq1 seq2 ...)
    (filter-map (lambda(v0 v1 ...) expr) seq0 seq1 seq2 ...) ]
    [(_ v expr seq) (filter-map (fn* v expr) seq) ] ))

    Using an anaphoric macro:

    (define (build-book-index text books)
    (keep book (string-contains-ci text book) (list it book)
    books))

    Given:


    (define-macro keep
    (case-lambda
    ((pred seq) `(filter ,pred ,seq))
    ((v test expr seq)
    `(filter-map
    (lambda(,v) (let ((it ,test)) (and it ,expr)))
    ,seq))
    ((v test seq)
    `(filter (lambda(,v) ,test) ,seq))))
    --- Synchronet 3.21a-Linux NewsLink 1.2