Here is the code:
! TODO:
! Define unit tests
! help files
! signatures
! parsing words
IN: series
USING: math words sequences kernel tools quotations arrays ;
TUPLE: il list quote ; ! il = infinite list
: get-il-list ( il -- seq )
dup il-list ;
: get-il-quote ( il -- quot )
dup il-quote ;
: unfold ( seq -- stackseq )
[ ] each ;
: push-next-element ( il -- )
over il-list push ;
: rev-il-list ( il -- )
get-il-list nreverse ;
: (pop-first-element) ( il -- element )
get-il-list pop ;
: pop-first-element ( il -- element )
rev-il-list (pop-first-element) ;
: remove-first-element ( il -- element )
pop-first-element >r rev-il-list drop r> ;
: calc-next-element ( seq -- element )
get-il-quote >r get-il-list unfold r> call ;
: il-next ( il -- next )
calc-next-element push-next-element remove-first-element ;
: repeat-if ( il-quot crit-quot -- el ) ! acts as a filter
over call 2dup swap call [ 2nip ] [ drop repeat-if ] if ;
: collect ( n quot -- seq )
V{ } -rot [ add ] append times ;
: not-dividable ( n divisor -- ? )
mod zero? not ;
: naturals ( -- n )
V{ 1 } [ 1+ ] <il> il-next ;
: squares ( -- n )
V{ } [ naturals dup * ] <il> il-next ;
: ones ( -- n )
V{ } [ 1 ] <il> il-next ;
: from2 ( -- n )
V{ 2 } [ 1+ ] <il> il-next ;
: factorial ( -- n )
V{ 1 } [ from2 * ] <il> il-next ;
: powers-of-two ( -- n )
V{ 1 } [ dup + ] <il> il-next ;
: fib ( -- n )
V{ 0 1 } [ + ] <il> il-next ;
: odds ( -- n )
[ naturals ] [ odd? ] repeat-if ;
: evens ( -- n )
[ naturals ] [ even? ] repeat-if ;
: (primes) ( -- )
V{ 2 } [ 1+ ] <il> il-next ; ! => from2
: call-word-def ( word -- res )
word-def dup call dup ;
: prime-criteria ( n -- quot )
[ not-dividable ] curry ;
: gen-quot ( -- quot )
\ repeat-if 3array >quotation ;
: update-word ( x y z -- word-def )
rot define-compound ;
: primestep ( word -- n )
dup >r call-word-def >r prime-criteria
gen-quot r> r> update-word ;
: primes ( -- n )
\ (primes) primestep ;
PROVIDE: demos/series ;
You can use it as follows, e.g.
-
naturals
returns because its invoked the first time "1" -
naturals
returns "2" -
10 [ primes ] collect
returns the first 10 primes in a vector -
10 [ fib ] collect
returns the first 10 fibonacci numbers in a vector
Here is a screenshot: