• re: Stumped (basic LISP question)

    From B. Pym@Nobody447095@here-nor-there.org to comp.lang.lisp,comp.lang.scheme on Sun Aug 10 13:13:20 2025
    From Newsgroup: comp.lang.lisp

    Pierre R. Mai wrote:

    I need to write a function that takes in a list and a function, tests the function over each of the members of the list and returns two lists : one list is of the members where the function evaluates to true and the other is where the function evaluates to false.

    The simplest form of the function might be one based on the built-in function "remove-if" and an appropriate use of the built-in function "complement". See the CLHS for information on both.

    Another very simple way, which should also be of "optimal" performance
    (i.e. O(n)), is to use LOOP:

    (defun foo (list predicate)
    (loop for item in list
    if (funcall predicate item) collect item into successes
    else collect item into failures
    finally (return (values successes failures))))

    Gauche Scheme

    (define (segregate List test)
    (Do (yes no)
    ((null? List) @ (values yes no))
    (let1 item (pop! List)
    (if (test item) (push! yes item) (push! no item)))))

    (segregate '(0 2 3 4 7) odd?)
    ===>
    (3 7)
    (0 2 4)

    Given:

    (define (reverse~ x) (if (pair? x) (reverse x) x))

    (define-syntax Do-aux
    (syntax-rules (<> @ values)
    [(_ ((a b <>) d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a b b)) z ...) ]
    [(_ ((a b c) d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a b c)) z ...) ]
    [(_ ((a b) d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a b)) z ...) ]
    [(_ ((a) d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a '())) z ...) ]
    [(_ (a d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a '())) z ...) ]
    [(_ () seen (a b ... @ (values x ...)) z ...)
    (Do-aux () seen (a b ... (values (reverse~ x) ...)) z ...) ]
    [(_ () seen (a b ... @ xs) z ...)
    (Do-aux () seen (a b ... (reverse xs)) z ...) ]
    [(_ () seen till body ...)
    (do seen till body ...) ]))
    (define-syntax Do
    (syntax-rules ()
    [(_ specs till body ...)
    (Do-aux specs () till body ...) ]))
    --
    [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 Mon Aug 11 14:27:16 2025
    From Newsgroup: comp.lang.lisp

    B. Pym wrote:

    Pierre R. Mai wrote:

    I need to write a function that takes in a list and a function, tests the
    function over each of the members of the list and returns two lists : one
    list is of the members where the function evaluates to true and the other
    is where the function evaluates to false.

    The simplest form of the function might be one based on the built-in function "remove-if" and an appropriate use of the built-in function "complement". See the CLHS for information on both.

    Another very simple way, which should also be of "optimal" performance (i.e. O(n)), is to use LOOP:

    (defun foo (list predicate)
    (loop for item in list
    if (funcall predicate item) collect item into successes
    else collect item into failures
    finally (return (values successes failures))))

    Gauche Scheme

    (define (segregate List test)
    (Do (yes no)
    ((null? List) @ (values yes no))
    (let1 item (pop! List)
    (if (test item) (push! yes item) (push! no item)))))

    (segregate '(0 2 3 4 7) odd?)
    ===>
    (3 7)
    (0 2 4)

    Given:

    (define (reverse~ x) (if (pair? x) (reverse x) x))

    (define-syntax Do-aux
    (syntax-rules (<> @ values)
    [(_ ((a b <>) d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a b b)) z ...) ]
    [(_ ((a b c) d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a b c)) z ...) ]
    [(_ ((a b) d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a b)) z ...) ]
    [(_ ((a) d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a '())) z ...) ]
    [(_ (a d ...) (seen ...) z ...)
    (Do-aux (d ...) (seen ... (a '())) z ...) ]
    [(_ () seen (a b ... @ (values x ...)) z ...)
    (Do-aux () seen (a b ... (values (reverse~ x) ...)) z ...) ]
    [(_ () seen (a b ... @ xs) z ...)
    (Do-aux () seen (a b ... (reverse xs)) z ...) ]
    [(_ () seen till body ...)
    (do seen till body ...) ]))
    (define-syntax Do
    (syntax-rules ()
    [(_ specs till body ...)
    (Do-aux specs () till body ...) ]))

    Shorter:

    (define (segregate List test)
    (Do (yes no)
    ((null? List) @ (values yes no))
    (push-to-either! yes no test (pop! List))))

    Given:

    (define-syntax push-to-either!
    (syntax-rules ()
    [(_ a b pred x)
    (let ((val x))
    (if (pred val)
    (set! a (cons val a))
    (set! b (cons val b)))) ] ))
    --
    The good news is, it's not Lisp that sucks, but Common Lisp. --- Paul Graham --- Synchronet 3.21a-Linux NewsLink 1.2