[racket] iteration for user-defined data structures
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
http://planet.plt-scheme.org/package-source/dvanhorn/ralist.plt/3/5/main.ss
, where both a `for' macro and a version of `in-list' are defined.
--
sam th
samth at ccs.neu.edu