[plt-scheme] for.ss

From: David Einstein (deinst at gmail.com)
Date: Sat Sep 22 10:38:39 EDT 2007

On 9/20/07, Jens Axel Søgaard <jensaxel at soegaard.net> wrote:
> David Einstein wrote:
> > I am glad to see that plt is considering including some comprehension
> > macros.  I realize that they are not yet final, but I have some comments.
> >
> > A) The behavior of in-range seems to have been inherited from srfi-42
> > and python.  In my opinion it is one of the few things that python gets
> > wrong.  If you assign problems 7 through 9 as homework to your students,
> > do you really expect them to hand back just problems 7 and 8?  (These
> > would be abstract ideal students.)
> ad A)
> Given a vector (or string or byte-string) v it common to iterate through
> the indices 0, 1, ... (- (vector-length v) 1). Convenience of the
> common case therefore dictates the last index in the range to be
> excluded.

There are three reasons to create a comprehension macro (or any DSL in
general), convenience, conciseness, and clarity.  The further I
incoherently stagger along the path toward geezerdom, the more I value
clarity over convenience or conciseness.  I, and I suspect many
others, spend much more time pondering what my code is doing and how
to make it do what I want than I spend typing the code in.  I do not
want to have to type or read extraneous cruft, but I do not want to
have to remember that (in-range 0 9) means (0 1 2 3 4 5 6 7 8).

I think that Swindle's solution of appending a < is reasonable, I do
not think that I would be as prone to misinterpret in-range<.

>  > D)  A 'for*/seq'  form that takes a set of nested sequences and
>  > returns a generator for all the values of the nested would be useful.
>  > I've been trying to get one integrated into Jens' srfi-42 rewrite
>  > using William Farr's multiple value yield, but my macro skills are not
>  > yet up to the task.
> ad D)
> Do you have an example of the intended behaviour?

What I would like is for
(do-ec (:nested (: a 1 10) (: b 10) (if (= 1 (gcd a b)))) (printf "~a
~a ~n" a b))
to turn into something related to

(let-values ([(fun done a b)
              (let/cc ret
                (do-ec (: a 1 10) (: b 1 10) (if (= 1 (gcd a b)))
                       (let/cc enter (call-with-values (lambda ()
(values enter #f a b)) ret)))
                (call-with-values (lambda () (values #f #t #f #f)) ret))])
  (let loop ([fun fun][done done][a a][b b])
    (if (not done)
          (printf "~a ~a ~n" a b)
          (loop (fun))))))

A few questions.
1) My way of detecting the termination condition is a kludge.  Is
there a better way?

2)  I cannot figure out how to get a list of the variables named in
the generators used in the nested loop.

3)  There should be some way of having the macro generate equivalent
code without using call/cc.  Would this be worth the trouble?

> --
> Jens Axel Søgaard

Posted on the users mailing list.