[racket] interaction between in-cycle and in-value

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Fri Aug 3 09:26:07 EDT 2012

At Fri, 03 Aug 2012 14:11:20 +0100, Tim Brown wrote:
> 
> (for ([j (in-range 10)] [i (in-cycle (in-range 3) (in-value (displayln 
> ".")))]) (displayln i))
>   stdout: ".\n0\n1\n2\n#<void>\n0\n1\n2\n#<void>\n0\n1\n"
> 
> Which suggests that the in-value is evaluated once printing a dot and
> returning #<void> -- then returning void (which is printed out with the
> (displayln i) clause.

More precisely, evaluation of the `in-value' call is evaluated once,
printing a dot and returning a sequence that contains #<void>.

> The documentation for in-cycle says:
> "where each seq is initiated afresh in each iteration"
> 
> Can (in-value ..) not be "initiated afresh"?
> Why not?
> Is there a bug in the documentation of (in-cycle)?
> Or should (in-value) be documented as "cannot be initiated afresh"?

I think you are confusing "initiating a sequence" with "evaluating an
expression".

Evaluation of an `in-cycle' call evaluates all of its arguments to
sequence values. The documentation for `in-cycle' doesn't say that
explicitly, but `in-cycle' is documented as a procedure, so `(in-cycle
....)' is a procedure call, and that's the way procedure calls work.

So, as you say, `(in-value (displayln "."))' is evaluated once to the
sequence that contains just #<void>, while `(in-range 3)' is evaluated
to the sequence that contains 1, 2, and 3. Those are put together into
a cycle sequence that is the result of `(in-cycle (in-range 3)
(in-value (displayln ".")))'.

As the cycle sequence's elements are requested, the sequence's
implementation initiates each of the given number and #<void> sequences
once per cycle. That means it restarts sequences of 1, 2, 3, and
#<void>. It doesn't (and can't) re-evaluate the expressions that
produced the sequences.

Hope that helps,
Matthew


Posted on the users mailing list.