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

From: J. Ian Johnson (ianj at ccs.neu.edu)
Date: Tue Mar 26 23:46:40 EDT 2013

I can't really test what you've posted (no stress-testing code), and you also compare safe versus unsafe accessors, which skews things.

I wanted to follow up apologizing to anyone who tried to use my library. I had not tested it thoroughly enough and didn't realize it does not work outside its own module. I've since fixed this and added the documentation in markdown format (Scribble does some weird extra ```racket additions with markdown that I had to manually remove, too. Dunno what that's about).
-Ian
----- Original Message -----
From: "Pierpaolo Bernardi" <olopierpa at gmail.com>
To: "J. Ian Johnson" <ianj at ccs.neu.edu>
Cc: "Tim Nelson" <tbnelson at gmail.com>, "users" <users at racket-lang.org>
Sent: Monday, March 25, 2013 10:42:28 AM GMT -05:00 US/Canada Eastern
Subject: Re: [racket] for/hash and for/list: adding nothing, adding more than one thing

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.