[racket] iteration for user-defined data structures

From: Sam Tobin-Hochstadt (samth at ccs.neu.edu)
Date: Wed Jun 1 08:51:02 EDT 2011

On Wed, Jun 1, 2011 at 8:40 AM, Marijn <hkBst at gentoo.org> wrote:
> I'm working on a doubly-linked list (dlist) implementation and have been
> able to succesfully implement the prop:sequence #:property, allowing the
> use of my data structure as a sequence, allowing for example to convert
> to an ordinary list with `for/list'. I'm trying to now do the converse,
> that is implement my own `for/dlist' for constructing dlists from
> sequences, but I am having some trouble with the docs.

There's basically a 3 step process here that I'd recommend here:

1. Write down a `for/fold' that would produce a dlist in the right
way. I'll illustrate this with simple list construction:

  (reverse (for/fold ([l null]) ([v seq]) (cons v l)))

This is just to give an idea of how to write step 2.

2. Abstract this into a macro:

  (define-syntax-rule (for/list clauses body ... expr)
     (reverse (for/fold ([l null]) clauses (begin body ... (cons expr l)))))

Now we're mostly done, although we probably want to write `for*/list'
along the same lines.

3. Improve the error messages by using `for/fold/derived':

  (define-syntax (for/list stx)
     (syntax-parse stx
        [(_ clauses body ... expr)
         #`(reverse (for/fold/derived #,stx ([l null]) clauses (begin
body ... (cons expr l))))]))

Note that `for/fold/derived' is *only* for error reporting, and we
didn't need to use `define-sequence-syntax' at all.  Instead, you
should use `define-sequence-syntax' to make `in-dlist' faster.

For examples, see
, where both a `for' macro and a version of `in-list' are defined.
sam th
samth at ccs.neu.edu

Posted on the users mailing list.