• Re: Bad Idiom?

    From B. Pym@Nobody447095@here-nor-there.org to comp.lang.lisp on Fri Aug 29 06:50:51 2025
    From Newsgroup: comp.lang.lisp

    Riesbeck wrote:

    Barry Margolin wrote:

    IMHO, any LOOP use that's more than about a half dozen lines long is probably too complex. As I said in my other posting, LOOP is most useful when you're using one or two of its built-in features that doesn't exist in any other CL constructs. I wouldn't ever write

    (loop for x in list collect (f x))

    since this is better written as (mapcar #'f list). But I would write

    (loop for i from 1 to n collect (f i))

    because there's no other concise way to express this. And you don't have

    Gauche Scheme

    (map square (lrange 1 5))
    ===>
    (1 4 9 16)


    (map square (iota 4 1))
    ===>
    (1 4 9 16)


    (use gauche.generator)
    (generator-map square (grange 1 5))
    ===>
    (1 4 9 16)


    (use srfi-1)
    (list-tabulate 4 (^i (square (+ 1 i))))
    ===>
    (1 4 9 16)


    (do ((i 4 (- i 1))
    (r () (cons (square i) r)))
    ((= 0 i) r))
    ===>
    (1 4 9 16)


    (use srfi-42)
    (list-ec (:range i 1 5) (square i))
    ===>
    (1 4 9 16)


    "!" is similar to "do".

    (! (r cons (square i) i 1 :to 4) @)
    ===>
    (1 4 9 16)


    (let1 r ()
    (dotimes (i 4 (reverse r)) (push! r (square (+ 1 i)))))
    ===>
    (1 4 9 16)


    (use srfi-1)
    (unfold (cut = <> 5) square (cut + 1 <>) 1)
    ===>
    (1 4 9 16)


    (let r ((i 1)) (if (> i 4) () (cons (square i) (r (+ 1 i)))))
    ===>
    (1 4 9 16)


    Another very common situation that's much more readable in
    LOOP (IMHO) than alternatives like REMOVE-IF-NOT is

    (loop for x in l when (testp x) collect x)

    (remove-if-not 'oddp '(1 2 3 4 5 7))
    ===>
    (1 3 5 7)

    Gauche Scheme

    (filter even? (iota 8))

    (0 2 4 6)
    --
    [T]he problem is that lispniks are as cultish as any other devout group and basically fall down frothing at the mouth if they see [heterodoxy].
    --- Kenny Tilton
    The good news is, it's not Lisp that sucks, but Common Lisp. --- Paul Graham --- 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 29 08:40:18 2025
    From Newsgroup: comp.lang.lisp

    B. Pym wrote:

    "!" is similar to "do".

    (! (r cons (square i) i 1 :to 4) @)
    ===>
    (1 4 9 16)

    Shorter:

    (! (r cons (square i) i 1 :to 4))

    Given:

    (define-syntax !-aux
    (syntax-rules (<> @ @@ + - : cons append :meld
    cdr :in :across :along
    :on :by :pop-or-nothing
    :if :if-else ! :also? :also :to
    :till :always
    :let := )
    [(_ specs seen lets @)
    (!-aux specs seen lets #f @) ]
    [(_ (:let id val z ...) seen (lets ...) stuff ...)
    (!-aux (z ...) seen (lets ... (id val)) stuff ...) ]
    [(_ (:= id val z ...) stuff ...)
    (!-aux (:let id #f dummy #f (set! id val) z ...) stuff ...) ]
    ;;
    [(_ (:also? bool op x z ...) (seen ... (v i update)) stuff ...)
    (!-aux (z ...)
    (seen ... (v i (if bool (op x update) update)))
    stuff ...) ]
    [(_ (:also op x z ...) stuff ...)
    (!-aux (:also? #t op x z ...) stuff ...) ]
    ;;
    [(_ ((:pop-or-nothing x xs nil) z ...) stuff ...)
    (!-aux (x (if (pair? xs)(pop! xs) nil) <> z ...) stuff ...) ]
    ;;
    ;;
    [(_ (:always expr z ...) seen lets bool)
    (!-aux (ok #t expr
    :till (not ok)
    z ...)
    seen lets bool ok
    ) ]
    [(_ (:always expr z ...) stuff ...)
    (!-aux " * * * Bad usage of :always in !") ]
    [(_ (:till expr z ...) seen lets #f stuff ...)
    (!-aux (z ...) seen lets expr stuff ...) ]
    [(_ (:till expr z ...) seen lets bool stuff ...)
    (!-aux (z ...) seen lets (or expr bool) stuff ...) ]
    ;;
    [(_ (:if bool z ...) (seen ... (v i u)) stuff ...)
    (!-aux (z ...)
    (seen ... (v i (if bool u v))) stuff ...) ]
    ;;
    [(_ (:if-else bool z ...) (seen ... (a b c)(d e f)) stuff ...)
    (!-aux (:let yes #f z ...)
    (seen ... (a b (begin (set! yes bool) (if yes c a)))
    (d e (if (not yes) f d))) stuff ...) ]
    ;;
    [(_ ((a b ...) :on lst :by kdr z ...) stuff ...)
    (!-aux (:let xs lst
    :let ys #f
    exhausted (null? xs) <>
    dummy (begin (set! ys xs)
    (when (pair? xs) (set! xs (kdr xs)))) <>
    (:pop-or-nothing a ys #f)
    (:pop-or-nothing b ys #f) ...
    :till exhausted
    z ...) stuff ...) ]
    [(_ ((a b ...) :on lst z ...) stuff ...)
    (!-aux ((a b ...) :on lst :by cdr z ...) stuff ...) ]
    ;;
    [(_ (x :in lst z ...) stuff ...)
    (!-aux (:let xs lst
    x (if (pair? xs)(pop! xs) !-aux) <>
    :till (eq? x !-aux)
    z ...) stuff ...) ]
    ;;
    [(_ (x :across vec z ...) stuff ...)
    (!-aux (:let v vec :let i 0
    x (if (< i (vector-length v))
    (begin0 (vector-ref v i) (inc! i))
    !-aux) <>
    :till (eq? x !-aux)
    z ...) stuff ...) ]
    [(_ (ch :along str z ...) stuff ...)
    (!-aux (:let s str :let i 0
    ch (and (< i (string-length s))
    (begin0 (string-ref s i) (inc! i))) <>
    :till (not ch)
    z ...)
    stuff ...) ]
    [(_ (a b <> z ...) stuff ...)
    (!-aux (a b b z ...) stuff ...) ]
    ;;
    [(_ (a b + z ...) stuff ...)
    (!-aux (a b (+ 1 a) z ...) stuff ...) ]
    [(_ (a + n z ...) stuff ...)
    (!-aux (a 0 (+ n a) z ...) stuff ...) ]
    [(_ (a b - z ...) stuff ...)
    (!-aux (a b (- a 1) z ...) stuff ...) ]
    [(_ (n lo inc :to hi z ...) stuff ...)
    (!-aux (:let step inc :let high hi
    n lo (+ n step)
    :till (> n high)
    z ...) stuff ...) ]
    [(_ (n lo :to hi z ...) stuff ...)
    (!-aux (n lo 1 :to hi z ...) stuff ...) ]
    ;;
    [(_ (v init : kons u z ...) stuff ...)
    (!-aux (v init (kons u v) z ...) stuff ...) ]
    ;;
    [(_ (a cons b z ...) stuff ...)
    (!-aux (a '() : cons b z ...) stuff ...) ]
    [(_ (a append b z ...) stuff ...)
    (!-aux (a '() : append b z ...) stuff ...) ]
    [(_ (a :meld b z ...) stuff ...)
    (!-aux (a '()
    (if (pair? b) (append (reverse b) a)
    (cons b a))
    z ...) stuff ...) ]
    ;;
    [(_ (a b cdr z ...) stuff ...)
    (!-aux (a b (cdr a) z ...) stuff ...) ]
    [(_ (a b c z ...) (seen ...) stuff ...)
    (!-aux (z ...) (seen ... (a b c)) stuff ...) ]
    [(_ (a b) (seen ...) stuff ...)
    (!-aux () (seen ... (a b)) stuff ...) ]
    [(_ (a) (seen ...) stuff ...)
    (!-aux () (seen ... (a '())) stuff ...) ]
    ;; Default action is print first variable.
    [(_ () ((a b c) z ...) lets bool !)
    (!-aux () ((a b c) z ...) lets bool ! print a) ]
    ;; (!-aux () ((a b c) z ...) lets bool ! begin (print a)(sys-sleep 1)) ]
    [(_ () seen lets bool ! action ...)
    (!-aux () seen lets bool #t (action ...)) ]
    ;; If result not specified, pick one.
    [(_ () ((a b c) z ...) lets bool)
    (!-aux () ((a b c) z ...) lets bool
    (if (pair? a) (reverse a) a)) ]
    [(_ () ((a b c) z ...) lets bool @)
    (!-aux () ((a b c) z ...) lets bool (reverse a)) ]
    [(_ () seen lets bool @ result stuff ...)
    (!-aux () seen lets bool (reverse result) stuff ...) ]
    ;;
    [(_ () seen lets bool @@ (what x ...) stuff ...)
    (!-aux () seen lets bool (what (reverse x) ...) stuff ...) ]
    [(_ () seen lets bool (what @ x z ...) stuff ...)
    (!-aux () seen lets bool (what (reverse x) z ...) stuff ...) ]
    [(_ () seen lets bool (what x @ y z ...) stuff ...)
    (!-aux () seen lets bool (what x (reverse y) z ...) stuff ...) ]
    ;;
    [(_ () ((a b c) z ...) lets 0 stuff ...)
    (!-aux () ((a b c) z ...) lets (= 0 a) stuff ...) ]
    [(_ () seen lets bool result stuff ...)
    (let lets (do seen (bool result) stuff ...)) ]
    ))
    (define-syntax !
    (syntax-rules ()
    [(_ specs bool stuff ...)
    (!-aux specs () () bool stuff ...) ]
    [(_ specs) (! specs #f) ]
    ))
    --
    [T]he problem is that lispniks are as cultish as any other devout group and basically fall down frothing at the mouth if they see [heterodoxy].
    --- Kenny Tilton
    The good news is, it's not Lisp that sucks, but Common Lisp. --- Paul Graham --- Synchronet 3.21a-Linux NewsLink 1.2