updated the documentation
Added stop-before, stop-after, in-cycle and in-indexed to the documentation. Also clarified (and examplified) the erathostenes example.
This commit is contained in:
parent
6f0c6e636f
commit
66e435aa92
2 changed files with 74 additions and 15 deletions
|
@ -25,22 +25,40 @@
|
|||
* A coherent, simple intefrace for accumulating data in loops, with support for accumulating data over sub-loops
|
||||
* A looping facility that in almost all cases produces as fast code as a hand-written named let
|
||||
* An extensible looping facility, where new ways of iterating over data can be easily added
|
||||
The only other lisp looping facility that I know of that provides these things is Common Lisps iterate package. Iterate does however do a lot of things that are cumbersome to do in portable scheme, and would be prohibitively complicated to implement efficiently in a portable way.
|
||||
|
||||
The only other lisp looping facility that I know of that provides these things is Common Lisps iterate package. Iterate does however do a lot of things that are cumbersome to do in portable scheme, and would be prohibitively complicated to implement efficiently in a portable way. Unless, of course, one considers CPS-conversion of arbitrary scheme code using syntax-rules simple.
|
||||
|
||||
<subsection title="An example or two">
|
||||
So, how does it look? A slightly contrived example, a naive sieve of Erathostenes:
|
||||
|
||||
<example>
|
||||
(define (erathostenes n)
|
||||
(define vec (make-vector n #t))
|
||||
(loop/list ((:for i (up-from 2 (to n)))
|
||||
(:when (vector-ref vec i)))
|
||||
(loop ((:for j (up-from (* 2 i) (to n) (by i))))
|
||||
(vector-set! vec j #f))
|
||||
i))
|
||||
(define vec (make-vector n #t))
|
||||
(loop/list ((:for i (up-from 2 (:to n)))
|
||||
(:when (vector-ref vec i)))
|
||||
;; Here we set all multiples of i to #f
|
||||
(loop ((:for j (up-from (* 3 i) (:to n) (:by (* i 2)))))
|
||||
(vector-set! vec j #f))
|
||||
i))
|
||||
</example>
|
||||
|
||||
Calling `(erathostenes 10)` returns a list of all primes below 10.
|
||||
|
||||
The example above can also be written using "subloops", but unless you know the expansion it can be somewhat surprising.
|
||||
|
||||
<example>
|
||||
(define (erathostenes n)
|
||||
(define vec (make-vector n #t))
|
||||
(loop ((:for i (up-from 2 (:to n)))
|
||||
(:acc lst (listing i))
|
||||
(:when (vector-ref vec i))
|
||||
(:for j (up-from (* 3 i) (:to n) (:by (* i 2))))
|
||||
=> lst
|
||||
(vector-set! vec j #f)))
|
||||
</example>
|
||||
|
||||
Any :for clause following a :break, :when, :unless or :final clause is considered to be a subloop. Any :when clause also affects when accumulating clauses collect values. The expression following => is the final expression: this is the expression returned after the loop ends.
|
||||
|
||||
</subsection>
|
||||
</section>
|
||||
|
||||
|
@ -316,6 +334,30 @@
|
|||
val)
|
||||
</example>
|
||||
</syntax>
|
||||
|
||||
<syntax name="in-cycle">
|
||||
<form>(:for binding (in-cycle iterator))</form>
|
||||
|
||||
Binds the values produced by `iterator` to `binding`. Once `iterator` stops, it starts over.
|
||||
</syntax>
|
||||
|
||||
<syntax name="in-indexed">
|
||||
<form>(:for binding (in-indexed iterator))</form>
|
||||
|
||||
Binds `binding` to `(n . value)`, where `n` is the nth value produced by `iterator` and `value` is that value. `n` starts from 0
|
||||
</syntax>
|
||||
|
||||
<syntax name="stop-before">
|
||||
<form>(:for binding (stop-before iterator pred))</form>
|
||||
|
||||
Binds `binding` to the values produced by `iterator` until `pred` applied to that value returns true. The iterator is then considered exhausted. Useful in subloops where one might want to end internal iteration without :break-ing.
|
||||
</syntax>
|
||||
|
||||
<syntax name="stop-after">
|
||||
<form>(:for binding (stop-after iterator pred))</form>
|
||||
|
||||
Binds `binding` to the values produced by `iterator` until `pred` applied to that value returns true. It then produces that last value. The iterator is then considered exhausted. Useful in subloops where one might want to end internal iteration without :break-ing.
|
||||
</syntax>
|
||||
</spec>
|
||||
|
||||
</subsection>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue