[racket-dev] for/Type forms -> for/fold ([#:type type]) ...

From: J. Ian Johnson (ianj at ccs.neu.edu)
Date: Thu Oct 18 13:32:31 EDT 2012

I'm fairly frustrated every time I have to write
(for/fold ([res outer-set]) (guards ...) (set-add res (let () body ...)))

instead of the nicer
(for/set #:initial outer-set (guards ...) body ...)

I have also found myself wanting an analog to this for the for/hash form, since I extend hashes often in loops.
I almost wrote an email earlier asking for a #:default for the for/vector form, but I see that the pre-release has a #:fill. This is good.

Taking a closer look at the other for/* forms, it doesn't make sense to have an analog for the for/list* forms, since you might want to do the true recursive thing and add to the base list, or reverse the base list first and do the tail-recursive thing. Supporting both of these seems excessive.

There are also occasions that I want to give the accumulator a name that I can refer to.

This all fits a pattern that I think would be great for the for forms: user-defined accumulators. That is, instead of writing
(for/set (guards ...) body ...)

we could also write
(for/fold ([#:type set]) (guards ...) body ...)
or optionally
(for/fold ([#:type set [accumulator initial-value]]) (guards ...) body ...)
(for/fold ([#:type set accumulator]) (guards ...) body ...)
(for/fold ([#:type set #:initial initial-value]) (guards ...) body ...)

Now (for/lists (lst ...) gs b ...)is
(for/fold ([#:type list lst] ...) gs b ...)

This would allow for different positions in the values returned by body to be accumulated differently, according to the user-defined accumulator transform, and then managed after the loop by a post-process transform (to account for reversing the accumulated list in for/list, say). These would be associated with the syntax value of the type identifier.

I've rolled my own specialized forms of for/fold that handle different positions according to a special type, but I think it's time to extend the idea.

Does anyone else share my plight?

Also, samth: still waiting on your for/X/match macros to be released.
-Ian

Posted on the dev mailing list.