[racket] for/hash and for/list: adding nothing, adding more than one thing

From: Pierpaolo Bernardi (olopierpa at gmail.com)
Date: Mon Mar 25 10:42:28 EDT 2013

On Mon, Mar 25, 2013 at 2:41 PM, J. Ian Johnson <ianj at ccs.neu.edu> wrote:
> Let me know how you like my library. I'm thinking of adding some more ergonomics to it:
> 1) support right folds so a for/list-like comprehension has better allocation behavior.
> 2) add a keyword for-clause for starting an inner iteration so you don't have to do this:
> (for ([e0 (in-list l0)]
>       [e1 (in-list l1)])
>   (for ([e2 (in-list l2)]
>         [e3 (in-list l3)])
>     ...body...))
> but instead you can do this:
> (for ([e0 (in-list l0)]
>       [e1 (in-list l1)]
>       #:start-inner-loop ;; suggest a better name please
>       [e2 (in-list l2)]
>       [e3 (in-list l3)])
>   ...body...))

IMHO the first form is clearer.  I don't see any gain in the second one.

> I seem to remember that for* is not equivalent to successive nesting of for forms, but I can't remember how I reached this conclusion.

I have found, in one case, that performance of nested fors is
significantly better than a single for*, but I have not investigated
the cause. See the code fragment below.

Cheers
P.

(define (risolvi-2 sexomini)
  (let ((tabella (crea-tabella)))
    (let fansexomino ((sexomini sexomini))
      (cond ((null? sexomini)
             (eureka tabella))
            ((posizione-accettabile? tabella sexomini)
             (let ((sexomino (unsafe-first sexomini)))
               (for ((orientazione (in-list sexomino)))
                 (let ((forma (unsafe-first orientazione)))
                   (for ((posizione (in-list (unsafe-rest orientazione))))
                     (when (compatibile? forma posizione tabella)
                       (let* ((x (posizione-x posizione))
                              (y (posizione-y posizione))
                              (v (unsafe-vector-ref tabella x)))
                         (unsafe-vector-set! v y forma)
                         (fansexomino (unsafe-rest sexomini))
                         (unsafe-vector-set! v y #f))))))))))))

#|
;; risolvi-2 is faster
(define (risolvi-3 sexomini)
  (let ((tabella (crea-tabella)))
    (let fansexomino ((sexomini sexomini))
      (cond ((null? sexomini)
             (eureka tabella))
            ((posizione-accettabile? tabella sexomini)
             (for* ((sexomino (in-value (first sexomini)))
                    (orientazione (in-list sexomino))
                    (forma (in-value (first orientazione)))
                    (posizione (in-list (rest orientazione)))
                    #:when (compatibile? forma posizione tabella)
                    (x (in-value (posizione-x posizione)))
                    (y (in-value (posizione-y posizione)))
                    (v (in-value (vector-ref tabella x))))
               (vector-set! v y forma)
               (fansexomino (rest sexomini))
               (vector-set! v y #f)))))))
|#

Posted on the users mailing list.