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
	
	 Linus
						Linus