• Re: Am I missing something about (loop ... maximizing ...) ?

    From B. Pym@21:1/5 to All on Sun Sep 8 07:03:27 2024
    XPost: comp.lang.scheme

    Raffael Cavallaro wrote:

    Indeed. Here's rob Warnock's version with the full boat of loop
    keywords using triplets instead of an association list:

    CL-USER 22 > (defun find-maximizing-item (list &key (key #'identity)
    (test #'<))
    (loop for item in list
    for value = (funcall key item)
    and position from 0
    for current-triplet = (list item value position)
    as max-triplet = current-triplet
    then (if (funcall test (second max-triplet)
    (second current-triplet))
    current-triplet
    max-triplet)
    finally return
    (values (first max-triplet) (second max-triplet) (third max-triplet))))


    Rejected by ABCL:

    Debugger invoked on condition of type PROGRAM-ERROR:

    Rejected by SBCL:

    ; A compound form was expected, but RETURN found.
    ; current LOOP context: FINALLY RETURN (VALUES (FIRST MAX-TRIPLET)
    ; (SECOND MAX-TRIPLET)
    ; (THIRD MAX-TRIPLET)).

    Gauche Scheme

    (use srfi-1) ;; second

    (define (maximizing-item the-list :key (key identity))
    (fold
    (lambda (item i best)
    (let ((value (key item)))
    (if (or (null? best) (> value (second best)))
    (list item value i)
    best)))
    '()
    the-list
    (lrange 0)))

    (maximizing-item '("bells" "usher" "ullalume" "poe") :key string-length)
    ===>
    ("ullalume" 8 2)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From B. Pym@21:1/5 to Raffael Cavallaro on Wed Jun 18 10:20:44 2025
    Raffael Cavallaro wrote:

    Indeed. Here's rob Warnock's version with the full boat of loop
    keywords using triplets instead of an association list:

    CL-USER 22 > (defun find-maximizing-item (list &key (key #'identity)
    (test #'<))
    (loop for item in list
    for value = (funcall key item)
    and position from 0
    for current-triplet = (list item value position)
    as max-triplet = current-triplet
    then (if (funcall test (second max-triplet)
    (second current-triplet))
    current-triplet
    max-triplet)
    finally return
    (values (first max-triplet) (second max-triplet)
    (third max-triplet))))


    Rejected by ABCL:

    Debugger invoked on condition of type PROGRAM-ERROR:

    Current LOOP context: "A compound form was expected, but ~S found.".


    Rejected by SBCL:

    ; in: LAMBDA NIL
    ; (LOOP FOR ITEM IN LIST
    ; FOR VALUE = (FUNCALL KEY ITEM)
    ; AND POSITION FROM ...)
    ;
    ; caught ERROR:
    ; (in macroexpansion of (LOOP FOR ITEM ...))
    ; (hint: For more precise location, try *BREAK-ON-SIGNALS*.)
    ; A compound form was expected, but RETURN found.
    ; current LOOP context: FINALLY RETURN (VALUES (FIRST MAX-TRIPLET)
    ; (SECOND MAX-TRIPLET)
    ; (THIRD MAX-TRIPLET)).



    FIND-MAXIMIZING-ITEM

    CL-USER 28 > (find-maximizing-item (list "one" "two" "three" "fifteen" "four" "five") :key #'length)
    "fifteen"
    7
    3


    It's somewhat shorter in Gauche Scheme.

    (use gauche.collection) ;; find-max

    (define (find-maximizing-item items :optional (key identity))
    (find-max
    (map (lambda (x i) (list x (key x) i)) items (liota))
    :key cadr))


    (find-maximizing-item (list "one" "two" "three" "fifteen" "four"
    "five") string-length)
    ===>
    ("fifteen" 7 3)

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)