Changes for the better
* goof-impl.scm (loop/first loop/last): add ability to specify a :default value. Added auxiliary syntax :default. * goof/iterators.scm (accumulating hash(q|v)ing): changed auxiliary keyword from initial -> :initial. * goof.scm: export extra keywords * doc.html * doc.xml : document changes. fix bugs.
This commit is contained in:
parent
1de0a624f5
commit
832c414260
6 changed files with 77 additions and 61 deletions
|
@ -106,7 +106,7 @@
|
|||
<example>
|
||||
(loop ((:for a (in-list '(1 2 3)))
|
||||
:subloop
|
||||
(:for b (up-from 0 (to a)))
|
||||
(:for b (up-from 0 (:to a)))
|
||||
(:acc acc (listing (cons a b)))))
|
||||
|
||||
;; => ((1 . 0) (2 . 0) (2 . 1) (3 . 0) (3 . 1) (3 . 2))
|
||||
|
@ -117,7 +117,7 @@
|
|||
<example>
|
||||
(loop ((:for a (in-list '(1 2 3)))
|
||||
(:break (= 3 a))
|
||||
(:for b (up-from 0 (to a)))
|
||||
(:for b (up-from 0 (:to a)))
|
||||
(:acc acc (listing (cons a b)))))
|
||||
|
||||
;; => ((1 . 0) (2 . 0) (2 . 1))
|
||||
|
@ -128,10 +128,10 @@
|
|||
<example>
|
||||
(loop ((:for a (in-list '(1 2 3 4)))
|
||||
(:final (= 3 a))
|
||||
(:for b (up-from 0 (to a)))
|
||||
(:for b (up-from 0 (:to a)))
|
||||
(:acc acc (listing (cons a b)))))
|
||||
|
||||
;; => ((1 . 0) (2 . 0) (2 . 1) (3 . 0) (3 . 1))
|
||||
;; => ((1 . 0) (2 . 0) (2 . 1) (3 . 0) (3 . 1) (3 . 2))
|
||||
</example>
|
||||
|
||||
The :final clause is actually equivalent to something alike the following:
|
||||
|
@ -182,7 +182,7 @@
|
|||
The pure `loop` macro is quite a big hammer for most tasks. Often we want to do simple things, like collect elements into a list or a vector, which means the extra housekeeping of separating accumulators and for clauses are too much heavy lifting. goof-loop provides several simpler forms that can be used in those cases. In these simpler forms :acc is disallowed, and everything not identified as anything else is assumed to be a :for clause. The loop below accumulates the 100 first fibonacci numbers into a list.
|
||||
|
||||
<example>
|
||||
(loop/list ((count (up-from 0 (to 100)))
|
||||
(loop/list ((count (up-from 0 (:to 100)))
|
||||
(a (in 0 b))
|
||||
(b (in 1 (+ a b))))
|
||||
b)
|
||||
|
@ -192,15 +192,15 @@
|
|||
|
||||
<spec>
|
||||
<syntax name="loop/first">
|
||||
<form>(loop/first (clauses ...) body ...)</form>
|
||||
<form>(loop/first [:default #f] (clauses ...) body ...)</form>
|
||||
|
||||
If any body is ever evaluated, stop and return the value of that evaluation. If no body is ever evaluated the return value is unspecified.
|
||||
If any body is ever evaluated, stop and return the value of that evaluation. If no body is evaluated it returns the value specified by `:default`, which defaults to #f.
|
||||
</syntax>
|
||||
|
||||
<syntax name="loop/last">
|
||||
<form>(loop/last (clauses ...) body ...)</form>
|
||||
<form>(loop/last [:default #f] (clauses ...) body ...)</form>
|
||||
|
||||
Returns the result of the last body to be evaluated. If no body is evaluated the return value is unspecified.
|
||||
Returns the result of the last body to be evaluated. If no body is evaluated it returns the value specified by `:default`, which defaults to #f.
|
||||
</syntax>
|
||||
|
||||
<syntax name="loop/list">
|
||||
|
@ -392,69 +392,69 @@
|
|||
|
||||
<spec>
|
||||
<syntax name="listing">
|
||||
<form>(:acc binding (listing [(initial init)] expr [if guard]))</form>
|
||||
<form>(:acc binding (listing [(:initial init)] expr [if guard]))</form>
|
||||
|
||||
Accumulates `expr` into a list. ´binding` is only accesible in the final-expression. The list is in the same order as the loop bodies were evaluated. If `initial` is given that will be used as the tail of the accumulated results. It defaults to `'()`.
|
||||
</syntax>
|
||||
|
||||
<syntax name="listing-reverse">
|
||||
<form>(:acc binding (listing-reverse [(initial init)] expr [if guard]))</form>
|
||||
<form>(:acc binding (listing-reverse [(:initial init)] expr [if guard]))</form>
|
||||
|
||||
The same as `listing` but the resulting list in in reverse order. If the order of the resulting list does not matter, this will be faster than the regular listing as it will not preform any reverse at the end.
|
||||
</syntax>
|
||||
|
||||
<syntax name="appending">
|
||||
<form>(:acc binding (appending [(initial init)] expr [if guard]))</form>
|
||||
<form>(:acc binding (appending [(:initial init)] expr [if guard]))</form>
|
||||
|
||||
`expr` evaluates to a list that is then appended to the accumulated result.
|
||||
|
||||
<example>
|
||||
(loop ((:for elt (in-list '((1 2) (3 4))))
|
||||
(:acc acc (appending (initial '(0)) elt)))
|
||||
(:acc acc (appending (:initial '(0)) elt)))
|
||||
=> acc)
|
||||
;; => (0 1 2 3 4)
|
||||
</example>
|
||||
</syntax>
|
||||
|
||||
<syntax name="appending-reverse">
|
||||
<form>(:acc binding (appending-reverse [(initial init)] expr [if guard]))</form>
|
||||
<form>(:acc binding (appending-reverse [(:initial init)] expr [if guard]))</form>
|
||||
|
||||
`expr` evaluates to a list that is then consed element by element onto the already accumulated results. The default initial value is `'()`.
|
||||
|
||||
<example>
|
||||
(loop ((:for elt (in-list '((1 2) (3 4))))
|
||||
(:acc acc (appending-reverse (initial '(0)) elt)))
|
||||
(:acc acc (appending-reverse (:initial '(0)) elt)))
|
||||
=> acc)
|
||||
;; => (4 3 2 1 0)
|
||||
</example>
|
||||
</syntax>
|
||||
|
||||
<syntax name="summing">
|
||||
<form>(:acc binding (summing [(initial init)] expr [(if guard)]))</form>
|
||||
<form>(:acc binding (summing [(:initial init)] expr [(if guard)]))</form>
|
||||
|
||||
Adds the result of `expr` together using `+`. The default initial value is 0.
|
||||
</syntax>
|
||||
|
||||
<syntax name="multiplying">
|
||||
<form>(:acc binding (multiplying [(initial init)] expr [(if guard)]))</form>
|
||||
<form>(:acc binding (multiplying [(:initial init)] expr [(if guard)]))</form>
|
||||
|
||||
Multiplies the result of `expr` using `*`. The default initial value is 1.
|
||||
</syntax>
|
||||
|
||||
<syntax name="hashing">
|
||||
<form>(:acc binding (hashing [(initial init)] key value [(if guard)]))</form>
|
||||
<form>(:acc binding (hashing [(:initial init)] key value [(if guard)]))</form>
|
||||
|
||||
Adds the mapping `(key => value)` to the hashtable `binding` using equal?-hashing. The initial hash table is an empty hash-table. `binding` is bound to the hash table throughout the loop, and its content can be mutated in the loop body.
|
||||
</syntax>
|
||||
|
||||
<syntax name="hashving">
|
||||
<form>(:acc binding (hashving [(initial init)] key value [(if guard)]))</form>
|
||||
<form>(:acc binding (hashving [(:initial init)] key value [(if guard)]))</form>
|
||||
|
||||
Adds the mapping `(key => value)` to the hashtable `binding` using eqv?-hashing. The initial hash table is an empty hash-table. `binding` is bound to the hash table throughout the loop, and its content can be mutated in the loop body.
|
||||
</syntax>
|
||||
|
||||
<syntax name="hashqing">
|
||||
<form>(:acc binding (hashqing [(initial init)] key value [(if guard)]))</form>
|
||||
<form>(:acc binding (hashqing [(:initial init)] key value [(if guard)]))</form>
|
||||
|
||||
Adds the mapping `(key => value)` to a hashtable using eq?-hashing. The initial hash table is an empty hash-table.`binding` is bound to the hash table throughout the loop, and its can be mutated in the loop body.
|
||||
</syntax>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue