• Re: SBCL complains where Lispwork does not: loop for i for j

    From B. Pym@Nobody447095@here-nor-there.org to comp.lang.lisp on Sun Aug 24 15:29:33 2025
    From Newsgroup: comp.lang.lisp

    B. Pym wrote:

    Jochen wrote:

    This ...

    CL-USER 1 > (loop for i for j in '(a b c) collect (cons i j))
    ((0 . A) (1 . B) (2 . C))

    works perfectly on LispWorks, but not with SBCL

    FOR is an unknown keyword in FOR or AS clause in LOOP.

    I found a way around it 'for i from 0' but am not sure if there is another smarter way to achieve this.

    I think the canonical way would be

    (loop for i upfrom 0
    for j in '(a b c)
    collect (cons i j))

    newLISP

    (map (curry list $idx) '(a b c))

    ((0 a) (1 b) (2 c))

    Gauche Scheme

    (let ((i (makeigen)) (col (makelbag)))
    (dolist (j '(a b c)) (col (cons (i) j)))
    (col))

    ((0 . a) (1 . b) (2 . c))

    Given:

    ;; Make an integer generator.
    (define (makeigen :optional (start 0) (step #f) (m #f))
    (let ((i start)
    (s step)
    (m m)) ;; mod
    (if m
    (lambda () (begin0 (mod i m) (inc! i s)))
    (if s
    (lambda () (begin0 i (inc! i s)))
    (lambda () (begin0 i (inc! i)))))))

    (define (makelbag :optional (raw #f) (pass-through #t))
    (let ((bag '()))
    (lambda args
    (if (null? args)
    (if raw bag (reverse bag))
    (if pass-through
    (begin0 (car args) (push! bag (car args)))
    (push! bag (car args)))))))
    --
    [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 tpeplt@tpeplt@gmail.com to comp.lang.lisp on Sun Aug 24 14:53:01 2025
    From Newsgroup: comp.lang.lisp


    Jochen wrote:

    This ...

    CL-USER 1 > (loop for i for j in '(a b c) collect (cons i j))
    ((0 . A) (1 . B) (2 . C))

    works perfectly on LispWorks, but not with SBCL

    FOR is an unknown keyword in FOR or AS clause in LOOP.

    I found a way around it 'for i from 0' but am not sure if there is
    another smarter way to achieve this.

    I think the canonical way would be

    (loop for i upfrom 0
    for j in '(a b c)
    collect (cons i j))

    When variables iterate independently, they can be joined by
    rCy:andrCO or rCyandrCO in place of the subsequent rCyforrCO.

    For example, (colons added for emphasis):

    (loop
    :for i :upfrom 0 :and j :in '(a b c)
    :collect (cons i j))
    ((0 . A) (1 . B) (2 . C))

    Both control when the loop ends, so the first iterating
    expression can be the constraint on when to stop...

    (loop
    for i below 2 :and j in '(a b c)
    collect (cons i j))
    ((0 . A) (1 . B))

    ...or the second iterating expression can be the constraint
    on when to stop:

    (loop
    for i below 1000 :and j in '(a b c)
    collect (cons i j))
    ((0 . A) (1 . B) (2 . C))

    (loop
    for i downfrom 9 :and j in '(a b c)
    collect (cons i j))
    ((9 . A) (8 . B) (7 . C))

    See http://www.ai.mit.edu/projects/iiip/doc/CommonLISP/HyperSpec/Body/sec_6-1-2-1.html

    "If multiple iteration clauses are used to control
    iteration, variable initialization and stepping[1] occur
    sequentially by default. The AND construct can be used to
    connect two or more iteration clauses when sequential
    binding and stepping[1] are not necessary. The iteration
    behavior of clauses joined by AND is analogous to the
    behavior of the macro DO with respect to DO*."
    --
    The lyf so short, the craft so long to lerne.
    - Geoffrey Chaucer, The Parliament of Birds.
    --- Synchronet 3.21a-Linux NewsLink 1.2
  • From B. Pym@Nobody447095@here-nor-there.org to comp.lang.lisp on Sun Aug 24 22:02:51 2025
    From Newsgroup: comp.lang.lisp

    B. Pym wrote:

    Jochen wrote:

    This ...

    CL-USER 1 > (loop for i for j in '(a b c) collect (cons i j))
    ((0 . A) (1 . B) (2 . C))

    works perfectly on LispWorks, but not with SBCL

    FOR is an unknown keyword in FOR or AS clause in LOOP.

    I found a way around it 'for i from 0' but am not sure if there is another smarter way to achieve this.

    I think the canonical way would be

    (loop for i upfrom 0
    for j in '(a b c)
    collect (cons i j))

    Gauche Scheme

    "!" is somewhat like "do" except that it is optimized
    for brevity. So this is shorter than the "loop" solution.

    (! (r cons (cons i j)
    i 0 +
    j :in '(a b c))
    (not j) @)

    ((0 . a) (1 . b) (2 . c))

    Given:

    (define-syntax !-aux
    (syntax-rules (<> @ + - cons cdr :in :across :if ! )
    [(_ (:if bool z ...) ((v i u) seen ...) stuff ...)
    (!-aux (z ...)
    ((v i (if bool u v)) seen ...) stuff ...) ]
    [(_ (x :in lst z ...) seen (lets ...) stuff ...)
    (!-aux (x (and (pair? xs)(pop! xs)) <> z ...)
    seen
    (lets ... (xs lst)) stuff ...) ]
    [(_ (x :across vec z ...) seen (lets ...) stuff ...)
    (!-aux (x (and (< i (vector-length v))
    (begin0 (vector-ref v i) (inc! i))) <>
    z ...)
    seen (lets ... (v vec) (i 0)) stuff ...) ]
    [(_ (a b <> z ...) (seen ...) stuff ...)
    (!-aux (z ...) (seen ... (a b b)) stuff ...) ]
    [(_ (a b + z ...) (seen ...) stuff ...)
    (!-aux (z ...) (seen ... (a b (+ 1 a))) stuff ...) ]
    [(_ (a + n z ...) (seen ...) stuff ...)
    (!-aux (z ...) (seen ... (a 0 (+ n a))) stuff ...) ]
    [(_ (a b - z ...) (seen ...) stuff ...)
    (!-aux (z ...) (seen ... (a b (- a 1))) stuff ...) ]
    [(_ (a cons b z ...) (seen ...) stuff ...)
    (!-aux (z ...) (seen ... (a '() (cons b a))) stuff ...) ]
    [(_ (a b cdr z ...) (seen ...) stuff ...)
    (!-aux (z ...) (seen ... (a b (cdr a))) 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 ...) ]
    ;;
    [(_ () seen lets a b c ! action ...)
    (!-aux () seen lets (a b c) #t (action ...)) ]
    [(_ () seen lets a b ! action ...)
    (!-aux () seen lets (a b) #t (action ...)) ]
    [(_ () seen lets a ! action ...)
    (!-aux () seen lets a #t (action ...)) ]
    ;;
    [(_ () ((a b c) z ...) lets bool)
    (!-aux () ((a b c) z ...) lets bool 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 z ...) stuff ...)
    (!-aux () seen lets bool (what (reverse x) z ...) stuff ...) ]
    [(_ () seen lets bool (what x ... @ z) stuff ...)
    (!-aux () seen lets bool (what x ... (reverse 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 ...) ]
    ))
    --
    [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