Generator/Exponential: Difference between revisions

m
Moved Wren entry into correct alphabetical order.
m (Moved Wren entry into correct alphabetical order.)
 
(152 intermediate revisions by 62 users not shown)
Line 1:
{{task}}
{{draft task}}A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided. Generators are often built on top of coroutines or objects so that the internal state of the object is handled “naturally”. Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.
{{omit from|Lilypond}}
[[Category:Non parametric generators]]
[[Category:Stateful transactions]]
 
A generator is an executable entity (like a function or procedure) that contains code that yields a sequence of values, one at a time, so that each time you call the generator, the next value in the sequence is provided.
Generators are often built on top of coroutines or objects so that the internal state of the object is handled “naturally”.
 
Generators are often used in situations where a sequence is potentially infinite, and where it is possible to construct the next value of the sequence with only minimal state.
 
 
;Task:
* Create a function that returns a generation of the m'th powers of the positive integers starting from zero, in order, and without obvious or simple upper limit. (Any upper limit to the generator should not be stated in the source but should be down to factors such as the languages natural integer size limit or computational time/size).
* Use it to create a generator of:
:::*   Squares.
:::*   Cubes.
* Create a new generator that filters all cubes from the generator of squares.
* Drop the first 20 values from this last generator of filtered results, and then show the next 10 values.
 
'''Task description'''
 
# Create a function returning a generator of the m'th powers of the positive integers starting from zero, in order, and without obvious or simple upper limit. (Any upper limit to the generator should not be stated in the source but should be down to factors such as the languages natural integer size limit or computational time/size).
# Use it to create a generator of:
:# Squares.
:# Cubes.
# Create a new generator that filters all cubes from the generator of squares.
# Drop the first 20 values from this last generator of filtered results then show the next 10 values
Note that this task ''requires'' the use of generators in the calculation of the result.
 
 
'''See also'''
;Also see:
* [[wp:Generator (computer_science)|Generator]]
<br><br>
 
=={{header|11l}}==
{{trans|C++}}
 
<syntaxhighlight lang="11l">T Generator
F.virtual.abstract next() -> Float
 
T PowersGenerator(Generator)
i = 0.0
Float e
 
F (e)
.e = e
 
F.virtual.assign next() -> Float
V r = .i ^ .e
.i++
R r
 
T Filter
Generator gen, filter
Float lastG, lastF
 
F (Generator gen, filter)
.gen = gen
.filter = filter
.lastG = .gen.next()
.lastF = .filter.next()
 
F ()()
L .lastG >= .lastF
I .lastG == .lastF
.lastG = .gen.next()
.lastF = .filter.next()
 
V out = .lastG
.lastG = .gen.next()
R out
 
V gen = Filter(PowersGenerator(2), PowersGenerator(3))
 
L 20
gen()
L 10
print(gen(), end' ‘ ’)</syntaxhighlight>
 
{{out}}
<pre>
529 576 625 676 784 841 900 961 1024 1089
</pre>
 
=={{header|Ada}}==
{{works with|Ada 2005}}
 
To modify the internal state, the function uses an access parameter.
To modify the internal state, the function uses an access parameter. For a different approach, see the Random packages of the Ada compiler, which use the so-called "Rosen trick". With the next release of Ada 2012 functions are allowed to have in-out parameters, which would solve this problem, too. You could also use procedures instead of functions.
For a different approach, see the Random packages of the Ada compiler, which use the so-called "Rosen trick".
With the next release of Ada 2012 functions are allowed to have in-out parameters, which would solve this problem, too.
You could also use procedures instead of functions.
 
generator.ads:
<langsyntaxhighlight Adalang="ada">package Generator is
 
type Generator is tagged private;
Line 42 ⟶ 108:
end record;
 
end Generator;</langsyntaxhighlight>
 
generator-filtered.ads:
<langsyntaxhighlight Adalang="ada">package Generator.Filtered is
 
type Filtered_Generator is new Generator with private;
Line 63 ⟶ 129:
end record;
 
end Generator.Filtered;</langsyntaxhighlight>
 
generator.adb:
<langsyntaxhighlight Adalang="ada">package body Generator is
 
--------------
Line 127 ⟶ 193:
end Set_Generator_Function;
 
end Generator;</langsyntaxhighlight>
 
generator-filtered.adb:
<langsyntaxhighlight Adalang="ada">package body Generator.Filtered is
 
-----------
Line 188 ⟶ 254:
end Set_Filter;
 
end Generator.Filtered;</langsyntaxhighlight>
 
example use:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
with Generator.Filtered;
 
Line 225 ⟶ 291:
end loop;
 
end Generator_Test;</langsyntaxhighlight>
 
{{out}}
output:
<pre>I: 1, F: 529
I: 2, F: 576
Line 238 ⟶ 304:
I: 9, F: 1024
I: 10, F: 1089</pre>
 
=={{header|ALGOL 68}}==
{{trans|Python}}{{works with|ALGOL 68|Revision 1 - with [[currying]] of functions and PRAGMA READ extensions}}
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.3.5 algol68g-2.3.5].}}
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of '''format'''[ted] ''transput''.}}
'''File: Template.Generator.a68'''<langsyntaxhighlight lang="algol68">MODE YIELDVALUE = PROC(VALUE)VOID;
MODE GENVALUE = PROC(YIELDVALUE)VOID;
 
Line 304 ⟶ 371:
 
PROC powers = (VALUE m, YIELDVALUE yield)VOID:
FOR n FROM 0 DO yield(n ** m) OD;</langsyntaxhighlight>'''File: test.Generator.a68'''<langsyntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script #
 
MODE VALUE = INT;
Line 312 ⟶ 379:
GENVALUE fil = gen filtered(squares, cubes,);
 
printf(($g(0)x$, get list(gen slice(fil, 20, 30, )) ))</langsyntaxhighlight>'''Output:'''
{{out}}
<pre>
529 576 625 676 784 841 900 961 1024 1089
</pre>
 
=={{header|AppleScript}}==
Composable generators can be constructed from the methods and persistent properties of ''script'' objects:
{{Trans|JavaScript}}
{{Trans|Python}}
<syntaxhighlight lang="applescript">----------------- EXPONENTIAL / GENERATOR ----------------
 
-- powers :: Gen [Int]
on powers(n)
script f
on |λ|(x)
x ^ n as integer
end |λ|
end script
fmapGen(f, enumFrom(0))
end powers
 
 
--------------------------- TEST -------------------------
on run
take(10, ¬
drop(20, ¬
differenceGen(powers(2), powers(3))))
--> {529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089}
end run
 
 
------------------------- GENERIC ------------------------
 
-- Just :: a -> Maybe a
on Just(x)
{type:"Maybe", Nothing:false, Just:x}
end Just
 
 
-- Nothing :: Maybe a
on Nothing()
{type:"Maybe", Nothing:true}
end Nothing
 
 
-- Tuple (,) :: a -> b -> (a, b)
on Tuple(a, b)
{type:"Tuple", |1|:a, |2|:b, length:2}
end Tuple
 
 
-- differenceGen :: Gen [a] -> Gen [a] -> Gen [a]
on differenceGen(ga, gb)
-- All values of ga except any
-- already seen in gb.
script
property g : zipGen(ga, gb)
property bs : {}
property xy : missing value
on |λ|()
set xy to g's |λ|()
if missing value is xy then
xy
else
set x to |1| of xy
set y to |2| of xy
set bs to {y} & bs
if bs contains x then
|λ|() -- Next in series.
else
x
end if
end if
end |λ|
end script
end differenceGen
 
 
-- drop :: Int -> [a] -> [a]
-- drop :: Int -> String -> String
on drop(n, xs)
set c to class of xs
if script is not c then
if string is not c then
if n < length of xs then
items (1 + n) thru -1 of xs
else
{}
end if
else
if n < length of xs then
text (1 + n) thru -1 of xs
else
""
end if
end if
else
take(n, xs) -- consumed
return xs
end if
end drop
 
 
-- enumFrom :: Int -> [Int]
on enumFrom(x)
script
property v : missing value
on |λ|()
if missing value is not v then
set v to 1 + v
else
set v to x
end if
return v
end |λ|
end script
end enumFrom
 
 
-- fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
on fmapGen(f, gen)
script
property g : mReturn(f)
on |λ|()
set v to gen's |λ|()
if v is missing value then
v
else
g's |λ|(v)
end if
end |λ|
end script
end fmapGen
 
 
-- length :: [a] -> Int
on |length|(xs)
set c to class of xs
if list is c or string is c then
length of xs
else
(2 ^ 29 - 1) -- (maxInt - simple proxy for non-finite)
end if
end |length|
 
 
-- Lift 2nd class handler function into 1st class script wrapper
-- mReturn :: First-class m => (a -> b) -> m (a -> b)
on mReturn(f)
if script is class of f then
f
else
script
property |λ| : f
end script
end if
end mReturn
 
 
-- take :: Int -> [a] -> [a]
-- take :: Int -> String -> String
on take(n, xs)
set c to class of xs
if list is c then
if 0 < n then
items 1 thru min(n, length of xs) of xs
else
{}
end if
else if string is c then
if 0 < n then
text 1 thru min(n, length of xs) of xs
else
""
end if
else if script is c then
set ys to {}
repeat with i from 1 to n
set v to xs's |λ|()
if missing value is v then
return ys
else
set end of ys to v
end if
end repeat
return ys
else
missing value
end if
end take
 
 
-- uncons :: [a] -> Maybe (a, [a])
on uncons(xs)
set lng to |length|(xs)
if 0 = lng then
Nothing()
else
if (2 ^ 29 - 1) as integer > lng then
if class of xs is string then
set cs to text items of xs
Just(Tuple(item 1 of cs, rest of cs))
else
Just(Tuple(item 1 of xs, rest of xs))
end if
else
set nxt to take(1, xs)
if {} is nxt then
Nothing()
else
Just(Tuple(item 1 of nxt, xs))
end if
end if
end if
end uncons
 
 
-- zipGen :: Gen [a] -> Gen [b] -> Gen [(a, b)]
on zipGen(ga, gb)
script
property ma : missing value
property mb : missing value
on |λ|()
if missing value is ma then
set ma to uncons(ga)
set mb to uncons(gb)
end if
if Nothing of ma or Nothing of mb then
missing value
else
set ta to Just of ma
set tb to Just of mb
set x to Tuple(|1| of ta, |1| of tb)
set ma to uncons(|2| of ta)
set mb to uncons(|2| of tb)
return x
end if
end |λ|
end script
end zipGen</syntaxhighlight>
{{Out}}
<pre>{529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089}</pre>
 
=={{header|ATS}}==
 
<syntaxhighlight lang="ats">
(* "Generators" *)
 
(* I implement "generators" as non-linear closures. *)
 
#include "share/atspre_staload.hats"
 
#define NIL list_nil ()
#define :: list_cons
 
(* Integer powers where base and power are of any unsigned integer
types. *)
fn {tk_b, tk_p : tkind}
g1uint_ipow
(base : g1uint tk_b,
power : g1uint tk_p)
:<> g1uint tk_b =
let
fun
loop {p : nat}
.<p>.
(b : g1uint tk_b,
p : g1uint (tk_p, p),
accum : g1uint tk_b)
:<> g1uint tk_b =
let
val ph = half p
val accum = (if ph + ph = p then accum else accum * b)
in
if ph = g1i2u 0 then
accum
else
loop (b * b, ph, accum)
end
 
prval () = lemma_g1uint_param base
prval () = lemma_g1uint_param power
in
loop (base, power, g1i2u 1)
end
 
overload ipow with g1uint_ipow of 100
 
(* Some unit tests of ipow. *)
val- 0U = ipow (0U, 100U)
val- 1U = ipow (0U, 0U) (* Sometimes a convenient result. *)
val- 9UL = ipow (3UL, 2ULL)
val- 81ULL = ipow (3ULL, 4U)
 
typedef generator (tk : tkind) =
() -<cloref1> g1uint tk
 
typedef option_generator (tk : tkind) =
() -<cloref1> Option (g1uint tk)
 
fn {tk_b : tkind}
{tk_p : tkind}
make_powers_generator
(power : g1uint tk_p)
:<!wrt> generator tk_b =
let
val base : ref (g1uint tk_b) = ref (g1i2u 0)
in
lam () =>
let
val b = !base
val result = ipow (b, power)
in
!base := succ b;
result
end
end
 
fn {tk : tkind}
make_generator_of_1_that_are_not_also_2
(gen1 : generator tk,
gen2 : generator tk)
:<!wrt> generator tk =
let
val initialized : ref bool = ref false
val x2 : ref (g1uint tk) = ref (g1i2u 0)
 
fn
check (x1 : g1uint tk)
:<1> bool =
let
fun
loop ()
:<1> bool =
if x1 <= !x2 then
(x1 <> !x2)
else
begin
!x2 := gen2 ();
loop ()
end
in
loop ()
end
in
lam () =>
let
var result : g1uint tk = g1i2u 0
var found_one : bool = false
in
if ~(!initialized) then
begin
!x2 := gen2 ();
!initialized := true
end;
while (~found_one)
let
val next1 = gen1 ()
in
if check next1 then
begin
result := next1;
found_one := true
end
end;
result
end
end
 
fn {tk : tkind}
make_dropper
(n : size_t,
gen : generator tk)
:<!wrt> generator tk =
let
val counter : ref size_t = ref n
in
lam () =>
begin
while (isneqz (!counter))
let
val _ = gen ()
in
!counter := pred (!counter)
end;
gen ()
end
end
 
fn {tk : tkind}
make_taker
(n : size_t,
gen : generator tk)
:<!wrt> option_generator tk =
let
val counter : ref size_t = ref n
in
lam () =>
if iseqz (!counter) then
None ()
else
begin
!counter := pred (!counter);
Some (gen ())
end
end
 
implement
main0 () =
let
stadef tk = uintknd
macdef filter = make_generator_of_1_that_are_not_also_2<tk>
 
val squares_generator = make_powers_generator<tk> 2U
val cubes_generator = make_powers_generator<tk> 3U
val gen = filter (squares_generator, cubes_generator)
val gen = make_dropper<tk> (i2sz 20, gen)
val gen = make_taker<tk> (i2sz 10, gen)
 
var done : bool = false
in
while (~done)
begin
case+ gen () of
| None () => done := true
| Some x => print! (" ", x)
end;
println! ()
end
</syntaxhighlight>
 
{{out}}
<pre>$ patscc -DATS_MEMALLOC_GCBDW generator-exponential.dats -lgc && ./a.out
529 576 625 676 784 841 900 961 1024 1089</pre>
 
=={{header|C}}==
==={{libheader|libco}}===
libco is a tiny library that adds ''cooperative multithreading'', also known as ''coroutines'', to the C language. Its <tt>co_switch(x)</tt> function pauses the current cothread and resumes the other cothread <tt>x</tt>.
Its <tt>co_switch(x)</tt> function pauses the current cothread and resumes the other cothread <tt>x</tt>.
 
This example provides <tt>next64()</tt> and <tt>yield64()</tt>, to generate 64-bit integers. <tt>next64()</tt> switches to a generator. Then the generator passes some 64-bit integer to <tt>yield64()</tt>, which switches to the first cothread, where <tt>next64()</tt> returns this 64-bit integer.
Then the generator passes some 64-bit integer to <tt>yield64()</tt>, which switches to the first cothread, where <tt>next64()</tt> returns this 64-bit integer.
 
<langsyntaxhighlight lang="c">#include <inttypes.h> /* int64_t, PRId64 */
#include <stdlib.h> /* exit() */
#include <stdio.h> /* printf() */
Line 484 ⟶ 985:
gen.free(&gen); /* Free memory. */
return 0;
}</langsyntaxhighlight>
 
One must download [http://byuu.org/programming/ libco] and give libco.c to the compiler.
Line 492 ⟶ 993:
$ ./main
529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089</pre>
 
===Using struct to store state===
<langsyntaxhighlight Clang="c">#include <stdio.h>
#include <stdlib.h>
#include <math.h>
Line 566 ⟶ 1,068:
 
return 0;
}</syntaxhighlight>
}</lang>output<lang>529
{{out}}<pre>529
576
625
Line 575 ⟶ 1,078:
961
1024
1089</langpre>
 
=={{header|C sharp}}==
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
 
static class Program {
static void Main() {
Func<int, IEnumerable<int>> ms = m => Infinite().Select(i => (int)Math.Pow(i, m));
var squares = ms(2);
var cubes = ms(3);
var filtered = squares.Where(square => cubes.First(cube => cube >= square) != square);
var final = filtered.Skip(20).Take(10);
foreach (var i in final) Console.WriteLine(i);
}
 
static IEnumerable<int> Infinite() {
var i = 0;
while (true) yield return i++;
}
}</syntaxhighlight>
 
=={{header|C++}}==
Line 581 ⟶ 1,105:
A templated solution.
 
<langsyntaxhighlight lang="cpp">#include <iostream>
using namespace std;
 
Line 646 ⟶ 1,170:
for(int i = 20; i < 30; ++i)
cout << i << ": " << gen() << endl;
}</langsyntaxhighlight>
 
{{out}}
Output:
<pre>
20: 529
Line 662 ⟶ 1,186:
</pre>
 
=={{header|C sharpClojure}}==
Note that types have been made static and variables made explicit as an aid to understanding.
 
In Clojure, the role that generator functions take in some other languages
'''Closure Style'''
is generally filled by sequences. Most of the functions that produce sequences
<lang csharp>using System;
produce lazy sequences, many of the standard functions deal with sequences,
using System.Collections.Generic;
and their use in Clojure is extremely idiomatic.
using System.Linq;
Thus we can define squares and cubes as lazy sequences:
 
<syntaxhighlight lang="clojure">(defn powers [m] (for [n (iterate inc 1)] (reduce * (repeat m n)))))
namespace RosettaGenerator
(def squares (powers 2))
{
(take 5 squares) ; => (1 4 9 16 25)</syntaxhighlight>
class ClosureStyle
{
static void Main(string[] args)
{
Func<int> squaresGenerator = PowerGeneratorAsClosure(2);
Func<int> cubesGenerator = PowerGeneratorAsClosure(3);
 
The definition here of the squares-not-cubes lazy sequence uses the loop/recur construct,
Func<int> filter = FilterAsClosure(squaresGenerator, cubesGenerator);
which isn't lazy. So we use ''lazy-seq'' explicity:
<syntaxhighlight lang="clojure">(defn squares-not-cubes
([] (squares-not-cubes (powers 2) (powers 3)))
([squares cubes]
(loop [[p2first & p2rest :as p2s] squares, [p3first & p3rest :as p3s] cubes]
(cond
(= p2first p3first) (recur p2rest p3rest)
(> p2first p3first) (recur p2s p3rest)
:else (cons p2first (lazy-seq (squares-not-cubes p2rest p3s)))))))
(->> (squares-not-cubes) (drop 20) (take 10))
; => (529 576 625 676 784 841 900 961 1024 1089)</syntaxhighlight>
 
If we really need a generator function for some reason, any lazy sequence
foreach (int i in Enumerable.Range(0, 20))
can be turned into a stateful function. (The inverse of ''seq->fn'' is the standard
filter();
function ''repeatedly''.)
foreach (int i in Enumerable.Range(21, 10))
Console.Write(filter() + " ");
Console.WriteLine();
}
 
<syntaxhighlight lang="clojure">(defn seq->fn [sequence]
public static Func<int> PowerGeneratorAsClosure(int exponent)
(let [state (atom (cons nil sequence))]
{
(fn [] int(first x(swap! =state 0;rest)))
return () => { return (int)Math.Pow(x++, exponent); };
(def f (seq->fn (squares-not-cubes)))
}
[(f) (f) (f)] ; => [4 9 16]</syntaxhighlight>
 
public static Func<int> FilterAsClosure(Func<int> squaresGenerator, Func<int> cubesGenerator)
{
int value;
int filter = cubesGenerator();
return () =>
{
while (true)
{
value = squaresGenerator();
while (value > filter)
filter = cubesGenerator();
if (value < filter)
return value;
}
};
}
}
}</lang>
'''List Style'''
<lang csharp>using System;
using System.Collections.Generic;
using System.Linq;
 
namespace RosettaGenerator
{
class ListStyle
{
static void Main(string[] args)
{
IEnumerator<int> squaresGenerator = PowerGeneratorAsList(2);
IEnumerator<int> cubesGenerator = PowerGeneratorAsList(3);
 
IEnumerable<int> filter = FilterAsList(squaresGenerator, cubesGenerator);
 
foreach (int value in filter.Skip(20).Take(10))
Console.Write(value + " ");
Console.WriteLine();
}
 
public static IEnumerator<int> PowerGeneratorAsList(int exponent)
{
int x = 0;
while (true)
yield return (int)Math.Pow(x++, exponent);
}
 
public static IEnumerable<int> FilterAsList(IEnumerator<int> squaresGenerator, IEnumerator<int> cubesGenerator)
{
int value;
int filter = cubesGenerator.Current;
while (true)
{
value = squaresGenerator.Current;
while (value > filter)
{
cubesGenerator.MoveNext();
filter = cubesGenerator.Current;
}
if (value < filter)
yield return value;
squaresGenerator.MoveNext();
}
}
}
}</lang>
 
Output (for either):
<pre>529 576 625 676 784 841 900 961 1024 1089</pre>
 
=={{header|Common Lisp}}==
<langsyntaxhighlight lang="lisp">(defun take (seq &optional (n 1))
(values-list (loop repeat n collect (funcall seq))))
 
Line 784 ⟶ 1,245:
(let ((2not3 (filter-seq (power-seq 2) (power-seq 3))))
(take 2not3 20) ;; drop 20
(princ (multiple-value-list (take 2not3 10))))</langsyntaxhighlight>
 
=={{header|D}}==
===Ranges-BasedEfficient Standard Version===
<syntaxhighlight lang="d">void main() {
<lang d>import std.stdio, std.bigint, std.range, std.algorithm;
import std.stdio, std.bigint, std.range, std.algorithm;
 
auto squares = 0.sequence!"n".map!(i => i.BigInt ^^ 2);
auto cubes = 0.sequence!"n".map!(i => i.BigInt ^^ 3);
 
squares.setDifference(cubes).drop(20).take(10).writeln;
}</syntaxhighlight>
{{out}}
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre>
 
===Simple Ranges-Based Implementation===
{{trans|C#}}
<syntaxhighlight lang="d">void main() {
import std.stdio, std.bigint, std.range, std.algorithm;
 
auto squares = 0.sequence!"n".map!(i => i.BigInt ^^ 2);
auto cubes = 0.sequence!"n".map!(i => i.BigInt ^^ 3);
 
squares
.filter!(s => cubes.find!(c => c >= s).front != s)
.drop(20)
.take(10)
.writeln;
}</syntaxhighlight>
The output is the same.
 
===More Efficient Ranges-Based Version===
<syntaxhighlight lang="d">import std.stdio, std.bigint, std.range, std.algorithm;
 
struct Filtered(R1, R2) if (is(ElementType!R1 == ElementType!R2)) {
Line 794 ⟶ 1,283:
R2 s2;
alias ElementType!R1 T;
T currentfront, source, filter;
 
this(R1 r1, R2 r2) {
s1 = r1;
s2 = r2;
source = s1.front();
filter = s2.front();
_next()popFront;
}
 
conststatic boolimmutable empty = false;
@property T front() { return current; }
void popFront() { _next(); }
 
private void _nextpopFront() {
while (true) {
if (source > filter) {
s2.popFront();
filter = s2.front();
continue;
} else if (source < filter) {
currentfront = source;
s1.popFront();
source = s1.front();
break;
}
s1.popFront();
source = s1.front();
}
}
}
 
auto filtered(R1, R2)(R1 r1, R2 r2) // Helper function.
if (is(ElementTypeisInputRange!R1 ==&& ElementTypeisInputRange!R2)) {&&
is(ElementType!R1 == ElementType!R2)) {
return Filtered!(R1, R2)(r1, r2);
}
 
struct Count(T) {
T n;
this(T n_) { this.n = n_; }
const bool empty = false;
@property T front() { return n; }
void popFront() { /* n++; */ n += 1; }
}
 
Count!T count(T)(T start) { return Count!T(start); }
Count!T count(T)() { return Count!T(cast(T)0); }
 
void main() {
auto squares = count0.sequence!BigInt()"n".map!q{a(i => i.BigInt ^^ 2}();
auto cubes = count0.sequence!BigInt()"n".map!q{a(i => i.BigInt ^^ 3}();
auto f = filtered(squares, cubes).drop(20).take(10).writeln;
}</syntaxhighlight>
The output is the same.
 
popFrontN(f, 20);
writeln(take(f, 10));
}</lang>
{{out}}
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre>
===Closures-Based Version===
{{trans|Go}}
<langsyntaxhighlight lang="d">import std.stdio;
 
auto powers(in double e) pure nothrow {
double i = 0.0;
return () => i++ ^^ e;
}
 
auto filterfilter2(D)(D af, D bf) {
double a = af(), b = bf();
 
return {
double r;
Line 880 ⟶ 1,355:
 
void main() {
auto fgen = filterfilter2(2.powers(2), 3.powers(3));
foreach (immutable i; 0 .. 20)
fgen();
foreach (immutable i; 0 .. 10)
write(fgen(), " ");
writeln();
}</langsyntaxhighlight>
{{out}}
<pre>529 576 625 676 784 841 900 961 1024 1089 </pre>
 
===Generator Range Version===
<syntaxhighlight lang="d">import std.stdio, std.range, std.algorithm, std.concurrency, std.bigint;
 
auto powers(in uint m) pure nothrow @safe {
return 0.sequence!"n".map!(i => i.BigInt ^^ m);
}
 
auto filtered(R1, R2)(R1 r1, R2 r2) /*@safe*/
if (isForwardRange!R1 && isForwardRange!R2 &&
is(ElementType!R1 == ElementType!R2)) {
return new Generator!(ElementType!R1)({
auto v = r1.front; r1.popFront;
auto f = r2.front; r2.popFront;
 
while (true) {
if (v > f) {
f = r2.front; r2.popFront;
continue;
} else if (v < f)
yield(v);
v = r1.front; r1.popFront;
}
});
}
 
void main() {
auto squares = 2.powers, cubes = 3.powers;
filtered(squares, cubes).drop(20).take(10).writeln;
}</syntaxhighlight>
{{out}}
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre>
 
=={{header|Delphi}}==
{{works with|Delphi|6.0}}
{{libheader|SysUtils,Math,StdCtrls,ExtCtrls}}
This program demostrates hierarchial object structure. It starts with a base generator object that has all the basic features need by a generator. Child objects are then created which customized the behavior to generate squares, cubes and filtered squares. Once the base object is created, any variation can be created with just a few lines of code. This is the power of polymorphism and inheritance.
 
<syntaxhighlight lang="Delphi">
{Custom object forms basic generator}
 
type TCustomGen = class(TObject)
private
FNumber: integer;
FExponent: integer;
FStart: integer;
protected
property Exponent: integer read FExponent write FExponent;
public
constructor Create; virtual;
procedure Reset;
function Next: integer; virtual;
procedure Skip(Count: integer);
property Start: integer read FStart write FStart;
end;
 
{Child object specifically for generating Squares}
 
type TSquareGen = class(TCustomGen)
public
constructor Create; override;
end;
 
 
{Child object specifically for generating cubes}
 
type TCubeGen = class(TCustomGen)
public
constructor Create; override;
end;
 
{Child object specifically for filtering squares}
 
type TFilterSquareGen = class(TSquareGen)
private
function IsCube(N: integer): boolean;
public
function Next: integer; override;
end;
 
{ TCustomGen }
 
constructor TCustomGen.Create;
begin
Start:=0;
{Default to returning X^1}
Exponent:=1;
Reset;
end;
 
 
function TCustomGen.Next: integer;
{Find next number in sequence}
var I: integer;
begin
Result:=FNumber;
{Raise to specified power}
for I:=1 to FExponent-1 do Result:=Result * Result;
{Get next base}
Inc(FNumber);
end;
 
 
procedure TCustomGen.Reset;
begin
FNumber:=Start;
end;
 
 
procedure TCustomGen.Skip(Count: integer);
{Skip specified number of items}
var I: integer;
begin
for I:=1 to Count do Next;
end;
 
{ TSquareGen }
 
constructor TSquareGen.Create;
begin
inherited;
Exponent:=2;
end;
 
{ TCubeGen }
 
constructor TCubeGen.Create;
begin
inherited;
Exponent:=3;
end;
 
{ TFilterSquareGen }
 
function TFilterSquareGen.IsCube(N: integer): boolean;
{Test if number is perfect cube}
var I: integer;
begin
I:=Round(Power(N,1/3));
Result:=I*I*I = N;
end;
 
 
 
function TFilterSquareGen.Next: integer;
begin
{Gets inherited next square, rejects cubes}
repeat Result:=inherited Next
until not IsCube(Result);
end;
 
 
{-----------------------------------------------------------}
 
procedure DoTest(Memo: TMemo; Gen: TCustomGen; SkipCnt: integer; Title: string);
{Carry out TGenerators tests. "Gen" is a TCustomGen which is the parent of}
{all generators. That means "DoTest" can work with any type of generator}
var S: string;
var I,V: integer;
begin
Gen.Reset;
Gen.Skip(SkipCnt);
Memo.Lines.Add(Title);
S:='[';
for I:=1 to 10 do S:=S+Format(' %d',[Gen.Next]);
Memo.Lines.Add(S+']');
end;
 
 
 
procedure TestGenerators(Memo: TMemo);
{Tests all three types of generators}
var SquareGen: TSquareGen;
var CubeGen: TCubeGen;
var Filtered: TFilterSquareGen;
begin
SquareGen:=TSquareGen.Create;
try
CubeGen:=TCubeGen.Create;
try
Filtered:=TFilterSquareGen.Create;
try
DoTest(Memo,SquareGen,0,'Testing Square Generator');
DoTest(Memo,CubeGen,0,'Testing Cube Generator');
DoTest(Memo,Filtered,20,'Testing Squares with cubes removed');
 
finally Filtered.Free; end;
finally CubeGen.Free; end;
finally SquareGen.Free; end;
end;
 
 
</syntaxhighlight>
{{out}}
<pre>
Testing Square Generator
[ 0 1 4 9 16 25 36 49 64 81]
Testing Cube Generator
[ 0 1 16 81 256 625 1296 2401 4096 6561]
Testing Squares with cubes removed
[ 529 576 625 676 784 841 900 961 1024 1089]
</pre>
 
 
=={{header|E}}==
Line 894 ⟶ 1,572:
E does not provide coroutines on the principle that interleaving of execution of code should be explicit to avoid unexpected interactions. However, this problem does not especially require them. Each generator here is simply a function that returns the next value in the sequence when called.
 
<langsyntaxhighlight lang="e">def genPowers(exponent) {
var i := -1
return def powerGenerator() {
Line 928 ⟶ 1,606:
print(`${squaresNotCubes()} `)
}
println()</langsyntaxhighlight>
 
=={{header|EchoLisp}}==
<syntaxhighlight lang="scheme">
(lib 'tasks) ;; for make-generator
 
;; generator of generators
(define (gen-power power)
(make-generator
(lambda(n) (yield (expt n power)) (1+ n)) 1))
(define powers-2 (gen-power 2))
(define powers-3 (gen-power 3))
 
(take powers-3 10)
→ (1 8 27 64 125 216 343 512 729 1000)
 
;; generators substraction
;; input : two generators ga, gb - Sequences must be increasing
;; output : new generator = ga sequence minus gb sequence
 
(define (gen-substract ga gb)
(define (substract b (a))
(set! a (next ga))
(while (>= a b) ; avance b until > a
(when (= a b) (set! a (next ga)))
(set! b (next gb)))
(yield a)
b ) ;; b := next state
(make-generator substract (next gb)))
 
;; application
(define task (gen-substract (gen-power 2) (gen-power 3)))
 
(drop task 20)
(take task 10)
→ (529 576 625 676 784 841 900 961 1024 1089)
 
; inspect
task → #generator:state: 1331
</syntaxhighlight>
 
=={{header|Elixir}}==
{{trans|Erlang}}
<syntaxhighlight lang="elixir">defmodule Generator do
def filter( source_pid, remove_pid ) do
first_remove = next( remove_pid )
spawn( fn -> filter_loop(source_pid, remove_pid, first_remove) end )
end
def next( pid ) do
send(pid, {:next, self})
receive do
x -> x
end
end
def power( m ), do: spawn( fn -> power_loop(m, 0) end )
def task do
squares_pid = power( 2 )
cubes_pid = power( 3 )
filter_pid = filter( squares_pid, cubes_pid )
for _x <- 1..20, do: next(filter_pid)
for _x <- 1..10, do: next(filter_pid)
end
defp filter_loop( pid1, pid2, n2 ) do
receive do
{:next, pid} ->
{n, new_n2} = filter_loop_next( next(pid1), n2, pid1, pid2 )
send( pid, n )
filter_loop( pid1, pid2, new_n2 )
end
end
defp filter_loop_next( n1, n2, pid1, pid2 ) when n1 > n2, do:
filter_loop_next( n1, next(pid2), pid1, pid2 )
defp filter_loop_next( n, n, pid1, pid2 ), do:
filter_loop_next( next(pid1), next(pid2), pid1, pid2 )
defp filter_loop_next( n1, n2, _pid1, _pid2 ), do: {n1, n2}
defp power_loop( m, n ) do
receive do
{:next, pid} -> send( pid, round(:math.pow(n, m) ) )
end
power_loop( m, n + 1 )
end
end
 
IO.inspect Generator.task</syntaxhighlight>
 
{{out}}
<pre>
[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]
</pre>
 
=={{header|Emacs Lisp}}==
 
This code requires generator library which was introduced in Emacs 25.2
 
<syntaxhighlight lang="lisp">;; lexical-binding: t
(require 'generator)
 
(iter-defun exp-gen (pow)
(let ((i -1))
(while
(setq i (1+ i))
(iter-yield (expt i pow)))))
 
(iter-defun flt-gen ()
(let* ((g (exp-gen 2))
(f (exp-gen 3))
(i (iter-next g))
(j (iter-next f)))
(while
(setq i (iter-next g))
(while (> i j)
(setq j (iter-next f)))
(unless (= i j)
(iter-yield i)))))
 
(let ((g (flt-gen))
(o 'nil))
(dotimes (i 29)
(setq o (iter-next g))
(when (>= i 20)
(print o))))</syntaxhighlight>
 
=={{header|Erlang}}==
<syntaxhighlight lang="erlang">
-module( generator ).
 
-export( [filter/2, next/1, power/1, task/0] ).
 
filter( Source_pid, Remove_pid ) ->
First_remove = next( Remove_pid ),
erlang:spawn( fun() -> filter_loop(Source_pid, Remove_pid, First_remove) end ).
 
next( Pid ) ->
Pid ! {next, erlang:self()},
receive X -> X end.
 
power( M ) -> erlang:spawn( fun() -> power_loop(M, 0) end ).
 
task() ->
Squares_pid = power( 2 ),
Cubes_pid = power( 3 ),
Filter_pid = filter( Squares_pid, Cubes_pid ),
[next(Filter_pid) || _X <- lists:seq(1, 20)],
[next(Filter_pid) || _X <- lists:seq(1, 10)].
 
 
filter_loop( Pid1, Pid2, N2 ) ->
receive
{next, Pid} ->
{N, New_N2} = filter_loop_next( next(Pid1), N2, Pid1, Pid2 ),
Pid ! N
end,
filter_loop( Pid1, Pid2, New_N2 ).
 
filter_loop_next( N1, N2, Pid1, Pid2 ) when N1 > N2 -> filter_loop_next( N1, next(Pid2), Pid1, Pid2 );
filter_loop_next( N, N, Pid1, Pid2 ) -> filter_loop_next( next(Pid1), next(Pid2), Pid1, Pid2 );
filter_loop_next( N1, N2, _Pid1, _Pid2 ) -> {N1, N2}.
 
power_loop( M, N ) ->
receive {next, Pid} -> Pid ! erlang:round(math:pow(N, M) ) end,
power_loop( M, N + 1 ).
</syntaxhighlight>
{{out}}
<pre>
31> generator:task().
[529,576,625,676,784,841,900,961,1024,1089]
</pre>
 
=={{header|F_Sharp|F#}}==
{{trans|C#}}
<syntaxhighlight lang="fsharp">let m n = Seq.unfold(fun i -> Some(bigint.Pow(i, n), i + 1I)) 0I
 
let squares = m 2
let cubes = m 3
 
let (--) orig veto = Seq.where(fun n -> n <> (Seq.find(fun m -> m >= n) veto)) orig
 
let ``squares without cubes`` = squares -- cubes
 
Seq.take 10 (Seq.skip 20 (``squares without cubes``))
|> Seq.toList |> printfn "%A"</syntaxhighlight>
{{out}}
<pre>[529; 576; 625; 676; 784; 841; 900; 961; 1024; 1089]</pre>
 
=={{header|Factor}}==
Using lazy lists for our generators:
<syntaxhighlight lang="factor">USING: fry kernel lists lists.lazy math math.functions
prettyprint ;
IN: rosetta-code.generator-exponential
 
: mth-powers-generator ( m -- lazy-list )
[ 0 lfrom ] dip [ ^ ] curry lmap-lazy ;
 
: lmember? ( elt list -- ? )
over '[ unswons dup _ >= ] [ drop ] until nip = ;
 
: 2-not-3-generator ( -- lazy-list )
2 mth-powers-generator
[ 3 mth-powers-generator lmember? not ] <lazy-filter> ;
 
10 2-not-3-generator 20 [ cdr ] times ltake list>array .</syntaxhighlight>
{{out}}
<pre>
{ 529 576 625 676 784 841 900 961 1024 1089 }
</pre>
 
=={{header|Fantom}}==
Line 934 ⟶ 1,824:
Using closures to implement generators.
 
<langsyntaxhighlight lang="fantom">
class Main
{
Line 975 ⟶ 1,865:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Output:
<pre>
529
Line 989 ⟶ 1,879:
1024
1089
</pre>
 
=={{header|Forth}}==
<syntaxhighlight lang="forth">
\ genexp-rcode.fs Generator/Exponential for RosettaCode.org
 
\ Generator/filter implementation using return stack as continuations stack
: ENTER ( cont.addr -- ;borrowed from M.L.Gasanenko papers)
>R
;
: | ( f -- ;true->go ahead, false->return into generator )
IF EXIT THEN R> DROP
;
: GEN ( -- ;generate forever what is between 'GEN' and ';' )
BEGIN R@ ENTER AGAIN
;
: STOP ( f -- ;return to caller of word that contain 'GEN' )
IF R> DROP R> DROP R> DROP THEN
;
 
\ Problem at hand
: square ( n -- n^2 ) dup * ;
: cube ( n -- n^3 ) dup square * ;
 
\ Faster tests using info that tested numbers are monotonic growing
VARIABLE Sqroot \ last square root
VARIABLE Cbroot \ last cubic root
: square? ( u -- f ;test U for square number)
BEGIN
Sqroot @ square over <
WHILE
1 Sqroot +!
REPEAT
Sqroot @ square =
;
: cube? ( u -- f ;test U for cubic number)
BEGIN
Cbroot @ cube over <
WHILE
1 Cbroot +!
REPEAT
Cbroot @ cube =
;
VARIABLE Counter
: (go) ( u -- u' )
GEN 1+ Counter @ 30 >= STOP
dup square? | dup cube? 0= | Counter @ 20 >= 1 Counter +! | dup .
;
:noname 0 Counter ! 1 Sqroot ! 1 Cbroot ! 0 (go) drop ;
execute cr bye
</syntaxhighlight>
{{out}}
<pre>
$ gforth -e "include genexp-rcode.fs"
529 576 625 676 784 841 900 961 1024 1089
$
</pre>
 
 
=={{header|FreeBASIC}}==
{{trans|VBA}}
<syntaxhighlight lang="freebasic">Dim Shared As Long lastsquare, nextsquare, lastcube, midcube, nextcube
 
Function squares() As Long
lastsquare += nextsquare
nextsquare += 2
squares = lastsquare
End Function
 
Function cubes() As Long
lastcube += nextcube
nextcube += midcube
midcube += 6
cubes = lastcube
End Function
 
lastsquare = 1 : nextsquare = -1 : lastcube = -1 : midcube = 0 : nextcube = 1
Dim As Long cube, square
cube = cubes
 
For i As Byte = 1 To 30
Do
square = squares
Do While cube < square
cube = cubes
Loop
If square <> cube Then Exit Do
Loop
If i > 20 Then Print square;
Next i
Sleep</syntaxhighlight>
{{out}}
<pre>
Igual que la entrada de VBA.
</pre>
 
 
=={{header|FunL}}==
{{trans|Haskell}} (for the powers function)
{{trans|Scala}} (for the filter)
<syntaxhighlight lang="funl">def powers( m ) = map( (^ m), 0.. )
 
def
filtered( s@sh:_, ch:ct ) | sh > ch = filtered( s, ct )
filtered( sh:st, c@ch:_ ) | sh < ch = sh # filtered( st, c )
filtered( _:st, c ) = filtered( st, c )
 
println( filtered(powers(2), powers(3)).drop(20).take(10) )</syntaxhighlight>
{{out}}
<pre>
[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]
</pre>
 
=={{header|Go}}==
Most direct and most efficient on a single core is implementing generators with closures.
<langsyntaxhighlight lang="go">package main
 
import (
Line 1,039 ⟶ 2,040:
}
fmt.Println()
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
529 576 625 676 784 841 900 961 1024 1089
</pre>
Alternatively, generators can be implemented in Go with goroutines and channels. There are tradeoffs however, and often one technique is a significantly better choice.
 
Alternatively, generators can be implemented in Go with goroutines and channels.
Goroutines can run concurrently, but there is overhead associated with thread scheduling and channel communication. Flow control is also different. A generator implemented as a closure is a function with a single entry point fixed at the beginning. On repeated calls, execution always starts over at the beginning and ends when a value is returned. A generator implemented as a goroutine, on the other hand, "returns" a value by sending it on a channel, and then the goroutine continues execution from that point. This allows more flexibility in structuring code.
There are tradeoffs however, and often one technique is a significantly better choice.
<lang go>package main
 
Goroutines can run concurrently, but there is overhead associated with thread scheduling and channel communication. Flow control is also different.
A generator implemented as a closure is a function with a single entry point fixed at the beginning.
On repeated calls, execution always starts over at the beginning and ends when a value is returned.
A generator implemented as a goroutine, on the other hand, "returns" a value by sending it on a channel, and then the goroutine continues execution from that point.
This allows more flexibility in structuring code.
<syntaxhighlight lang="go">package main
 
import (
Line 1,094 ⟶ 2,101:
}
fmt.Println()
}</langsyntaxhighlight>
 
=={{header|Haskell}}==
Generators in most cases can be implemented using infinite lists in Haskell. Because Haskell is lazy, only as many elements as needed is computed from the infinite list:
<syntaxhighlight lang ="haskell">powers m = map (^ m)import [0Data.List.]Ordered
 
powers :: Int -> [Int]
filtered (x:xs) (y:ys) | x > y = filtered (x:xs) ys
powers m = map (^ m) [0..]
| x < y = x : filtered xs (y:ys)
| otherwise = filtered xs (y:ys)
squares :: [Int]
 
squares = powers 2
 
cubes :: [Int]
cubes = powers 3
f = filtered squares cubes
 
foo :: [Int]
foo = filter (not . has cubes) squares
main :: IO ()
main = print $ take 10 $ drop 20 $ ffoo</langsyntaxhighlight>
{{Out}}
 
'''Sample output'''
<pre>[529,576,625,676,784,841,900,961,1024,1089]</pre>
 
=={{header|Icon}} and {{header|Unicon}}==
Generators are close to the heart and soul of Icon/Unicon. Co-expressions let us circumvent the normal backtracking mechanism and get results where we need them.
Co-expressions let us circumvent the normal backtracking mechanism and get results where we need them.
 
<langsyntaxhighlight Iconlang="icon">procedure main()
 
write("Non-cube Squares (21st to 30th):")
Line 1,141 ⟶ 2,152:
}
}
end</langsyntaxhighlight>
 
Note: The task could be written without co-expressions but would be likely be ugly. If there is an elegant non-co-expression version please add it as an alternate example.
If there is an elegant non-co-expression version please add it as an alternate example.
 
{{out}}
Output:<pre>Non-cube Squares (21st to 30th):
<pre>Non-cube Squares (21st to 30th):
21 : 529
22 : 576
Line 1,163 ⟶ 2,176:
Here is a generator for mth powers of a number:
 
<langsyntaxhighlight lang="j">coclass 'mthPower'
N=: 0
create=: 3 :0
Line 1,172 ⟶ 2,185:
N=: N+1
n^M
)</langsyntaxhighlight>
 
And, here are corresponding square and cube generators
 
<langsyntaxhighlight lang="j">stateySquare=: 2 conew 'mthPower'
stateyCube=: 3 conew 'mthPower'</langsyntaxhighlight>
 
Here is a generator for squares which are not cubes:
 
<langsyntaxhighlight lang="j">coclass 'uncubicalSquares'
N=: 0
next=: 3 :0"0
while. (-: <.) 3 %: *: n=. N do. N=: N+1 end. N=: N+1
*: n
)</langsyntaxhighlight>
 
And here is an example of its use:
 
<langsyntaxhighlight lang="j"> next__g i.10 [ next__g i.20 [ g=: conew 'uncubicalSquares'
529 576 625 676 784 841 900 961 1024 1089</langsyntaxhighlight>
 
That said, here is a more natural approach, for J.
 
<langsyntaxhighlight lang="j">mthPower=: 1 :'^&m@i.'
squares=: 2 mthPower
cubes=: 3 mthPower
uncubicalSquares=: squares -. cubes</langsyntaxhighlight>
 
The downside of this approach is that it is computing independent sequences. And for the "uncubicalSquares" verb, it is removing some elements from that sequence. So you must estimate how many values to generate. However, this can be made transparent to the user with a simplistic estimator:
 
<langsyntaxhighlight lang="j">uncubicalSquares=: {. squares@<.@p.~&3 1.1 -. cubes</langsyntaxhighlight>
 
Example use:
 
<langsyntaxhighlight lang="j">20 }. uncubicalSquares 30 NB. the 21st through 30th uncubical square
529 576 625 676 784 841 900 961 1024 1089</langsyntaxhighlight>
 
=={{header|Java}}==
{{works with|java|8}}
<syntaxhighlight lang="java">import java.util.function.LongSupplier;
import static java.util.stream.LongStream.generate;
 
public class GeneratorExponential implements LongSupplier {
private LongSupplier source, filter;
private long s, f;
 
public GeneratorExponential(LongSupplier source, LongSupplier filter) {
this.source = source;
this.filter = filter;
f = filter.getAsLong();
}
 
@Override
public long getAsLong() {
s = source.getAsLong();
 
while (s == f) {
s = source.getAsLong();
f = filter.getAsLong();
}
 
while (s > f) {
f = filter.getAsLong();
}
 
return s;
}
 
public static void main(String[] args) {
generate(new GeneratorExponential(new SquaresGen(), new CubesGen()))
.skip(20).limit(10)
.forEach(n -> System.out.printf("%d ", n));
}
}
 
class SquaresGen implements LongSupplier {
private long n;
 
@Override
public long getAsLong() {
return n * n++;
}
}
 
class CubesGen implements LongSupplier {
private long n;
 
@Override
public long getAsLong() {
return n * n * n++;
}
}</syntaxhighlight>
 
<pre>529 576 625 676 784 841 900 961 1024 1089</pre>
 
=={{header|JavaScript}}==
===Procedural===
{{works with|Firefox 3.6 using JavaScript 1.7|}}
 
<syntaxhighlight lang="javascript">
<lang JavaScript>
function PowersGenerator(m) {
var n=0;
Line 1,251 ⟶ 2,322:
for( var x = 20; x < 30; x++ ) console.logfiltered.next());
 
</syntaxhighlight>
</lang>
 
====ES6====
<syntaxhighlight lang="javascript">function* nPowerGen(n) {
let e = 0;
while (1) { e++ && (yield Math.pow(e, n)); }
}
 
function* filterGen(gS, gC, skip=0) {
let s = 0; // The square value
let c = 0; // The cube value
let n = 0; // A skip counter
 
while(1) {
s = gS.next().value;
s > c && (c = gC.next().value);
s == c ?
c = gC.next().value :
n++ && n > skip && (yield s);
}
}
 
const filtered = filterGen(nPowerGen(2), nPowerGen(3), skip=20);</syntaxhighlight>
<syntaxhighlight lang="javascript">// Generate the first 10 values
for (let n = 0; n < 10; n++) {
console.log(filtered.next().value)
}</syntaxhighlight>
<pre>529
576
625
676
784
841
900
961
1024
1089</pre>
 
===Functional===
====ES6====
Compositional derivation of custom generators:
{{Trans|Python}}
<syntaxhighlight lang="javascript">(() => {
'use strict';
 
// main :: IO()
const main = () => {
 
// powers :: Gen [Int]
const powers = n =>
fmapGen(
x => Math.pow(x, n),
enumFrom(0)
);
 
// xs :: [Int]
const xs = take(10, drop(20,
differenceGen(
powers(2),
powers(3)
)
));
 
console.log(xs);
// -> [529,576,625,676,784,841,900,961,1024,1089]
};
 
 
// GENERIC FUNCTIONS ----------------------------------
 
// Just :: a -> Maybe a
const Just = x => ({
type: 'Maybe',
Nothing: false,
Just: x
});
 
// Nothing :: Maybe a
const Nothing = () => ({
type: 'Maybe',
Nothing: true,
});
 
// Tuple (,) :: a -> b -> (a, b)
const Tuple = (a, b) => ({
type: 'Tuple',
'0': a,
'1': b,
length: 2
});
 
// differenceGen :: Gen [a] -> Gen [a] -> Gen [a]
function* differenceGen(ga, gb) {
// All values of generator stream a except any
// already seen in generator stream b.
const
stream = zipGen(ga, gb),
sb = new Set([]);
let xy = take(1, stream);
while (0 < xy.length) {
const [x, y] = Array.from(xy[0]);
sb.add(y);
if (!sb.has(x)) yield x;
xy = take(1, stream);
}
};
 
// drop :: Int -> [a] -> [a]
// drop :: Int -> Generator [a] -> Generator [a]
// drop :: Int -> String -> String
const drop = (n, xs) =>
Infinity > length(xs) ? (
xs.slice(n)
) : (take(n, xs), xs);
 
// enumFrom :: Enum a => a -> [a]
function* enumFrom(x) {
let v = x;
while (true) {
yield v;
v = 1 + v;
}
}
 
// fmapGen <$> :: (a -> b) -> Gen [a] -> Gen [b]
function* fmapGen(f, gen) {
let v = take(1, gen);
while (0 < v.length) {
yield(f(v[0]))
v = take(1, gen)
}
}
 
// fst :: (a, b) -> a
const fst = tpl => tpl[0];
 
// Returns Infinity over objects without finite length.
// This enables zip and zipWith to choose the shorter
// argument when one is non-finite, like cycle, repeat etc
 
// length :: [a] -> Int
const length = xs =>
(Array.isArray(xs) || 'string' === typeof xs) ? (
xs.length
) : Infinity;
 
// snd :: (a, b) -> b
const snd = tpl => tpl[1];
 
// take :: Int -> [a] -> [a]
// take :: Int -> String -> String
const take = (n, xs) =>
'GeneratorFunction' !== xs.constructor.constructor.name ? (
xs.slice(0, n)
) : [].concat.apply([], Array.from({
length: n
}, () => {
const x = xs.next();
return x.done ? [] : [x.value];
}));
 
// uncons :: [a] -> Maybe (a, [a])
const uncons = xs => {
const lng = length(xs);
return (0 < lng) ? (
lng < Infinity ? (
Just(Tuple(xs[0], xs.slice(1))) // Finite list
) : (() => {
const nxt = take(1, xs);
return 0 < nxt.length ? (
Just(Tuple(nxt[0], xs))
) : Nothing();
})() // Lazy generator
) : Nothing();
};
 
// zipGen :: Gen [a] -> Gen [b] -> Gen [(a, b)]
const zipGen = (ga, gb) => {
function* go(ma, mb) {
let
a = ma,
b = mb;
while (!a.Nothing && !b.Nothing) {
let
ta = a.Just,
tb = b.Just
yield(Tuple(fst(ta), fst(tb)));
a = uncons(snd(ta));
b = uncons(snd(tb));
}
}
return go(uncons(ga), uncons(gb));
};
 
// MAIN ---
return main();
})();</syntaxhighlight>
{{Out}}
<pre>[529,576,625,676,784,841,900,961,1024,1089]</pre>
 
=={{header|jq}}==
{{works with|jq|1.4}}
'''Part 1: i^m, 2^m and 3^m'''
 
jq is a purely functional language and so does not have generators
with state. To generate a sequence of values one-by-one therefore
requires a "next-value" function, the input of which must include
relevant state information. For convenience, a counter is usually
included. For generating i^m, therefore, we would have:
<syntaxhighlight lang="jq"># Compute self^m where m is a non-negative integer:
def pow(m): . as $in | reduce range(0;m) as $i (1; .*$in);
 
# state: [i, i^m]
def next_power(m): .[0] + 1 | [., pow(m) ];</syntaxhighlight>
To make such generators easier to use, we shall define filters to
skip and to emit a specified number of items:
<syntaxhighlight lang="jq"># skip m states, and return the next state
def skip(m; next):
if m <= 0 then . else next | skip(m-1; next) end;
 
# emit m states including the initial state
def emit(m; next):
if m <= 0 then empty else ., (next | emit(m-1; next)) end;</syntaxhighlight>
'''Examples''':
<syntaxhighlight lang="jq"># Generate the first 4 values in the sequence i^2:
[0,0] | emit(4; next_power(2)) | .[1]
 
# Generate all the values in the sequence i^3 less than 100:
[0,0] | recurse(next_power(3) | if .[1] < 100 then . else empty end) | .[1]</syntaxhighlight>
'''An aside on streams'''
 
Since the release of version jq 1.4, enhancements for processing
streams of values have been added, notably "foreach" and "limit".
If your version of jq has these enhancements, then it is often
preferable to use them in conjunction with functions that emit streams of values rather than the "next-value" functions that are the focus of this page.
 
'''Part 2: selection from 2 ^ m'''
<syntaxhighlight lang="jq"># Infrastructure:
def last(f): reduce f as $i (null; $i);
 
# emit the last value that satisfies condition, or null
def while(condition; next):
def w: if condition then ., (next|w) else empty end;
last(w);
 
# Powers of m1 that are not also powers of m2.
# filtered_next_power(m1;m2) produces [[i, i^m1], [j, j^m1]] where i^m1
# is not a power of m2 and j^m2 < i^m1
#
def filtered_next_power(m1; m2):
if . then . else [[0,0],[0,0]] end
| (.[0] | next_power(m1)) as $next1
| (.[1] | while( .[1] <= $next1[1]; next_power(m2))) as $next2
| if $next1[1] == $next2[1]
then [$next1, $next2] | filtered_next_power(m1;m2)
else [$next1, $next2]
end ;
 
# Emit ten powers of 2 that are NOT powers of 3,
# skipping the first 20 integers satisfying the condition, including 0.
filtered_next_power(2;3)
| skip(20; filtered_next_power(2;3))
| emit(10; filtered_next_power(2;3))
| .[0][1]</syntaxhighlight>
{{out}}
<syntaxhighlight lang="sh">$ jq -n -f generators.jq
529
576
625
676
784
841
900
961
1024
1089</syntaxhighlight>
 
=={{header|Julia}}==
The task can be achieved by using closures, iterators or tasks. Here is a solution using anonymous functions and closures.
 
<syntaxhighlight lang="julia">drop(gen::Function, n::Integer) = (for _ in 1:n gen() end; gen)
take(gen::Function, n::Integer) = collect(gen() for _ in 1:n)
 
function pgen(n::Number)
x = 0
return () -> (x += 1) ^ n
end
 
function genfilter(g1::Function, g2::Function)
local r1
local r2 = g2()
return () -> begin
r1 = g1()
while r2 < r1 r2 = g2() end
while r1 == r2 r1 = g1() end
return r1
end
end
 
@show take(drop(genfilter(pgen(2), pgen(3)), 20), 10)</syntaxhighlight>
 
{{out}}
<pre>take(drop(genfilter(pgen(2), pgen(3)), 20), 10) = [529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre>
 
=={{header|Kotlin}}==
Coroutines were introduced in version 1.1 of Kotlin but, as yet, are an experimental feature:
<syntaxhighlight lang="scala">// version 1.1.0
// compiled with flag -Xcoroutines=enable to suppress 'experimental' warning
 
import kotlin.coroutines.experimental.buildSequence
 
fun generatePowers(m: Int) =
buildSequence {
var n = 0
val mm = m.toDouble()
while (true) yield(Math.pow((n++).toDouble(), mm).toLong())
}
 
fun generateNonCubicSquares(squares: Sequence<Long>, cubes: Sequence<Long>) =
buildSequence {
val iter2 = squares.iterator()
val iter3 = cubes.iterator()
var square = iter2.next()
var cube = iter3.next()
while (true) {
if (square > cube) {
cube = iter3.next()
continue
} else if (square < cube) {
yield(square)
}
square = iter2.next()
}
}
 
fun main(args: Array<String>) {
val squares = generatePowers(2)
val cubes = generatePowers(3)
val ncs = generateNonCubicSquares(squares, cubes)
print("Non-cubic squares (21st to 30th) : ")
ncs.drop(20).take(10).forEach { print("$it ") } // print 21st to 30th items
println()
}</syntaxhighlight>
 
{{out}}
<pre>
Non-cubic squares (21st to 30th) : 529 576 625 676 784 841 900 961 1024 1089
</pre>
 
=={{header|Lingo}}==
Lingo neither supports coroutines nor first-class functions, and also misses syntactic sugar for implementing real generators. But in the context of for or while loops, simple pseudo-generator objects that store states internally and manipulate data passed by reference can be used to implement generator-like behavior and solve the given task.
<syntaxhighlight lang="lingo">squares = script("generator.power").new(2)
cubes = script("generator.power").new(3)
filter = script("generator.filter").new(squares, cubes)
filter.skip(20)
res = []
i = 0
repeat while filter.exec(res)
i = i + 1
if i>10 then exit repeat
put res[1]
end repeat</syntaxhighlight>
 
{{out}}
<pre>
-- 529
-- 576
-- 625
-- 676
-- 784
-- 841
-- 900
-- 961
-- 1024
-- 1089
</pre>
 
Parent script "generator.power"
 
<syntaxhighlight lang="lingo">property _exp
property _index
 
-- @constructor
on new (me, e)
me._exp = e
me._index = 0
return me
end
 
on exec (me, input)
me._index = me._index+1
input[1] = integer(power(me._index, me._exp))
return TRUE
end
 
on skip (me, steps)
me._index = me._index + steps
end
 
on reset (me)
me._index = 0
end</syntaxhighlight>
 
Parent script "generator.filter"
 
<syntaxhighlight lang="lingo">property _genv
property _genf
 
-- @constructor
on new (me, genv, genf)
me._genv = genv
me._genf = genf
return me
end
 
on exec (me, input)
repeat while TRUE
me._genv.exec(input)
v = input[1]
ok = TRUE
me._genf.reset() -- reset filter generator
repeat while TRUE
me._genf.exec(input)
f = input[1]
if f>v then exit repeat
if f=v then
ok=FALSE
exit repeat
end if
end repeat
if ok then
input[1] = v
exit repeat
end if
end repeat
return TRUE
end
 
on skip (me, steps)
repeat with i = 1 to steps
me.exec([])
end repeat
end
 
on reset (me)
me._genv.reset()
me._genf.reset()
end</syntaxhighlight>
 
=={{header|Lua}}==
Generators can be implemented both as closures and as coroutines. The following example demonstrates both.
 
<syntaxhighlight lang="lua">
<lang Lua>
--could be done with a coroutine, but a simple closure works just as well.
local function powgen(m)
Line 1,295 ⟶ 2,813:
end
end
</syntaxhighlight>
</lang>
 
=={{header|M2000 Interpreter}}==
<syntaxhighlight lang="m2000 interpreter">
Module Generator {
PowGen = Lambda (e)
-> {
= Lambda
i=0, // closure
e // closure
-> {
i++
= i**e
}
}
Squares=Lambda
PowGen=PowGen(2) // closure
->{
= PowGen()
}
Cubes=Lambda
PowGen=PowGen(3) // closure
-> {
= PowGen()
}
Filter=Lambda
z=Squares(), // closure
Squares, // closure
m, // closure
Cubes // closure
->{
while m<z :m=cubes():end while
if z=m then z=Squares()
= z : z=Squares()
}
For i=1 to 20 : dropit=Filter() :Next i
Document doc$="Non-cubic squares (21st to 30th)"
Print doc$
doc$={
} \\ a new line to doc$
For i=1 to 10
f=Filter()
Print Format$("I: {0::-2}, F: {1}",i+20, f)
doc$=Format$("I: {0::-2}, F: {1}",i+20, f)+{
}
Next
Clipboard doc$
}
Generator
</syntaxhighlight>
 
{{out}}
<pre >
Non-cubic squares (21st to 30th)
I: 21, F: 529
I: 22, F: 576
I: 23, F: 625
I: 24, F: 676
I: 25, F: 784
I: 26, F: 841
I: 27, F: 900
I: 28, F: 961
I: 29, F: 1024
I: 30, F: 1089
</pre >
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
{{trans|VBA}}
Generators are not very natural in Mathemetica, because they avoid the use of lists and instead rely on sequential processing.
<syntaxhighlight lang="mathematica">lastsquare = 1;
nextsquare = -1;
lastcube = -1;
midcube = 0;
nextcube = 1;
Gensquares[] := Module[{},
lastsquare += nextsquare;
nextsquare += 2;
squares = lastsquare;
squares
]
Gencubes[] := Module[{},
lastcube += nextcube;
nextcube += midcube;
midcube += 6;
cubes = lastcube
]
 
 
c = Gencubes[];
Do[
While[True,
s = Gensquares[];
While[c < s,
c = Gencubes[];
];
If[s =!= c,
Break[]
];
];
If[i > 20,
Print[s]
]
,
{i, 30}
]</syntaxhighlight>
{{out}}
<pre>529
576
625
676
784
841
900
961
1024
1089</pre>
 
=={{header|Nim}}==
<syntaxhighlight lang="nim">type Iterator = iterator(): int
 
proc `^`*(base: Natural; exp: Natural): int =
var (base, exp) = (base, exp)
result = 1
while exp != 0:
if (exp and 1) != 0:
result *= base
exp = exp shr 1
base *= base
 
proc next(s: Iterator): int =
for n in s(): return n
 
proc powers(m: Natural): Iterator =
iterator it(): int {.closure.} =
for n in 0 ..< int.high:
yield n ^ m
result = it
 
iterator filtered(s1, s2: Iterator): int =
var v = next(s1)
var f = next(s2)
while true:
if v > f:
f = next(s2)
continue
elif v < f:
yield v
v = next(s1)
 
var
squares = powers(2)
cubes = powers(3)
i = 1
for x in filtered(squares, cubes):
if i > 20: echo x
if i >= 30: break
inc i</syntaxhighlight>
 
{{out}}
<pre>529
576
625
676
784
841
900
961
1024
1089</pre>
 
=={{header|OCaml}}==
Original version by [http://rosettacode.org/wiki/User:Vanyamil User:Vanyamil]
<syntaxhighlight lang="ocaml">
(* Task : Generator/Exponential
 
Version using the Seq module types, but transparently
*)
 
(*** Helper functions ***)
 
(* Generator type *)
type 'a gen = unit -> 'a node
and 'a node = Nil | Cons of 'a * 'a gen
 
(* Power function on integers *)
let power (base : int) (exp : int) : int =
let rec helper exp acc =
if exp = 0 then acc
else helper (exp - 1) (base * acc)
in
helper exp 1
 
(* Take (at most) n from generator *)
let rec take (n : int) (gen : 'a gen) : 'a list =
if n = 0 then []
else
match gen () with
| Nil -> []
| Cons (x, tl) -> x :: take (n - 1) tl
 
(* Stop existing generator at a given condition *)
let rec keep_while (p : 'a -> bool) (gen : 'a gen) : 'a gen = fun () ->
match gen () with
| Nil -> Nil
| Cons (x, tl) ->
if p x then Cons (x, keep_while p tl)
else Nil
 
(* Drop the first n elements of a generator *)
let rec drop (n : int) (gen : 'a gen) : 'a gen =
if n = 0 then gen
else
match gen () with
| Nil -> (fun () -> Nil)
| Cons (_, tl) -> drop (n - 1) tl
 
(* Filter based on predicate, lazily *)
let rec filter (p : 'a -> bool) (gen : 'a gen) : 'a gen = fun () ->
match gen () with
| Nil -> Nil
| Cons (x, tl) ->
if p x then Cons (x, filter p tl)
else filter p tl ()
 
(* Is this value inside this generator? Does not terminate for infinite streams! *)
let rec mem (val_ : 'a) (gen : 'a gen) : bool =
match gen () with
| Nil -> false
| Cons (x, tl) ->
if x = val_ then true
else mem val_ tl
 
(*** Task at hand ***)
 
(* Create a function that returns a generation of the m'th powers of the positive integers
starting from zero, in order, and without obvious or simple upper limit.
(Any upper limit to the generator should not be stated in the source but should be down
to factors such as the languages natural integer size limit or computational time/size).
*)
let power_gen k : int gen =
let rec generator n () =
Cons (power n k, generator (n + 1))
in
generator 0
 
(* Use it to create generators of squares and cubes *)
let squares = power_gen 2
let cubes = power_gen 3
 
(* Create a new generator that filters all cubes from the generator of squares. *)
let squares_no_cubes =
let filter_p square =
(* Get all cubes up to square *)
let cubes_up_to_n2 = keep_while ((>=) square) cubes in
not (mem square cubes_up_to_n2)
in
filter filter_p squares
 
(*** Output ***)
 
(* Drop the first 20 values from this last generator of filtered results, and then show the next 10 values. *)
let _ =
squares_no_cubes |> drop 20 |> take 10
</syntaxhighlight>
{{out}}
<pre>
- : int list = [529; 576; 625; 676; 784; 841; 900; 961; 1024; 1089]
</pre>
 
=={{header|PARI/GP}}==
Define two generator functions genpow() and genpow2().
<syntaxhighlight lang="parigp">g = List(1); \\ generator stack
 
genpow(p) = my(a=g[1]++);listput(g,[0,p]);()->g[a][1]++^g[a][2];
 
genpowf(p,f) = my(a=g[1]++);listput(g,[0,p]);(s=0)->my(q);while(ispower(p=g[a][1]++^g[a][2],f)||(s&&q++<=s),);p;</syntaxhighlight>
 
''genpow(power)'' returns a function that returns a simple power generator.<br>
''genpowf(power,filter)'' returns a function thats returns a filtered power generator. This generator accepts an optional skip-parameter.
 
Create simple power generators:
<pre>gp > squares = genpow(2);
gp > cubes = genpow(3);
gp > cubes()
1
gp > cubes()
8
gp > squares()
1
gp > squares()
4
gp > cubes()
27
gp > squares()
9</pre>
 
Create filtered power generator, skip first 20 results and print next 10 values:
<pre>gp > powf2 = genpowf(2,3);
gp > print(powf2(20)); for(i=1,9,print(powf2()))
529
576
625
676
784
841
900
961
1024
1089</pre>
 
=={{header|Perl}}==
These generators are anonymous subroutines, which are closures.
 
<langsyntaxhighlight lang="perl"># gen_pow($m) creates and returns an anonymous subroutine that will
# generate and return the powers 0**m, 1**m, 2**m, ...
sub gen_pow {
Line 1,336 ⟶ 3,162:
my @answer;
push @answer, $squares_without_cubes->() for (1..10);
print "[", join(", ", @answer), "]\n";</langsyntaxhighlight>
 
Output: {{out}}<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre>
=={{header|Perl 6}}==
As with Haskell, generators are disguised as lazy lists in Perl&nbsp;6.
<lang perl6>sub powers($m) { 0..* X** $m }
 
=={{header|Phix}}==
my @squares := powers(2);
<!--<syntaxhighlight lang="phix">(notonline)-->
my @cubes := powers(3);
<span style="color: #000080;font-style:italic;">--
-- demo\rosetta\Generator_Exponential.exw
-- ======================================
--</span>
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- tasks</span>
<span style="color: #004080;">bool</span> <span style="color: #000000;">terminate</span> <span style="color: #0000FF;">=</span> <span style="color: #004600;">false</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">procedure</span> <span style="color: #000000;">powers</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #004080;">integer</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span>
<span style="color: #008080;">while</span> <span style="color: #008080;">not</span> <span style="color: #000000;">terminate</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">,</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">task_suspend</span><span style="color: #0000FF;">(</span><span style="color: #000000;">task_self</span><span style="color: #0000FF;">())</span>
<span style="color: #000000;">task_yield</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">i</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<span style="color: #008080;">constant</span> <span style="color: #000000;">squares</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">task_create</span><span style="color: #0000FF;">(</span><span style="color: #000000;">powers</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">2</span><span style="color: #0000FF;">}),</span>
<span style="color: #000000;">cubes</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">task_create</span><span style="color: #0000FF;">(</span><span style="color: #000000;">powers</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">3</span><span style="color: #0000FF;">})</span>
<span style="color: #004080;">atom</span> <span style="color: #000000;">square</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">cube</span>
<span style="color: #000000;">task_schedule</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cubes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">task_yield</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">cube</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">30</span> <span style="color: #008080;">do</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">task_schedule</span><span style="color: #0000FF;">(</span><span style="color: #000000;">squares</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">task_yield</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">square</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">while</span> <span style="color: #000000;">cube</span><span style="color: #0000FF;"><</span><span style="color: #000000;">square</span> <span style="color: #008080;">do</span>
<span style="color: #000000;">task_schedule</span><span style="color: #0000FF;">(</span><span style="color: #000000;">cubes</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
<span style="color: #000000;">task_yield</span><span style="color: #0000FF;">()</span>
<span style="color: #000000;">cube</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">res</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">square</span><span style="color: #0000FF;">!=</span><span style="color: #000000;">cube</span> <span style="color: #008080;">then</span> <span style="color: #008080;">exit</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">while</span>
<span style="color: #008080;">if</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">></span><span style="color: #000000;">20</span> <span style="color: #008080;">then</span>
<span style="color: #0000FF;">?</span><span style="color: #000000;">square</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<span style="color: #000000;">terminate</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
529
576
625
676
784
841
900
961
1024
1089
</pre>
 
=={{header|PHP}}==
sub infix:<without> (@orig,@veto) {
{{trans|Python}}
gather for @veto -> $veto {
{{works with|PHP|5.5+}}
take @orig.shift while @orig[0] before $veto;
<syntaxhighlight lang="php"><?php
@orig.shift if @orig[0] eqv $veto;
function powers($m) {
for ($n = 0; ; $n++) {
yield pow($n, $m);
}
}
function filtered($s1, $s2) {
while (true) {
list($v, $f) = [$s1->current(), $s2->current()];
if ($v > $f) {
$s2->next();
continue;
} else if ($v < $f) {
yield $v;
}
$s1->next();
}
}
 
say list(@$squares, without @$cubes)[20 ..^= 20+10].join[powers('2), 'powers(3)];</lang>
$f = filtered($squares, $cubes);
foreach (range(0, 19) as $i) {
$f->next();
}
foreach (range(20, 29) as $i) {
echo $i, "\t", $f->current(), "\n";
$f->next();
}
?></syntaxhighlight>
 
{{out}}
Output:
<pre>
<pre>529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089</pre>
20 529
21 576
22 625
23 676
24 784
25 841
26 900
27 961
28 1024
29 1089
</pre>
 
=={{header|PicoLisp}}==
Coroutines are available only in the 64-bit version.
<langsyntaxhighlight PicoLisplang="picolisp">(de powers (M)
(co (intern (pack 'powers M))
(for (I 0 (inc 'I))
Line 1,375 ⟶ 3,293:
 
(do 20 (filtered 2 3))
(do 10 (println (filtered 2 3)))</langsyntaxhighlight>
{{out}}
Output:
<pre>529
576
Line 1,387 ⟶ 3,305:
1024
1089</pre>
 
=={{header|PL/I}}==
<syntaxhighlight lang="pl/i">
Generate: procedure options (main); /* 27 October 2013 */
declare j fixed binary;
declare r fixed binary;
 
/* Ignore the first 20 values */
do j = 1 to 20;
/* put edit (filter() ) (f(6)); */
r = filter ();
end;
put skip;
do j = 1 to 10;
put edit (filter() ) (f(6));
end;
 
/* filters out cubes from the result of the square generator. */
filter: procedure returns (fixed binary);
declare n fixed binary static initial (-0);
declare (i, j, m) fixed binary;
 
do while ('1'b);
m = squares();
r = 0;
do j = 1 to m;
if m = cubes() then go to ignore;
end;
return (m);
ignore:
end;
end filter;
 
squares: procedure returns (fixed binary);
declare i fixed binary static initial (-0);
 
i = i + 1;
return (i**2);
end squares;
 
cubes: procedure returns (fixed binary);
 
r = r + 1;
return (r**3);
end cubes;
 
end Generate;
</syntaxhighlight>
<pre>
20 dropped values:
4 9 16 25 36 49 81 100 121 144 169 196 225
256 289 324 361 400 441 484
 
Next 10 values:
529 576 625 676 784 841 900 961 1024 1089
</pre>
 
=={{header|Python}}==
Line 1,392 ⟶ 3,366:
 
{{works with|Python|2.6+ and 3.x}} (in versions prior to 2.6, replace <code>next(something)</code> with <code>something.next()</code>)
<langsyntaxhighlight lang="python">from itertools import islice, count
 
def powers(m):
Line 1,410 ⟶ 3,384:
squares, cubes = powers(2), powers(3)
f = filtered(squares, cubes)
print(list(islice(f, 20, 30)))</langsyntaxhighlight>
 
{{out}}
'''Sample output'''
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre>
 
=={{header|REXX}}==
Code was added to support listing of so many values, the default is 0 (zero).
<br>The generators lie dormant until a request is made (illustrated by the calling of "TELL" to display some values).
<br>A lot of unnecessary iterator calls could be eliminated (and making the program a lot faster) if a check would be made to determine if a value has been emitted.
<br>The REXX program can handle any numbers, not just positive integers; one only need to increase the size of the DIGITS if more are needed.
<lang rexx>
/*REXX program to show how to use a generator (also known as iterators).*/
 
Or, deriving custom generators compositionally:
numeric digits 10000 /*just in case we need big 'uns. */
gen_.= /*have generators from scratch. */
/*how_many: show that many vals.*/
parse arg how_many; how_many=pick1(how_many 0)
 
{{Works with|Python|3.7}}
do j=1 to how_many; call tell 'squares' ,gen_squares(j) ; end
<syntaxhighlight lang="python">'''Exponentials as generators'''
do j=1 to how_many; call tell 'cubes' ,gen_cubes(j) ; end
do j=1 to how_many; call tell 'sq¬cubes',gen_sqNcubes(j) ; end
if how_many>0 then say 'dropping 1st --> 20th values.'
do j=1 to 20; drop gen_.sqNcubes.j ; end
do j=20+1 for 10 ; call tell 'sq¬cubes',gen_sqNcubes(j) ; end
 
from itertools import count, islice
exit
 
/*─────────────────────────────────────generate powers iterator─────────*/
gen_powers: procedure expose gen_.; parse arg x,p; if x=='' then return
if gen_.powers.x.p=='' then gen_.powers.x.p=x**p
return gen_.powers.x.p
 
# powers :: Gen [Int]
/*─────────────────────────────────────gen squares iterator─────────────*/
def powers(n):
gen_squares: procedure expose gen_.; parse arg x;if x=='' then return
'''A non-finite succession of integers,
if gen_.squares.x=='' then do
starting at zero,
call gen_powers x,2
raised to the nth power.'''
gen_.squares.x=gen_.powers.x.2
end
return gen_.squares.x
 
def f(x):
/*─────────────────────────────────────gen cubes iterator───────────────*/
return pow(x, n)
gen_cubes: procedure expose gen_.; parse arg x; if x=='' then return
if gen_.cubes.j=='' then do
call gen_powers x,3
gen_.cubes.x=gen_.powers.x.3
end
return gen_.cubes.x
 
return map(f, count(0))
/*─────────────────────────────────────gen squares not cubes iterator───*/
gen_sqNcubes: procedure expose gen_.; parse arg x; if x=='' then return
s=1
if gen_.sqNcubes.x=='' then do j=1 to x
if gen_.sqNcubes\=='' then do
sq=sq+1
iterate
end
do s=s+1 /*slow way to weed out cubes*/
?=gen_squares(s)
do c=1 until gen_cubes(c)>?
if gen_cubes(c)==? then iterate s
end /*c*/
leave
end /*s*/
gen_.sqNcubes.x=?
gen_.sqNcubes.x=gen_.squares.s
end /*j*/
return gen_.sqNcubes.x
 
/*─────────────────────────────────────"1─liner" subroutines────────────*/
tell: if j==1 then say /*format args to be aligned up. */
say right(arg(1),20) right(j,5) right(arg(2),20); return
 
# main :: IO ()
pick1: return word(arg(1) arg(2),1)
def main():
</lang>
'''Taking the difference between two derived generators.'''
Output when using the default (no input):
print(
<pre style="height:30ex;overflow:scroll">
take(10)(
sq¬cubes 21 529
sq¬cubes 22 576drop(20)(
sq¬cubes 23 625differenceGen(powers(2))(
sq¬cubes 24 676powers(3)
sq¬cubes 25 784)
sq¬cubes 26 841)
)
sq¬cubes 27 900
)
sq¬cubes 28 961
 
sq¬cubes 29 1024
 
sq¬cubes 30 1089
# GENERIC -------------------------------------------------
 
 
# differenceGen :: Gen [a] -> Gen [a] -> Gen [a]
def differenceGen(ga):
'''All values of ga except any
already seen in gb.'''
def go(a, b):
stream = zip(a, b)
bs = set([])
while True:
xy = next(stream, None)
if None is not xy:
x, y = xy
bs.add(y)
if x not in bs:
yield x
else:
return
return lambda gb: go(ga, gb)
 
 
# drop :: Int -> [a] -> [a]
# drop :: Int -> String -> String
def drop(n):
'''The sublist of xs beginning at
(zero-based) index n.'''
def go(xs):
if isinstance(xs, list):
return xs[n:]
else:
take(n)(xs)
return xs
return lambda xs: go(xs)
 
 
# take :: Int -> [a] -> [a]
# take :: Int -> String -> String
def take(n):
'''The prefix of xs of length n,
or xs itself if n > length xs.'''
return lambda xs: (
xs[0:n]
if isinstance(xs, list)
else list(islice(xs, n))
)
 
 
# MAIN ---
if __name__ == '__main__':
main()</syntaxhighlight>
{{Out}}
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ ' [ this -1 peek
this -2 peek **
1 this tally
done ]
swap join
0 join ] is expogen ( n --> [ )
 
[ ' [ this temp put
temp share -3 peek do
dup temp share share = iff
[ drop
temp share -2 peek do
temp take replace ] again
[ dup temp share share > iff
[ temp share -2 peek do
temp share replace ]
again ]
temp release
done ]
unrot
dip nested
dup dip nested
do 3 times join ] is taskgen ( [ [ --> [ )
 
2 expogen
3 expogen taskgen
 
20 times [ dup do drop ]
10 times [ dup do echo sp ]
drop</syntaxhighlight>
 
{{out}}
 
<pre>529 576 625 676 784 841 900 961 1024 1089 </pre>
 
=={{header|R}}==
 
<syntaxhighlight lang="rsplus">powers = function(m)
{n = -1
function()
{n <<- n + 1
n^m}}
 
noncubic.squares = local(
{squares = powers(2)
cubes = powers(3)
cube = cubes()
function()
{square = squares()
while (1)
{if (square > cube)
{cube <<- cubes()
next}
else if (square < cube)
{return(square)}
else
{square = squares()}}}})
 
for (i in 1:20)
noncubic.squares()
for (i in 1:10)
message(noncubic.squares())</syntaxhighlight>
 
=={{header|Racket}}==
 
<syntaxhighlight lang="racket">
#lang racket
 
(require racket/generator)
 
;; this is a function that returns a powers generator, not a generator
(define (powers m)
(generator ()
(for ([n (in-naturals)]) (yield (expt n m)))))
 
(define squares (powers 2))
(define cubes (powers 3))
 
;; same here
(define (filtered g1 g2)
(generator ()
(let loop ([n1 (g1)] [n2 (g2)])
(cond [(< n1 n2) (yield n1) (loop (g1) n2)]
[(> n1 n2) (loop n1 (g2))]
[else (loop (g1) (g2))]))))
 
(for/list ([x (in-producer (filtered squares cubes) (lambda (_) #f))]
[i 30] #:when (>= i 20))
x)
</syntaxhighlight>
 
{{out}}
<pre>
'(529 576 625 676 784 841 900 961 1024 1089)
</pre>
Output when using <tt> 10 </tt> for input:
<pre style="height:30ex;overflow:scroll">
 
=={{header|Raku}}==
squares 1 1
(formerly Perl 6)
squares 2 4
squares 3 9
squares 4 16
squares 5 25
squares 6 36
squares 7 49
squares 8 64
squares 9 81
squares 10 100
 
As with Haskell, generators are disguised as lazy lists in Raku.
cubes 1 1
<syntaxhighlight lang="raku" line>sub powers($m) { 0..* X** $m }
cubes 2 8
cubes 3 27
cubes 4 64
cubes 5 125
cubes 6 216
cubes 7 343
cubes 8 512
cubes 9 729
cubes 10 1000
 
my @squares = powers(2);
sq¬cubes 1 4
my @cubes = powers(3);
sq¬cubes 2 9
 
sq¬cubes 3 16
sub infix:<with-out> (@orig, @veto) {
sq¬cubes 4 25
gather for @veto -> $veto {
sq¬cubes 5 36
take @orig.shift while @orig[0] before $veto;
sq¬cubes 6 49
@orig.shift if @orig[0] eqv $veto;
sq¬cubes 7 81
}
sq¬cubes 8 100
}
sq¬cubes 9 121
 
sq¬cubes 10 144
say (@squares with-out @cubes)[20 ..^ 20+10].join(', ');</syntaxhighlight>
dropping 1st --> 20th values.
 
sq¬cubes 21 529
{{out}}
sq¬cubes 22 576
<pre>529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089</pre>
sq¬cubes 23 625
 
sq¬cubes 24 676
=={{header|REXX}}==
sq¬cubes 25 784
<br>The generators &nbsp; (below, the &nbsp; <big> Gxxxxx </big> &nbsp; functions) &nbsp; lie dormant until a request is made for a specific generator index.
sq¬cubes 26 841
<syntaxhighlight lang="rexx">/*REXX program demonstrates how to use a generator (also known as an iterator). */
sq¬cubes 27 900
parse arg N .; if N=='' | N=="," sq¬cubesthen N=20 28/*N not specified? Then use 961default.*/
@.= sq¬cubes 29 1024 /* [↓] calculate squares,cubes,pureSq.*/
do i=1 sq¬cubesfor N; 30call Gsquare 1089i
call Gcube i
call GpureSquare i /*these are cube─free square numbers.*/
end /*i*/
 
do k=1 for N; @.pureSquare.k=; end /*k*/ /*this is used to drop 1st N values.*/
 
w=length(N+10); ps= 'pure square' /*the width of the numbers; a literal.*/
 
do m=N+1 for 10; say ps right(m, w)":" right(GpureSquare(m), 3*w)
end /*m*/
exit /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
Gpower: procedure expose @.; parse arg x,p; q=@.pow.x.p
if q\=='' then return q; _=x**p; @.pow.x.p=_
return _
/*──────────────────────────────────────────────────────────────────────────────────────*/
Gsquare: procedure expose @.; parse arg x; q=@.square.x
if q=='' then @.square.x=Gpower(x, 2)
return @.square.x
/*──────────────────────────────────────────────────────────────────────────────────────*/
Gcube: procedure expose @.; parse arg x; q=@.cube.x
if q=='' then @.cube.x=Gpower(x, 3) _=@.cube.x; @.3pow._=1
return @.cube.x
/*──────────────────────────────────────────────────────────────────────────────────────*/
GpureSquare: procedure expose @.; parse arg x; q=@.pureSquare.x
if q\=='' then return q
#=0
do j=1 until #==x; ?=Gpower(j, 2) /*search for pure square. */
if @.3pow.?==1 then iterate /*is it a power of three? */
#=#+1; @.pureSquare.#=? /*assign next pureSquare. */
end /*j*/
return @.pureSquare.x</syntaxhighlight>
'''output''' &nbsp; when using the default value:
<pre>
pure square 21: 529
pure square 22: 576
pure square 23: 625
pure square 24: 676
pure square 25: 784
pure square 26: 841
pure square 27: 900
pure square 28: 961
pure square 29: 1024
pure square 30: 1089
</pre>
 
Line 1,550 ⟶ 3,654:
An iterator is a Ruby method that takes a block parameter, and loops the block for each element. So <tt>powers(2) { |i| puts "Got #{i}" }</tt> would loop forever and print Got 0, Got 1, Got 4, Got 9 and so on. Starting with Ruby 1.8.7, one can use <tt>Object#enum_for</tt> to convert an iterator method to an <tt>Enumerator</tt> object. The <tt>Enumerator#next</tt> method is a generator that runs the iterator method on a separate coroutine. Here <tt>cubes.next</tt> generates the next cube number.
 
<syntaxhighlight lang="ruby"># This solution cheats and uses only one generator!
{{works with|Ruby|1.8.7}}
 
<lang ruby># This solution cheats and uses only one generator!
 
def powers(m)
return enum_for(:powers__method__, m) unless block_given?
0.step{|n| yield n**m}
 
n = 0
loop { yield n ** m; n += 1 }
end
 
def squares_without_cubes
return enum_for(:squares_without_cubes__method__) unless block_given?
 
cubes = powers(3)
c = cubes.next
powers(2) do |s|
(c = cubes.next) untilwhile c >=< s
yield s unless c == s
end
end
 
p squares_without_cubes.take(30).drop(20)</lang>
# p squares_without_cubes.lazy.drop(20).first(10) # Ruby 2.0+</syntaxhighlight>
 
{{out}}
Output: <tt>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</tt>
<pre>
[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]
</pre>
 
----
Line 1,580 ⟶ 3,683:
Here is the correct solution, which obeys the ''requirement'' of ''three'' generators.
 
<syntaxhighlight lang="ruby"># This solution uses three generators.
{{works with|Ruby|1.8.7}}
 
<lang ruby># This solution uses three generators.
 
def powers(m)
return enum_for(:powers__method__, m) unless block_given?
0.step{|n| yield n**m}
 
n = 0
loop { yield n ** m; n += 1 }
end
 
def squares_without_cubes
return enum_for(:squares_without_cubes__method__) unless block_given?
 
cubes = powers(3) #no block, so this is the first generator
c = cubes.next
squares = powers(2) # second generator
loop do
s = squares.next
(c = cubes.next) untilwhile c >=< s
yield s unless c == s
end
end
 
answer = squares_without_cubes # third generator
20.times { answer.next }
p (110..10)times.map { answer.next }</langsyntaxhighlight>
{{out}}
 
<pre>
Output: <tt>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</tt>
[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]
</pre>
 
If we change both programs to drop the first 1_000_020 values (output: <tt>[1000242014641, 1000244014884, 1000246015129, 1000248015376, 1000250015625, 1000252015876, 1000254016129, 1000256016384, 1000258016641, 1000260016900]</tt>), then the one-generator solution runs much faster than the three-generator solution on a machine with [[MRI]] 1.9.2.
 
----
The other way.
Powers method is the same as the above.
{{trans|Python}}
<syntaxhighlight lang="ruby">def filtered(s1, s2)
return enum_for(__method__, s1, s2) unless block_given?
v, f = s1.next, s2.next
loop do
v > f and f = s2.next and next
v < f and yield v
v = s1.next
end
end
 
squares, cubes = powers(2), powers(3)
f = filtered(squares, cubes)
p f.take(30).last(10)
# p f.lazy.drop(20).first(10) # Ruby 2.0+</syntaxhighlight>
Output is the same as the above.
 
=={{header|Rust}}==
<syntaxhighlight lang="rust">use std::cmp::Ordering;
use std::iter::Peekable;
 
fn powers(m: u32) -> impl Iterator<Item = u64> {
(0u64..).map(move |x| x.pow(m))
}
 
fn noncubic_squares() -> impl Iterator<Item = u64> {
NoncubicSquares {
squares: powers(2).peekable(),
cubes: powers(3).peekable(),
}
}
 
struct NoncubicSquares<T: Iterator<Item = u64>, U: Iterator<Item = u64>> {
squares: Peekable<T>,
cubes: Peekable<U>,
}
 
impl<T: Iterator<Item = u64>, U: Iterator<Item = u64>> Iterator for NoncubicSquares<T, U> {
type Item = u64;
fn next(&mut self) -> Option<u64> {
loop {
match self.squares.peek()?.cmp(self.cubes.peek()?) {
Ordering::Equal => self.squares.next(),
Ordering::Greater => self.cubes.next(),
Ordering::Less => return self.squares.next(),
};
}
}
}
 
fn main() {
noncubic_squares()
.skip(20)
.take(10)
.for_each(|x| print!("{} ", x));
println!();
}</syntaxhighlight>
{{out}}
<pre>529 576 625 676 784 841 900 961 1024 1089 </pre>
 
=={{header|Scala}}==
<syntaxhighlight lang="scala">object Generators {
def main(args: Array[String]): Unit = {
def squares(n:Int=0):Stream[Int]=(n*n) #:: squares(n+1)
def cubes(n:Int=0):Stream[Int]=(n*n*n) #:: cubes(n+1)
def filtered(s:Stream[Int], c:Stream[Int]):Stream[Int]={
if(s.head>c.head) filtered(s, c.tail)
else if(s.head<c.head) Stream.cons(s.head, filtered(s.tail, c))
else filtered(s.tail, c)
}
 
filtered(squares(), cubes()) drop 20 take 10 print
}
}</syntaxhighlight>
Here is an alternative filter implementation using pattern matching.
<syntaxhighlight lang="scala">def filtered2(s:Stream[Int], c:Stream[Int]):Stream[Int]=(s, c) match {
case (sh#::_, ch#::ct) if (sh>ch) => filtered2(s, ct)
case (sh#::st, ch#::_) if (sh<ch) => sh #:: filtered2(st, c)
case (_#::st, _) => filtered2(st, c)
}</syntaxhighlight>
{{out}}
<pre>529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089, empty</pre>
 
=={{header|Scheme}}==
===Scheme using conventional closures===
<lang lisp>(define (power-seq n)
<syntaxhighlight lang="lisp">(define (power-seq n)
(let ((i 0))
(lambda ()
Line 1,639 ⟶ 3,828:
(newline))
(seq))
(loop seq (+ 1 i)))))</langsyntaxhighlight>output<lang>576
{{out}}
<pre>576
625
676
Line 1,647 ⟶ 3,838:
961
1024
1089</langpre>
 
===Scheme using ''call with current continuation''===
This method can be elaborated upon to, for instance, provide functionality similar to that of Icon co-expressions.
<syntaxhighlight lang="scheme">
;;; Generators using call/cc.
 
(cond-expand
(r7rs)
(chicken (import r7rs)))
 
(define-library (suspendable-procedures)
(export suspend)
(export make-generator-procedure)
 
(import (scheme base))
 
(begin
 
(define *suspend* (make-parameter (lambda (x) x)))
(define (suspend v) ((*suspend*) v))
 
(define (make-generator-procedure thunk)
;; This is for making a suspendable procedure that takes no
;; arguments when resumed. The result is a simple generator of
;; values.
(define (next-run return)
(define (my-suspend v)
(set! return (call/cc (lambda (resumption-point)
(set! next-run resumption-point)
(return v)))))
(parameterize ((*suspend* my-suspend))
(suspend (thunk))))
(lambda () (call/cc next-run)))
 
)) ;; end library (suspendable-procedures)
 
(import (scheme base))
(import (scheme case-lambda))
(import (scheme write))
(import (suspendable-procedures))
 
(define (make-integers-generator i0)
(make-generator-procedure
(lambda ()
(let loop ((i i0))
(suspend i)
(loop (+ i 1))))))
 
(define make-nth-powers-generator
(case-lambda
((n i0)
(define next-int (make-integers-generator i0))
(make-generator-procedure
(lambda ()
(let loop ()
(suspend (expt (next-int) n))
(loop)))))
((n)
(make-nth-powers-generator n 0))))
 
(define (make-filter-generator gen1 gen2)
(make-generator-procedure
(lambda ()
(let loop ((x1 (gen1))
(x2 (gen2)))
(cond ((= x1 x2) (loop (gen1) x2)) ; Skip this x1.
((< x1 x2) (begin ; Return this x1.
(suspend x1)
(loop (gen1) x2)))
(else (loop x1 (gen2))))))))
 
(define (gen-drop n)
(lambda (generator)
(make-generator-procedure
(lambda ()
(do ((i 0 (+ i 1)))
((= i n))
(generator))
(let loop ()
(suspend (generator))
(loop))))))
 
(define (gen-take n)
(lambda (generator)
(make-generator-procedure
(lambda ()
(do ((i 0 (+ i 1)))
((= i n))
(suspend (generator)))
(let loop ()
(suspend #f)
(loop))))))
 
(define my-generator
((gen-take 10)
((gen-drop 20)
(make-filter-generator
(make-nth-powers-generator 2)
(make-nth-powers-generator 3)))))
 
(let loop ()
(let ((x (my-generator)))
(when x
(display " ")
(display x)
(loop))))
(newline)
</syntaxhighlight>
{{out}}
Using Gauche Scheme.
<pre>$ gosh generator-exponential.scm
529 576 625 676 784 841 900 961 1024 1089</pre>
Using CHICKEN Scheme (which has efficient '''call/cc'''). You will need the '''r7rs''' egg.
<pre>$ csi -s generator-exponential.scm && ./a.out
529 576 625 676 784 841 900 961 1024 1089</pre>
 
=={{header|SenseTalk}}==
The ExponentialGenerator script is a generator object for exponential values.
<syntaxhighlight lang="sensetalk">// ExponentialGenerator.script
 
to initialize
set my base to 0
if my exponent is empty then set my exponent to 1 -- default if not given
end initialize
 
to handle nextValue
add 1 to my base
return my base to the power of my exponent
end nextValue</syntaxhighlight>
 
The FilteredGenerator takes source and filter generators. It gets values from the source generator but excludes those from the filter generator.
<syntaxhighlight lang="sensetalk">// FilteredGenerator.script
 
// Takes a source generator, and a filter generator, which must both produce increasing values
// Produces values from the source generator that don't match values from the filter generator
 
to initialize
set my nextFilteredValue to the nextValue of my filter
end initialize
 
to handle nextValue
put the nextValue of my source into value -- get a candidate value
-- advance the filter as needed if it is behind
repeat while my nextFilteredValue is less than or equal to value
-- advance value if it's equal to the next filtered value
if my nextFilteredValue = value then set value to my source's nextValue
set my nextFilteredValue to my filter's nextValue
end repeat
return value
end nextValue
</syntaxhighlight>
 
This script shows the use of both of the generators.
<syntaxhighlight lang="sensetalk">// Main.script to use the generators
 
set squares to new ExponentialGenerator with {exponent:2}
 
set cubes to new ExponentialGenerator with {exponent:3}
 
put "First 10 Squares:"
repeat 10 times
put squares.nextValue
end repeat
 
put "-" repeated 30 times
 
put "First 10 Cubes:"
repeat 10 times
put cubes.nextValue
end repeat
 
put "-" repeated 30 times
 
set filteredSquares to new FilteredGenerator with {
source: new ExponentialGenerator with {exponent:2},
filter: new ExponentialGenerator with {exponent:3}
}
 
repeat 20 times
get filteredSquares.nextValue
end repeat
 
put "Filtered Squares 21 to 30:"
repeat with n=21 to 30
put n & ":" && filteredSquares.nextValue
end repeat
</syntaxhighlight>
{{out}}
<pre>
First 10 Squares:
1
4
9
16
25
36
49
64
81
100
------------------------------
First 10 Cubes:
1
8
27
64
125
216
343
512
729
1000
------------------------------
Filtered Squares 21 to 30:
21: 529
22: 576
23: 625
24: 676
25: 784
26: 841
27: 900
28: 961
29: 1024
30: 1089
</pre>
 
=={{header|Sidef}}==
{{trans|Perl}}
<syntaxhighlight lang="ruby">func gen_pow(m) {
var e = 0;
func { e++ ** m };
}
 
func gen_filter(g1, g2) {
var v2 = g2.run;
func {
loop {
var v1 = g1.run;
while (v1 > v2) { v2 = g2.run };
v1 == v2 || return v1;
}
}
}
 
# Create generators.
var squares = gen_pow(2);
var cubes = gen_pow(3);
var squares_without_cubes = gen_filter(squares, cubes);
 
# Drop 20 values.
20.times { squares_without_cubes() };
 
# Print 10 values.
var answer = [];
10.times { answer.append(squares_without_cubes()) };
say answer;</syntaxhighlight>
{{out}}
<pre>
[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]
</pre>
 
=={{header|SuperCollider}}==
 
<syntaxhighlight lang="supercollider">
f = { |m| {:x, x<-(0..) } ** m };
g = f.(2);
g.nextN(10); // answers [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ]
</syntaxhighlight>
 
patterns are stream generators:
 
<syntaxhighlight lang="supercollider">(
f = Pseries(0, 1)
g = f ** 2;
g.asStream.nextN(10); // answers [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ]
)
</syntaxhighlight>
 
supercollider has no "without" stream function, this builds one:
 
<syntaxhighlight lang="supercollider">(
var filter = { |a, b, func| // both streams are assumed to be ordered
Prout {
var astr, bstr;
var aval, bval;
astr = a.asStream;
bstr = b.asStream;
bval = bstr.next;
while {
aval = astr.next;
aval.notNil
} {
while {
bval.notNil and: { bval < aval }
} {
bval = bstr.next;
};
if(func.value(aval, bval)) { aval.yield };
}
}
};
var without = filter.(_, _, { |a, b| a != b }); // partially apply function
 
f = Pseries(0, 1);
 
g = without.(f ** 2, f ** 3);
h = g.drop(20);
h.asStream.nextN(10);
)
 
answers: [ 529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089 ]
</syntaxhighlight>
 
=={{header|Swift}}==
<syntaxhighlight lang="swift">func powGen(m: Int) -> GeneratorOf<Int> {
let power = Double(m)
var cur: Double = 0
return GeneratorOf { Int(pow(cur++, power)) }
}
 
var squares = powGen(2)
var cubes = powGen(3)
 
var nCube = cubes.next()
 
var filteredSqs = GeneratorOf<Int> {
for var nSq = squares.next() ;; nCube = cubes.next() {
if nCube > nSq {
return nSq
} else if nCube == nSq {
nSq = squares.next()
}
}
}
 
extension GeneratorOf {
func drop(n: Int) -> GeneratorOf<T> {
var g = self
for _ in 0..<n {g.next()}
return GeneratorOf{g.next()}
}
func take(n: Int) -> GeneratorOf<T> {
var (i, g) = (0, self)
return GeneratorOf{++i > n ? nil : g.next()}
}
}
 
for num in filteredSqs.drop(20).take(10) {
print(num)
}
 
//529
//576
//625
//676
//784
//841
//900
//961
//1024
//1089</syntaxhighlight>
 
=={{header|Tcl}}==
{{works with|Tcl|8.6}}
Tcl implements generators in terms of coroutines.
Tcl implements generators in terms of coroutines. If these generators were terminating, they would finish by doing <code>return -code break</code> so as to terminate the calling loop context that is doing the extraction of the values from the generator.
If these generators were terminating, they would finish by doing <code>return -code break</code> so as to terminate the calling loop context that is doing the extraction of the values from the generator.
<lang tcl>package require Tcl 8.6
<syntaxhighlight lang="tcl">package require Tcl 8.6
 
proc powers m {
Line 1,682 ⟶ 4,237:
for {} {$i<30} {incr i} {
puts [filtered]
}</langsyntaxhighlight>
{{out}}
Output:
<pre>
529
Line 1,696 ⟶ 4,251:
1089
</pre>
 
=={{header|VBA}}==
<syntaxhighlight lang="vb">Public lastsquare As Long
Public nextsquare As Long
Public lastcube As Long
Public midcube As Long
Public nextcube As Long
Private Sub init()
lastsquare = 1
nextsquare = -1
lastcube = -1
midcube = 0
nextcube = 1
End Sub
 
Private Function squares() As Long
lastsquare = lastsquare + nextsquare
nextsquare = nextsquare + 2
squares = lastsquare
End Function
 
Private Function cubes() As Long
lastcube = lastcube + nextcube
nextcube = nextcube + midcube
midcube = midcube + 6
cubes = lastcube
End Function
 
Public Sub main()
init
cube = cubes
For i = 1 To 30
Do While True
square = squares
Do While cube < square
cube = cubes
Loop
If square <> cube Then
Exit Do
End If
Loop
If i > 20 Then
Debug.Print square;
End If
Next i
End Sub</syntaxhighlight>{{out}}
<pre> 529 576 625 676 784 841 900 961 1024 1089 </pre>
 
=={{header|Visual Basic .NET}}==
'''Compiler:''' >= Visual Studio 2012
 
<syntaxhighlight lang="vbnet">Module Program
Iterator Function IntegerPowers(exp As Integer) As IEnumerable(Of Integer)
Dim i As Integer = 0
Do
Yield CInt(Math.Pow(i, exp))
i += 1
Loop
End Function
 
Function Squares() As IEnumerable(Of Integer)
Return IntegerPowers(2)
End Function
 
Function Cubes() As IEnumerable(Of Integer)
Return IntegerPowers(3)
End Function
 
Iterator Function SquaresWithoutCubes() As IEnumerable(Of Integer)
Dim cubeSequence = Cubes().GetEnumerator()
Dim nextGreaterOrEqualCube As Integer = 0
For Each curSquare In Squares()
Do While nextGreaterOrEqualCube < curSquare
cubeSequence.MoveNext()
nextGreaterOrEqualCube = cubeSequence.Current
Loop
If nextGreaterOrEqualCube <> curSquare Then Yield curSquare
Next
End Function
 
Sub Main()
For Each x In From i In SquaresWithoutCubes() Skip 20 Take 10
Console.WriteLine(x)
Next
End Sub
End Module</syntaxhighlight>
 
More concise but slower implementation that relies on LINQ-to-objects to achieve generator behavior (runs slower due to re-enumerating Cubes() for every element of Squares()).
<syntaxhighlight lang="vbnet"> Function SquaresWithoutCubesLinq() As IEnumerable(Of Integer)
Return Squares().Where(Function(s) s <> Cubes().First(Function(c) c >= s))
End Function</syntaxhighlight>
 
{{out}}
<pre>529
576
625
676
784
841
900
961
1024
1089</pre>
 
=={{header|Wren}}==
Closure based solution. Similar approach to Go (first example).
<syntaxhighlight lang="wren">var powers = Fn.new { |m|
var i = 0
return Fn.new {
var p = i.pow(m)
i = i + 1
return p
}
}
 
var squaresNotCubes = Fn.new { |squares, cubes|
var sq = squares.call()
var cu = cubes.call()
return Fn.new {
var p
while (true) {
if (sq < cu) {
p = sq
sq = squares.call()
return p
}
if (sq == cu) sq = squares.call()
cu = cubes.call()
}
}
}
 
var squares = powers.call(2)
var cubes = powers.call(3)
var sqNotCu = squaresNotCubes.call(squares, cubes)
for (i in 0..29) {
var p = sqNotCu.call()
if (i > 19) System.write("%(p) ")
}
System.print()</syntaxhighlight>
 
{{out}}
<pre>
529 576 625 676 784 841 900 961 1024 1089
</pre>
 
=={{header|XPL0}}==
<syntaxhighlight lang="xpl0">code ChOut=8, IntOut=11;
 
func Gen(M); \Generate Mth powers of positive integers
int M;
int N, R, I;
[N:= [0, 0, 0, 0]; \provides own/static variables
R:= 1;
for I:= 1 to M do R:= R*N(M);
N(M):= N(M)+1;
return R;
];
 
func Filter; \Generate squares of positive integers that aren't cubes
int S, C;
[C:= [0]; \static variable = smallest cube > current square
repeat S:= Gen(2);
while S > C(0) do C(0):= Gen(3);
until S # C(0);
return S;
];
 
int I;
[for I:= 1 to 20 do Filter; \drop first 20 values
for I:= 1 to 10 do [IntOut(0, Filter); ChOut(0, ^ )]; \show next 10 values
]</syntaxhighlight>
 
{{out}}
<pre>
529 576 625 676 784 841 900 961 1024 1089
</pre>
 
=={{header|zkl}}==
{{trans|Python}}
Generators are implemented with fibers (aka VMs) and return [lazy] iterators.
<syntaxhighlight lang="zkl">fcn powers(m){ n:=0.0; while(1){vm.yield(n.pow(m).toInt()); n+=1} }
var squared=Utils.Generator(powers,2), cubed=Utils.Generator(powers,3);
 
fcn filtered(sg,cg){s:=sg.next(); c:=cg.next();
while(1){
if(s>c){c=cg.next(); continue;}
else if(s<c) vm.yield(s);
s=sg.next()
}
}
var f=Utils.Generator(filtered,squared,cubed);
f.drop(20);
f.walk(10).println();</syntaxhighlight>
{{out}}
<pre>L(529,576,625,676,784,841,900,961,1024,1089)</pre>
For this task, generators are overkill and overweight,
and lazy infinite squences can be used.
There is no real change to the algorithms (since generators are lazy sequences),
it just has been rewritten in a more functional style.
{{trans|Clojure}}
<syntaxhighlight lang="zkl">fcn powers(m){[0.0..].tweak(fcn(n,m){a:=n; do(m-1){a*=n} a}.fp1(m))}
var squared=powers(2), cubed=powers(3);
 
fcn filtered(sg,cg){s:=sg.peek(); c:=cg.peek();
if(s==c){ cg.next(); sg.next(); return(self.fcn(sg,cg)) }
if(s>c) { cg.next(); return(self.fcn(sg,cg)); }
sg.next(); return(s);
}
var f=[0..].tweak(filtered.fp(squared,cubed))
f.drop(20).walk(10).println();</syntaxhighlight>
9,482

edits