Generator/Exponential: Difference between revisions
Content added Content deleted
m (Emacs Lisp: Style fixes) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 30: | Line 30: | ||
{{trans|C++}} |
{{trans|C++}} |
||
< |
<syntaxhighlight lang="11l">T Generator |
||
F.virtual.abstract next() -> Float |
F.virtual.abstract next() -> Float |
||
Line 70: | Line 70: | ||
gen() |
gen() |
||
L 10 |
L 10 |
||
print(gen(), end' ‘ ’)</ |
print(gen(), end' ‘ ’)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 86: | Line 86: | ||
generator.ads: |
generator.ads: |
||
< |
<syntaxhighlight lang="ada">package Generator is |
||
type Generator is tagged private; |
type Generator is tagged private; |
||
Line 108: | Line 108: | ||
end record; |
end record; |
||
end Generator;</ |
end Generator;</syntaxhighlight> |
||
generator-filtered.ads: |
generator-filtered.ads: |
||
< |
<syntaxhighlight lang="ada">package Generator.Filtered is |
||
type Filtered_Generator is new Generator with private; |
type Filtered_Generator is new Generator with private; |
||
Line 129: | Line 129: | ||
end record; |
end record; |
||
end Generator.Filtered;</ |
end Generator.Filtered;</syntaxhighlight> |
||
generator.adb: |
generator.adb: |
||
< |
<syntaxhighlight lang="ada">package body Generator is |
||
-------------- |
-------------- |
||
Line 193: | Line 193: | ||
end Set_Generator_Function; |
end Set_Generator_Function; |
||
end Generator;</ |
end Generator;</syntaxhighlight> |
||
generator-filtered.adb: |
generator-filtered.adb: |
||
< |
<syntaxhighlight lang="ada">package body Generator.Filtered is |
||
----------- |
----------- |
||
Line 254: | Line 254: | ||
end Set_Filter; |
end Set_Filter; |
||
end Generator.Filtered;</ |
end Generator.Filtered;</syntaxhighlight> |
||
example use: |
example use: |
||
< |
<syntaxhighlight lang="ada">with Ada.Text_IO; |
||
with Generator.Filtered; |
with Generator.Filtered; |
||
Line 291: | Line 291: | ||
end loop; |
end loop; |
||
end Generator_Test;</ |
end Generator_Test;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 309: | Line 309: | ||
{{works with|ALGOL 68G|Any - tested with release [http://sourceforge.net/projects/algol68/files/algol68g/algol68g-2.3.5 algol68g-2.3.5].}} |
{{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''.}} |
{{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'''< |
'''File: Template.Generator.a68'''<syntaxhighlight lang="algol68">MODE YIELDVALUE = PROC(VALUE)VOID; |
||
MODE GENVALUE = PROC(YIELDVALUE)VOID; |
MODE GENVALUE = PROC(YIELDVALUE)VOID; |
||
Line 371: | Line 371: | ||
PROC powers = (VALUE m, YIELDVALUE yield)VOID: |
PROC powers = (VALUE m, YIELDVALUE yield)VOID: |
||
FOR n FROM 0 DO yield(n ** m) OD;</ |
FOR n FROM 0 DO yield(n ** m) OD;</syntaxhighlight>'''File: test.Generator.a68'''<syntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script # |
||
MODE VALUE = INT; |
MODE VALUE = INT; |
||
Line 379: | Line 379: | ||
GENVALUE fil = gen filtered(squares, cubes,); |
GENVALUE fil = gen filtered(squares, cubes,); |
||
printf(($g(0)x$, get list(gen slice(fil, 20, 30, )) ))</ |
printf(($g(0)x$, get list(gen slice(fil, 20, 30, )) ))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 389: | Line 389: | ||
{{Trans|JavaScript}} |
{{Trans|JavaScript}} |
||
{{Trans|Python}} |
{{Trans|Python}} |
||
< |
<syntaxhighlight lang="applescript">----------------- EXPONENTIAL / GENERATOR ---------------- |
||
-- powers :: Gen [Int] |
-- powers :: Gen [Int] |
||
Line 620: | Line 620: | ||
end |λ| |
end |λ| |
||
end script |
end script |
||
end zipGen</ |
end zipGen</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>{529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089}</pre> |
<pre>{529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089}</pre> |
||
Line 632: | Line 632: | ||
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. |
||
< |
<syntaxhighlight lang="c">#include <inttypes.h> /* int64_t, PRId64 */ |
||
#include <stdlib.h> /* exit() */ |
#include <stdlib.h> /* exit() */ |
||
#include <stdio.h> /* printf() */ |
#include <stdio.h> /* printf() */ |
||
Line 793: | Line 793: | ||
gen.free(&gen); /* Free memory. */ |
gen.free(&gen); /* Free memory. */ |
||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
One must download [http://byuu.org/programming/ libco] and give libco.c to the compiler. |
One must download [http://byuu.org/programming/ libco] and give libco.c to the compiler. |
||
Line 803: | Line 803: | ||
===Using struct to store state=== |
===Using struct to store state=== |
||
< |
<syntaxhighlight lang="c">#include <stdio.h> |
||
#include <stdlib.h> |
#include <stdlib.h> |
||
#include <math.h> |
#include <math.h> |
||
Line 876: | Line 876: | ||
return 0; |
return 0; |
||
}</ |
}</syntaxhighlight> |
||
{{out}}<pre>529 |
{{out}}<pre>529 |
||
576 |
576 |
||
Line 889: | Line 889: | ||
=={{header|C sharp}}== |
=={{header|C sharp}}== |
||
< |
<syntaxhighlight lang="csharp">using System; |
||
using System.Collections.Generic; |
using System.Collections.Generic; |
||
using System.Linq; |
using System.Linq; |
||
Line 907: | Line 907: | ||
while (true) yield return i++; |
while (true) yield return i++; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
=={{header|C++}}== |
=={{header|C++}}== |
||
Line 913: | Line 913: | ||
A templated solution. |
A templated solution. |
||
< |
<syntaxhighlight lang="cpp">#include <iostream> |
||
using namespace std; |
using namespace std; |
||
Line 978: | Line 978: | ||
for(int i = 20; i < 30; ++i) |
for(int i = 20; i < 30; ++i) |
||
cout << i << ": " << gen() << endl; |
cout << i << ": " << gen() << endl; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,002: | Line 1,002: | ||
Thus we can define squares and cubes as lazy sequences: |
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))))) |
||
(def squares (powers 2)) |
(def squares (powers 2)) |
||
(take 5 squares) ; => (1 4 9 16 25)</ |
(take 5 squares) ; => (1 4 9 16 25)</syntaxhighlight> |
||
The definition here of the squares-not-cubes lazy sequence uses the loop/recur construct, |
The definition here of the squares-not-cubes lazy sequence uses the loop/recur construct, |
||
which isn't lazy. So we use ''lazy-seq'' explicity: |
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-not-cubes (powers 2) (powers 3))) |
||
([squares cubes] |
([squares cubes] |
||
Line 1,019: | Line 1,019: | ||
(->> (squares-not-cubes) (drop 20) (take 10)) |
(->> (squares-not-cubes) (drop 20) (take 10)) |
||
; => (529 576 625 676 784 841 900 961 1024 1089)</ |
; => (529 576 625 676 784 841 900 961 1024 1089)</syntaxhighlight> |
||
If we really need a generator function for some reason, any lazy sequence |
If we really need a generator function for some reason, any lazy sequence |
||
Line 1,025: | Line 1,025: | ||
function ''repeatedly''.) |
function ''repeatedly''.) |
||
< |
<syntaxhighlight lang="clojure">(defn seq->fn [sequence] |
||
(let [state (atom (cons nil sequence))] |
(let [state (atom (cons nil sequence))] |
||
(fn [] (first (swap! state rest))) |
(fn [] (first (swap! state rest))) |
||
(def f (seq->fn (squares-not-cubes))) |
(def f (seq->fn (squares-not-cubes))) |
||
[(f) (f) (f)] ; => [4 9 16]</ |
[(f) (f) (f)] ; => [4 9 16]</syntaxhighlight> |
||
=={{header|Common Lisp}}== |
=={{header|Common Lisp}}== |
||
< |
<syntaxhighlight lang="lisp">(defun take (seq &optional (n 1)) |
||
(values-list (loop repeat n collect (funcall seq)))) |
(values-list (loop repeat n collect (funcall seq)))) |
||
Line 1,053: | Line 1,053: | ||
(let ((2not3 (filter-seq (power-seq 2) (power-seq 3)))) |
(let ((2not3 (filter-seq (power-seq 2) (power-seq 3)))) |
||
(take 2not3 20) ;; drop 20 |
(take 2not3 20) ;; drop 20 |
||
(princ (multiple-value-list (take 2not3 10))))</ |
(princ (multiple-value-list (take 2not3 10))))</syntaxhighlight> |
||
=={{header|D}}== |
=={{header|D}}== |
||
===Efficient Standard Version=== |
===Efficient Standard Version=== |
||
< |
<syntaxhighlight lang="d">void main() { |
||
import std.stdio, std.bigint, std.range, std.algorithm; |
import std.stdio, std.bigint, std.range, std.algorithm; |
||
Line 1,064: | Line 1,064: | ||
squares.setDifference(cubes).drop(20).take(10).writeln; |
squares.setDifference(cubes).drop(20).take(10).writeln; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
||
Line 1,070: | Line 1,070: | ||
===Simple Ranges-Based Implementation=== |
===Simple Ranges-Based Implementation=== |
||
{{trans|C#}} |
{{trans|C#}} |
||
< |
<syntaxhighlight lang="d">void main() { |
||
import std.stdio, std.bigint, std.range, std.algorithm; |
import std.stdio, std.bigint, std.range, std.algorithm; |
||
Line 1,081: | Line 1,081: | ||
.take(10) |
.take(10) |
||
.writeln; |
.writeln; |
||
}</ |
}</syntaxhighlight> |
||
The output is the same. |
The output is the same. |
||
===More Efficient Ranges-Based Version=== |
===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)) { |
struct Filtered(R1, R2) if (is(ElementType!R1 == ElementType!R2)) { |
||
Line 1,131: | Line 1,131: | ||
auto cubes = 0.sequence!"n".map!(i => i.BigInt ^^ 3); |
auto cubes = 0.sequence!"n".map!(i => i.BigInt ^^ 3); |
||
filtered(squares, cubes).drop(20).take(10).writeln; |
filtered(squares, cubes).drop(20).take(10).writeln; |
||
}</ |
}</syntaxhighlight> |
||
The output is the same. |
The output is the same. |
||
===Closures-Based Version=== |
===Closures-Based Version=== |
||
{{trans|Go}} |
{{trans|Go}} |
||
< |
<syntaxhighlight lang="d">import std.stdio; |
||
auto powers(in double e) pure nothrow { |
auto powers(in double e) pure nothrow { |
||
Line 1,169: | Line 1,169: | ||
write(fgen(), " "); |
write(fgen(), " "); |
||
writeln; |
writeln; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>529 576 625 676 784 841 900 961 1024 1089 </pre> |
<pre>529 576 625 676 784 841 900 961 1024 1089 </pre> |
||
===Generator Range Version=== |
===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 { |
auto powers(in uint m) pure nothrow @safe { |
||
Line 1,201: | Line 1,201: | ||
auto squares = 2.powers, cubes = 3.powers; |
auto squares = 2.powers, cubes = 3.powers; |
||
filtered(squares, cubes).drop(20).take(10).writeln; |
filtered(squares, cubes).drop(20).take(10).writeln; |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
||
Line 1,209: | Line 1,209: | ||
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. |
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. |
||
< |
<syntaxhighlight lang="e">def genPowers(exponent) { |
||
var i := -1 |
var i := -1 |
||
return def powerGenerator() { |
return def powerGenerator() { |
||
Line 1,243: | Line 1,243: | ||
print(`${squaresNotCubes()} `) |
print(`${squaresNotCubes()} `) |
||
} |
} |
||
println()</ |
println()</syntaxhighlight> |
||
=={{header|EchoLisp}}== |
=={{header|EchoLisp}}== |
||
< |
<syntaxhighlight lang="scheme"> |
||
(lib 'tasks) ;; for make-generator |
(lib 'tasks) ;; for make-generator |
||
Line 1,283: | Line 1,283: | ||
; inspect |
; inspect |
||
task → #generator:state: 1331 |
task → #generator:state: 1331 |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Elixir}}== |
=={{header|Elixir}}== |
||
{{trans|Erlang}} |
{{trans|Erlang}} |
||
< |
<syntaxhighlight lang="elixir">defmodule Generator do |
||
def filter( source_pid, remove_pid ) do |
def filter( source_pid, remove_pid ) do |
||
first_remove = next( remove_pid ) |
first_remove = next( remove_pid ) |
||
Line 1,333: | Line 1,333: | ||
end |
end |
||
IO.inspect Generator.task</ |
IO.inspect Generator.task</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 1,344: | Line 1,344: | ||
This code requires generator library which was introduced in Emacs 25.2 |
This code requires generator library which was introduced in Emacs 25.2 |
||
< |
<syntaxhighlight lang="lisp">;; lexical-binding: t |
||
(require 'generator) |
(require 'generator) |
||
Line 1,371: | Line 1,371: | ||
(setq o (iter-next g)) |
(setq o (iter-next g)) |
||
(when (>= i 20) |
(when (>= i 20) |
||
(print o))))</ |
(print o))))</syntaxhighlight> |
||
=={{header|Erlang}}== |
=={{header|Erlang}}== |
||
<syntaxhighlight lang="erlang"> |
|||
<lang Erlang> |
|||
-module( generator ). |
-module( generator ). |
||
Line 1,412: | Line 1,412: | ||
receive {next, Pid} -> Pid ! erlang:round(math:pow(N, M) ) end, |
receive {next, Pid} -> Pid ! erlang:round(math:pow(N, M) ) end, |
||
power_loop( M, N + 1 ). |
power_loop( M, N + 1 ). |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,421: | Line 1,421: | ||
=={{header|F_Sharp|F#}}== |
=={{header|F_Sharp|F#}}== |
||
{{trans|C#}} |
{{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 squares = m 2 |
||
Line 1,431: | Line 1,431: | ||
Seq.take 10 (Seq.skip 20 (``squares without cubes``)) |
Seq.take 10 (Seq.skip 20 (``squares without cubes``)) |
||
|> Seq.toList |> printfn "%A"</ |
|> Seq.toList |> printfn "%A"</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>[529; 576; 625; 676; 784; 841; 900; 961; 1024; 1089]</pre> |
<pre>[529; 576; 625; 676; 784; 841; 900; 961; 1024; 1089]</pre> |
||
Line 1,437: | Line 1,437: | ||
=={{header|Factor}}== |
=={{header|Factor}}== |
||
Using lazy lists for our generators: |
Using lazy lists for our generators: |
||
< |
<syntaxhighlight lang="factor">USING: fry kernel lists lists.lazy math math.functions |
||
prettyprint ; |
prettyprint ; |
||
IN: rosetta-code.generator-exponential |
IN: rosetta-code.generator-exponential |
||
Line 1,451: | Line 1,451: | ||
[ 3 mth-powers-generator lmember? not ] <lazy-filter> ; |
[ 3 mth-powers-generator lmember? not ] <lazy-filter> ; |
||
10 2-not-3-generator 20 [ cdr ] times ltake list>array .</ |
10 2-not-3-generator 20 [ cdr ] times ltake list>array .</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,461: | Line 1,461: | ||
Using closures to implement generators. |
Using closures to implement generators. |
||
< |
<syntaxhighlight lang="fantom"> |
||
class Main |
class Main |
||
{ |
{ |
||
Line 1,502: | Line 1,502: | ||
} |
} |
||
} |
} |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 1,519: | Line 1,519: | ||
=={{header|Forth}}== |
=={{header|Forth}}== |
||
<syntaxhighlight lang="forth"> |
|||
<lang Forth> |
|||
\ genexp-rcode.fs Generator/Exponential for RosettaCode.org |
\ genexp-rcode.fs Generator/Exponential for RosettaCode.org |
||
Line 1,566: | Line 1,566: | ||
:noname 0 Counter ! 1 Sqroot ! 1 Cbroot ! 0 (go) drop ; |
:noname 0 Counter ! 1 Sqroot ! 1 Cbroot ! 0 (go) drop ; |
||
execute cr bye |
execute cr bye |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,577: | Line 1,577: | ||
=={{header|FreeBASIC}}== |
=={{header|FreeBASIC}}== |
||
{{trans|VBA}} |
{{trans|VBA}} |
||
< |
<syntaxhighlight lang="freebasic">Dim Shared As Long lastsquare, nextsquare, lastcube, midcube, nextcube |
||
Function squares() As Long |
Function squares() As Long |
||
Line 1,606: | Line 1,606: | ||
If i > 20 Then Print square; |
If i > 20 Then Print square; |
||
Next i |
Next i |
||
Sleep</ |
Sleep</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,616: | Line 1,616: | ||
{{trans|Haskell}} (for the powers function) |
{{trans|Haskell}} (for the powers function) |
||
{{trans|Scala}} (for the filter) |
{{trans|Scala}} (for the filter) |
||
< |
<syntaxhighlight lang="funl">def powers( m ) = map( (^ m), 0.. ) |
||
def |
def |
||
Line 1,623: | Line 1,623: | ||
filtered( _:st, c ) = filtered( st, c ) |
filtered( _:st, c ) = filtered( st, c ) |
||
println( filtered(powers(2), powers(3)).drop(20).take(10) )</ |
println( filtered(powers(2), powers(3)).drop(20).take(10) )</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,631: | Line 1,631: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Most direct and most efficient on a single core is implementing generators with closures. |
Most direct and most efficient on a single core is implementing generators with closures. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 1,677: | Line 1,677: | ||
} |
} |
||
fmt.Println() |
fmt.Println() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 1,691: | Line 1,691: | ||
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. |
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. |
This allows more flexibility in structuring code. |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 1,738: | Line 1,738: | ||
} |
} |
||
fmt.Println() |
fmt.Println() |
||
}</ |
}</syntaxhighlight> |
||
=={{header|Haskell}}== |
=={{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: |
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">import Data.List.Ordered |
||
powers :: Int -> [Int] |
powers :: Int -> [Int] |
||
Line 1,757: | Line 1,757: | ||
main :: IO () |
main :: IO () |
||
main = print $ take 10 $ drop 20 foo</ |
main = print $ take 10 $ drop 20 foo</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>[529,576,625,676,784,841,900,961,1024,1089]</pre> |
<pre>[529,576,625,676,784,841,900,961,1024,1089]</pre> |
||
Line 1,765: | Line 1,765: | ||
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. |
||
< |
<syntaxhighlight lang="icon">procedure main() |
||
write("Non-cube Squares (21st to 30th):") |
write("Non-cube Squares (21st to 30th):") |
||
Line 1,789: | Line 1,789: | ||
} |
} |
||
} |
} |
||
end</ |
end</syntaxhighlight> |
||
Note: The task could be written without co-expressions but would be likely be ugly. |
Note: The task could be written without co-expressions but would be likely be ugly. |
||
Line 1,813: | Line 1,813: | ||
Here is a generator for mth powers of a number: |
Here is a generator for mth powers of a number: |
||
< |
<syntaxhighlight lang="j">coclass 'mthPower' |
||
N=: 0 |
N=: 0 |
||
create=: 3 :0 |
create=: 3 :0 |
||
Line 1,822: | Line 1,822: | ||
N=: N+1 |
N=: N+1 |
||
n^M |
n^M |
||
)</ |
)</syntaxhighlight> |
||
And, here are corresponding square and cube generators |
And, here are corresponding square and cube generators |
||
< |
<syntaxhighlight lang="j">stateySquare=: 2 conew 'mthPower' |
||
stateyCube=: 3 conew 'mthPower'</ |
stateyCube=: 3 conew 'mthPower'</syntaxhighlight> |
||
Here is a generator for squares which are not cubes: |
Here is a generator for squares which are not cubes: |
||
< |
<syntaxhighlight lang="j">coclass 'uncubicalSquares' |
||
N=: 0 |
N=: 0 |
||
next=: 3 :0"0 |
next=: 3 :0"0 |
||
while. (-: <.) 3 %: *: n=. N do. N=: N+1 end. N=: N+1 |
while. (-: <.) 3 %: *: n=. N do. N=: N+1 end. N=: N+1 |
||
*: n |
*: n |
||
)</ |
)</syntaxhighlight> |
||
And here is an example of its use: |
And here is an example of its use: |
||
< |
<syntaxhighlight lang="j"> next__g i.10 [ next__g i.20 [ g=: conew 'uncubicalSquares' |
||
529 576 625 676 784 841 900 961 1024 1089</ |
529 576 625 676 784 841 900 961 1024 1089</syntaxhighlight> |
||
That said, here is a more natural approach, for J. |
That said, here is a more natural approach, for J. |
||
< |
<syntaxhighlight lang="j">mthPower=: 1 :'^&m@i.' |
||
squares=: 2 mthPower |
squares=: 2 mthPower |
||
cubes=: 3 mthPower |
cubes=: 3 mthPower |
||
uncubicalSquares=: squares -. cubes</ |
uncubicalSquares=: squares -. cubes</syntaxhighlight> |
||
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: |
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: |
||
< |
<syntaxhighlight lang="j">uncubicalSquares=: {. squares@<.@p.~&3 1.1 -. cubes</syntaxhighlight> |
||
Example use: |
Example use: |
||
< |
<syntaxhighlight lang="j">20 }. uncubicalSquares 30 NB. the 21st through 30th uncubical square |
||
529 576 625 676 784 841 900 961 1024 1089</ |
529 576 625 676 784 841 900 961 1024 1089</syntaxhighlight> |
||
=={{header|Java}}== |
=={{header|Java}}== |
||
{{works with|java|8}} |
{{works with|java|8}} |
||
< |
<syntaxhighlight lang="java">import java.util.function.LongSupplier; |
||
import static java.util.stream.LongStream.generate; |
import static java.util.stream.LongStream.generate; |
||
Line 1,913: | Line 1,913: | ||
return n * n * n++; |
return n * n * n++; |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
<pre>529 576 625 676 784 841 900 961 1024 1089</pre> |
<pre>529 576 625 676 784 841 900 961 1024 1089</pre> |
||
Line 1,921: | Line 1,921: | ||
{{works with|Firefox 3.6 using JavaScript 1.7|}} |
{{works with|Firefox 3.6 using JavaScript 1.7|}} |
||
<syntaxhighlight lang="javascript"> |
|||
<lang JavaScript> |
|||
function PowersGenerator(m) { |
function PowersGenerator(m) { |
||
var n=0; |
var n=0; |
||
Line 1,959: | Line 1,959: | ||
for( var x = 20; x < 30; x++ ) console.logfiltered.next()); |
for( var x = 20; x < 30; x++ ) console.logfiltered.next()); |
||
</syntaxhighlight> |
|||
</lang> |
|||
====ES6==== |
====ES6==== |
||
< |
<syntaxhighlight lang="javascript">function* nPowerGen(n) { |
||
let e = 0; |
let e = 0; |
||
while (1) { e++ && (yield Math.pow(e, n)); } |
while (1) { e++ && (yield Math.pow(e, n)); } |
||
Line 1,981: | Line 1,981: | ||
} |
} |
||
const filtered = filterGen(nPowerGen(2), nPowerGen(3), skip=20);</ |
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++) { |
for (let n = 0; n < 10; n++) { |
||
console.log(filtered.next().value) |
console.log(filtered.next().value) |
||
}</ |
}</syntaxhighlight> |
||
<pre>529 |
<pre>529 |
||
576 |
576 |
||
Line 2,001: | Line 2,001: | ||
Compositional derivation of custom generators: |
Compositional derivation of custom generators: |
||
{{Trans|Python}} |
{{Trans|Python}} |
||
< |
<syntaxhighlight lang="javascript">(() => { |
||
'use strict'; |
'use strict'; |
||
Line 2,155: | Line 2,155: | ||
// MAIN --- |
// MAIN --- |
||
return main(); |
return main(); |
||
})();</ |
})();</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>[529,576,625,676,784,841,900,961,1024,1089]</pre> |
<pre>[529,576,625,676,784,841,900,961,1024,1089]</pre> |
||
Line 2,168: | Line 2,168: | ||
relevant state information. For convenience, a counter is usually |
relevant state information. For convenience, a counter is usually |
||
included. For generating i^m, therefore, we would have: |
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); |
def pow(m): . as $in | reduce range(0;m) as $i (1; .*$in); |
||
# state: [i, i^m] |
# state: [i, i^m] |
||
def next_power(m): .[0] + 1 | [., pow(m) ];</ |
def next_power(m): .[0] + 1 | [., pow(m) ];</syntaxhighlight> |
||
To make such generators easier to use, we shall define filters to |
To make such generators easier to use, we shall define filters to |
||
skip and to emit a specified number of items: |
skip and to emit a specified number of items: |
||
< |
<syntaxhighlight lang="jq"># skip m states, and return the next state |
||
def skip(m; next): |
def skip(m; next): |
||
if m <= 0 then . else next | skip(m-1; next) end; |
if m <= 0 then . else next | skip(m-1; next) end; |
||
Line 2,181: | Line 2,181: | ||
# emit m states including the initial state |
# emit m states including the initial state |
||
def emit(m; next): |
def emit(m; next): |
||
if m <= 0 then empty else ., (next | emit(m-1; next)) end;</ |
if m <= 0 then empty else ., (next | emit(m-1; next)) end;</syntaxhighlight> |
||
'''Examples''': |
'''Examples''': |
||
< |
<syntaxhighlight lang="jq"># Generate the first 4 values in the sequence i^2: |
||
[0,0] | emit(4; next_power(2)) | .[1] |
[0,0] | emit(4; next_power(2)) | .[1] |
||
# Generate all the values in the sequence i^3 less than 100: |
# 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]</ |
[0,0] | recurse(next_power(3) | if .[1] < 100 then . else empty end) | .[1]</syntaxhighlight> |
||
'''An aside on streams''' |
'''An aside on streams''' |
||
Line 2,196: | Line 2,196: | ||
'''Part 2: selection from 2 ^ m''' |
'''Part 2: selection from 2 ^ m''' |
||
< |
<syntaxhighlight lang="jq"># Infrastructure: |
||
def last(f): reduce f as $i (null; $i); |
def last(f): reduce f as $i (null; $i); |
||
Line 2,222: | Line 2,222: | ||
| skip(20; filtered_next_power(2;3)) |
| skip(20; filtered_next_power(2;3)) |
||
| emit(10; filtered_next_power(2;3)) |
| emit(10; filtered_next_power(2;3)) |
||
| .[0][1]</ |
| .[0][1]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
< |
<syntaxhighlight lang="sh">$ jq -n -f generators.jq |
||
529 |
529 |
||
576 |
576 |
||
Line 2,234: | Line 2,234: | ||
961 |
961 |
||
1024 |
1024 |
||
1089</ |
1089</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
The task can be achieved by using closures, iterators or tasks. Here is a solution using anonymous functions and closures. |
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) |
take(gen::Function, n::Integer) = collect(gen() for _ in 1:n) |
||
Line 2,258: | Line 2,258: | ||
end |
end |
||
@show take(drop(genfilter(pgen(2), pgen(3)), 20), 10)</ |
@show take(drop(genfilter(pgen(2), pgen(3)), 20), 10)</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,265: | Line 2,265: | ||
=={{header|Kotlin}}== |
=={{header|Kotlin}}== |
||
Coroutines were introduced in version 1.1 of Kotlin but, as yet, are an experimental feature: |
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 |
// compiled with flag -Xcoroutines=enable to suppress 'experimental' warning |
||
Line 2,301: | Line 2,301: | ||
ncs.drop(20).take(10).forEach { print("$it ") } // print 21st to 30th items |
ncs.drop(20).take(10).forEach { print("$it ") } // print 21st to 30th items |
||
println() |
println() |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,310: | Line 2,310: | ||
=={{header|Lingo}}== |
=={{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. |
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) |
cubes = script("generator.power").new(3) |
||
filter = script("generator.filter").new(squares, cubes) |
filter = script("generator.filter").new(squares, cubes) |
||
Line 2,320: | Line 2,320: | ||
if i>10 then exit repeat |
if i>10 then exit repeat |
||
put res[1] |
put res[1] |
||
end repeat</ |
end repeat</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,338: | Line 2,338: | ||
Parent script "generator.power" |
Parent script "generator.power" |
||
< |
<syntaxhighlight lang="lingo">property _exp |
||
property _index |
property _index |
||
Line 2,360: | Line 2,360: | ||
on reset (me) |
on reset (me) |
||
me._index = 0 |
me._index = 0 |
||
end</ |
end</syntaxhighlight> |
||
Parent script "generator.filter" |
Parent script "generator.filter" |
||
< |
<syntaxhighlight lang="lingo">property _genv |
||
property _genf |
property _genf |
||
Line 2,406: | Line 2,406: | ||
me._genv.reset() |
me._genv.reset() |
||
me._genf.reset() |
me._genf.reset() |
||
end</ |
end</syntaxhighlight> |
||
=={{header|Lua}}== |
=={{header|Lua}}== |
||
Generators can be implemented both as closures and as coroutines. The following example demonstrates both. |
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. |
--could be done with a coroutine, but a simple closure works just as well. |
||
local function powgen(m) |
local function powgen(m) |
||
Line 2,450: | Line 2,450: | ||
end |
end |
||
end |
end |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|M2000 Interpreter}}== |
=={{header|M2000 Interpreter}}== |
||
<syntaxhighlight lang="m2000 interpreter"> |
|||
<lang M2000 Interpreter> |
|||
Module Generator { |
Module Generator { |
||
PowGen = Lambda (e)-> { |
PowGen = Lambda (e)-> { |
||
Line 2,493: | Line 2,493: | ||
} |
} |
||
Generator |
Generator |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 2,513: | Line 2,513: | ||
{{trans|VBA}} |
{{trans|VBA}} |
||
Generators are not very natural in Mathemetica, because they avoid the use of lists and instead rely on sequential processing. |
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; |
nextsquare = -1; |
||
lastcube = -1; |
lastcube = -1; |
||
Line 2,548: | Line 2,548: | ||
, |
, |
||
{i, 30} |
{i, 30} |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>529 |
<pre>529 |
||
Line 2,562: | Line 2,562: | ||
=={{header|Nim}}== |
=={{header|Nim}}== |
||
< |
<syntaxhighlight lang="nim">type Iterator = iterator(): int |
||
proc `^`*(base: Natural; exp: Natural): int = |
proc `^`*(base: Natural; exp: Natural): int = |
||
Line 2,600: | Line 2,600: | ||
if i > 20: echo x |
if i > 20: echo x |
||
if i >= 30: break |
if i >= 30: break |
||
inc i</ |
inc i</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,616: | Line 2,616: | ||
=={{header|OCaml}}== |
=={{header|OCaml}}== |
||
Original version by [http://rosettacode.org/wiki/User:Vanyamil User:Vanyamil] |
Original version by [http://rosettacode.org/wiki/User:Vanyamil User:Vanyamil] |
||
<syntaxhighlight lang="ocaml"> |
|||
<lang OCaml> |
|||
(* Task : Generator/Exponential |
(* Task : Generator/Exponential |
||
Line 2,707: | Line 2,707: | ||
let _ = |
let _ = |
||
squares_no_cubes |> drop 20 |> take 10 |
squares_no_cubes |> drop 20 |> take 10 |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,715: | Line 2,715: | ||
=={{header|PARI/GP}}== |
=={{header|PARI/GP}}== |
||
Define two generator functions genpow() and genpow2(). |
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]; |
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;</ |
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> |
''genpow(power)'' returns a function that returns a simple power generator.<br> |
||
Line 2,757: | Line 2,757: | ||
These generators are anonymous subroutines, which are closures. |
These generators are anonymous subroutines, which are closures. |
||
< |
<syntaxhighlight lang="perl"># gen_pow($m) creates and returns an anonymous subroutine that will |
||
# generate and return the powers 0**m, 1**m, 2**m, ... |
# generate and return the powers 0**m, 1**m, 2**m, ... |
||
sub gen_pow { |
sub gen_pow { |
||
Line 2,793: | Line 2,793: | ||
my @answer; |
my @answer; |
||
push @answer, $squares_without_cubes->() for (1..10); |
push @answer, $squares_without_cubes->() for (1..10); |
||
print "[", join(", ", @answer), "]\n";</ |
print "[", join(", ", @answer), "]\n";</syntaxhighlight> |
||
{{out}}<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
{{out}}<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
<!--< |
<!--<syntaxhighlight lang="phix">(notonline)--> |
||
<span style="color: #000080;font-style:italic;">-- |
<span style="color: #000080;font-style:italic;">-- |
||
-- demo\rosetta\Generator_Exponential.exw |
-- demo\rosetta\Generator_Exponential.exw |
||
Line 2,844: | Line 2,844: | ||
<span style="color: #000000;">terminate</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</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> |
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 2,862: | Line 2,862: | ||
{{trans|Python}} |
{{trans|Python}} |
||
{{works with|PHP|5.5+}} |
{{works with|PHP|5.5+}} |
||
< |
<syntaxhighlight lang="php"><?php |
||
function powers($m) { |
function powers($m) { |
||
for ($n = 0; ; $n++) { |
for ($n = 0; ; $n++) { |
||
Line 2,891: | Line 2,891: | ||
$f->next(); |
$f->next(); |
||
} |
} |
||
?></ |
?></syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 2,909: | Line 2,909: | ||
=={{header|PicoLisp}}== |
=={{header|PicoLisp}}== |
||
Coroutines are available only in the 64-bit version. |
Coroutines are available only in the 64-bit version. |
||
< |
<syntaxhighlight lang="picolisp">(de powers (M) |
||
(co (intern (pack 'powers M)) |
(co (intern (pack 'powers M)) |
||
(for (I 0 (inc 'I)) |
(for (I 0 (inc 'I)) |
||
Line 2,924: | Line 2,924: | ||
(do 20 (filtered 2 3)) |
(do 20 (filtered 2 3)) |
||
(do 10 (println (filtered 2 3)))</ |
(do 10 (println (filtered 2 3)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>529 |
<pre>529 |
||
Line 2,938: | Line 2,938: | ||
=={{header|PL/I}}== |
=={{header|PL/I}}== |
||
<syntaxhighlight lang="pl/i"> |
|||
<lang PL/I> |
|||
Generate: procedure options (main); /* 27 October 2013 */ |
Generate: procedure options (main); /* 27 October 2013 */ |
||
declare j fixed binary; |
declare j fixed binary; |
||
Line 2,983: | Line 2,983: | ||
end Generate; |
end Generate; |
||
</syntaxhighlight> |
|||
</lang> |
|||
<pre> |
<pre> |
||
20 dropped values: |
20 dropped values: |
||
Line 2,997: | Line 2,997: | ||
{{works with|Python|2.6+ and 3.x}} (in versions prior to 2.6, replace <code>next(something)</code> with <code>something.next()</code>) |
{{works with|Python|2.6+ and 3.x}} (in versions prior to 2.6, replace <code>next(something)</code> with <code>something.next()</code>) |
||
< |
<syntaxhighlight lang="python">from itertools import islice, count |
||
def powers(m): |
def powers(m): |
||
Line 3,015: | Line 3,015: | ||
squares, cubes = powers(2), powers(3) |
squares, cubes = powers(2), powers(3) |
||
f = filtered(squares, cubes) |
f = filtered(squares, cubes) |
||
print(list(islice(f, 20, 30)))</ |
print(list(islice(f, 20, 30)))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,024: | Line 3,024: | ||
{{Works with|Python|3.7}} |
{{Works with|Python|3.7}} |
||
< |
<syntaxhighlight lang="python">'''Exponentials as generators''' |
||
from itertools import count, islice |
from itertools import count, islice |
||
Line 3,105: | Line 3,105: | ||
# MAIN --- |
# MAIN --- |
||
if __name__ == '__main__': |
if __name__ == '__main__': |
||
main()</ |
main()</syntaxhighlight> |
||
{{Out}} |
{{Out}} |
||
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
<pre>[529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089]</pre> |
||
Line 3,111: | Line 3,111: | ||
=={{header|Quackery}}== |
=={{header|Quackery}}== |
||
< |
<syntaxhighlight lang="quackery"> [ ' [ this -1 peek |
||
this -2 peek ** |
this -2 peek ** |
||
1 this tally |
1 this tally |
||
Line 3,140: | Line 3,140: | ||
20 times [ dup do drop ] |
20 times [ dup do drop ] |
||
10 times [ dup do echo sp ] |
10 times [ dup do echo sp ] |
||
drop</ |
drop</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,148: | Line 3,148: | ||
=={{header|R}}== |
=={{header|R}}== |
||
< |
<syntaxhighlight lang="rsplus">powers = function(m) |
||
{n = -1 |
{n = -1 |
||
function() |
function() |
||
Line 3,172: | Line 3,172: | ||
noncubic.squares() |
noncubic.squares() |
||
for (i in 1:10) |
for (i in 1:10) |
||
message(noncubic.squares())</ |
message(noncubic.squares())</syntaxhighlight> |
||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
Line 3,200: | Line 3,200: | ||
[i 30] #:when (>= i 20)) |
[i 30] #:when (>= i 20)) |
||
x) |
x) |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
Line 3,211: | Line 3,211: | ||
{{works with|rakudo|2015.12}} |
{{works with|rakudo|2015.12}} |
||
As with Haskell, generators are disguised as lazy lists in Raku. |
As with Haskell, generators are disguised as lazy lists in Raku. |
||
<lang |
<syntaxhighlight lang="raku" line>sub powers($m) { $m XR** 0..* } |
||
my @squares = powers(2); |
my @squares = powers(2); |
||
Line 3,223: | Line 3,223: | ||
} |
} |
||
say (@squares with-out @cubes)[20 ..^ 20+10].join(', ');</ |
say (@squares with-out @cubes)[20 ..^ 20+10].join(', ');</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,230: | Line 3,230: | ||
=={{header|REXX}}== |
=={{header|REXX}}== |
||
<br>The generators (below, the <big> Gxxxxx </big> functions) lie dormant until a request is made for a specific generator index. |
<br>The generators (below, the <big> Gxxxxx </big> functions) lie dormant until a request is made for a specific generator index. |
||
< |
<syntaxhighlight lang="rexx">/*REXX program demonstrates how to use a generator (also known as an iterator). */ |
||
parse arg N .; if N=='' | N=="," then N=20 /*N not specified? Then use default.*/ |
parse arg N .; if N=='' | N=="," then N=20 /*N not specified? Then use default.*/ |
||
@.= /* [↓] calculate squares,cubes,pureSq.*/ |
@.= /* [↓] calculate squares,cubes,pureSq.*/ |
||
Line 3,265: | Line 3,265: | ||
#=#+1; @.pureSquare.#=? /*assign next pureSquare. */ |
#=#+1; @.pureSquare.#=? /*assign next pureSquare. */ |
||
end /*j*/ |
end /*j*/ |
||
return @.pureSquare.x</ |
return @.pureSquare.x</syntaxhighlight> |
||
'''output''' when using the default value: |
'''output''' when using the default value: |
||
<pre> |
<pre> |
||
Line 3,285: | Line 3,285: | ||
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. |
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! |
||
def powers(m) |
def powers(m) |
||
Line 3,304: | Line 3,304: | ||
p squares_without_cubes.take(30).drop(20) |
p squares_without_cubes.take(30).drop(20) |
||
# p squares_without_cubes.lazy.drop(20).first(10) # Ruby 2.0+</ |
# p squares_without_cubes.lazy.drop(20).first(10) # Ruby 2.0+</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,314: | Line 3,314: | ||
Here is the correct solution, which obeys the ''requirement'' of ''three'' generators. |
Here is the correct solution, which obeys the ''requirement'' of ''three'' generators. |
||
< |
<syntaxhighlight lang="ruby"># This solution uses three generators. |
||
def powers(m) |
def powers(m) |
||
Line 3,336: | Line 3,336: | ||
answer = squares_without_cubes # third generator |
answer = squares_without_cubes # third generator |
||
20.times { answer.next } |
20.times { answer.next } |
||
p 10.times.map { answer.next }</ |
p 10.times.map { answer.next }</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,348: | Line 3,348: | ||
Powers method is the same as the above. |
Powers method is the same as the above. |
||
{{trans|Python}} |
{{trans|Python}} |
||
< |
<syntaxhighlight lang="ruby">def filtered(s1, s2) |
||
return enum_for(__method__, s1, s2) unless block_given? |
return enum_for(__method__, s1, s2) unless block_given? |
||
v, f = s1.next, s2.next |
v, f = s1.next, s2.next |
||
Line 3,361: | Line 3,361: | ||
f = filtered(squares, cubes) |
f = filtered(squares, cubes) |
||
p f.take(30).last(10) |
p f.take(30).last(10) |
||
# p f.lazy.drop(20).first(10) # Ruby 2.0+</ |
# p f.lazy.drop(20).first(10) # Ruby 2.0+</syntaxhighlight> |
||
Output is the same as the above. |
Output is the same as the above. |
||
=={{header|Rust}}== |
=={{header|Rust}}== |
||
< |
<syntaxhighlight lang="rust">use std::cmp::Ordering; |
||
use std::iter::Peekable; |
use std::iter::Peekable; |
||
Line 3,403: | Line 3,403: | ||
.for_each(|x| print!("{} ", x)); |
.for_each(|x| print!("{} ", x)); |
||
println!(); |
println!(); |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>529 576 625 676 784 841 900 961 1024 1089 </pre> |
<pre>529 576 625 676 784 841 900 961 1024 1089 </pre> |
||
=={{header|Scala}}== |
=={{header|Scala}}== |
||
< |
<syntaxhighlight lang="scala">object Generators { |
||
def main(args: Array[String]): Unit = { |
def main(args: Array[String]): Unit = { |
||
def squares(n:Int=0):Stream[Int]=(n*n) #:: squares(n+1) |
def squares(n:Int=0):Stream[Int]=(n*n) #:: squares(n+1) |
||
Line 3,421: | Line 3,421: | ||
filtered(squares(), cubes()) drop 20 take 10 print |
filtered(squares(), cubes()) drop 20 take 10 print |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Here is an alternative filter implementation using pattern matching. |
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#::_, ch#::ct) if (sh>ch) => filtered2(s, ct) |
||
case (sh#::st, ch#::_) if (sh<ch) => sh #:: filtered2(st, c) |
case (sh#::st, ch#::_) if (sh<ch) => sh #:: filtered2(st, c) |
||
case (_#::st, _) => filtered2(st, c) |
case (_#::st, _) => filtered2(st, c) |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089, empty</pre> |
<pre>529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089, empty</pre> |
||
=={{header|Scheme}}== |
=={{header|Scheme}}== |
||
< |
<syntaxhighlight lang="lisp">(define (power-seq n) |
||
(let ((i 0)) |
(let ((i 0)) |
||
(lambda () |
(lambda () |
||
Line 3,458: | Line 3,458: | ||
(newline)) |
(newline)) |
||
(seq)) |
(seq)) |
||
(loop seq (+ 1 i)))))</ |
(loop seq (+ 1 i)))))</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>576 |
<pre>576 |
||
Line 3,472: | Line 3,472: | ||
=={{header|SenseTalk}}== |
=={{header|SenseTalk}}== |
||
The ExponentialGenerator script is a generator object for exponential values. |
The ExponentialGenerator script is a generator object for exponential values. |
||
< |
<syntaxhighlight lang="sensetalk">// ExponentialGenerator.script |
||
to initialize |
to initialize |
||
Line 3,482: | Line 3,482: | ||
add 1 to my base |
add 1 to my base |
||
return my base to the power of my exponent |
return my base to the power of my exponent |
||
end nextValue</ |
end nextValue</syntaxhighlight> |
||
The FilteredGenerator takes source and filter generators. It gets values from the source generator but excludes those from the filter generator. |
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 |
// Takes a source generator, and a filter generator, which must both produce increasing values |
||
Line 3,506: | Line 3,506: | ||
return value |
return value |
||
end nextValue |
end nextValue |
||
</syntaxhighlight> |
|||
</lang> |
|||
This script shows the use of both of the generators. |
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 squares to new ExponentialGenerator with {exponent:2} |
||
Line 3,542: | Line 3,542: | ||
put n & ":" && filteredSquares.nextValue |
put n & ":" && filteredSquares.nextValue |
||
end repeat |
end repeat |
||
</syntaxhighlight> |
|||
</lang> |
|||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,584: | Line 3,584: | ||
=={{header|Sidef}}== |
=={{header|Sidef}}== |
||
{{trans|Perl}} |
{{trans|Perl}} |
||
< |
<syntaxhighlight lang="ruby">func gen_pow(m) { |
||
var e = 0; |
var e = 0; |
||
func { e++ ** m }; |
func { e++ ** m }; |
||
Line 3,611: | Line 3,611: | ||
var answer = []; |
var answer = []; |
||
10.times { answer.append(squares_without_cubes()) }; |
10.times { answer.append(squares_without_cubes()) }; |
||
say answer;</ |
say answer;</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,619: | Line 3,619: | ||
=={{header|SuperCollider}}== |
=={{header|SuperCollider}}== |
||
<syntaxhighlight lang="supercollider"> |
|||
<lang SuperCollider> |
|||
f = { |m| {:x, x<-(0..) } ** m }; |
f = { |m| {:x, x<-(0..) } ** m }; |
||
g = f.(2); |
g = f.(2); |
||
g.nextN(10); // answers [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ] |
g.nextN(10); // answers [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ] |
||
</syntaxhighlight> |
|||
</lang> |
|||
patterns are stream generators: |
patterns are stream generators: |
||
<syntaxhighlight lang="supercollider">( |
|||
<lang SuperCollider>( |
|||
f = Pseries(0, 1) |
f = Pseries(0, 1) |
||
g = f ** 2; |
g = f ** 2; |
||
g.asStream.nextN(10); // answers [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ] |
g.asStream.nextN(10); // answers [ 0, 1, 4, 9, 16, 25, 36, 49, 64, 81 ] |
||
) |
) |
||
</syntaxhighlight> |
|||
</lang> |
|||
supercollider has no "without" stream function, this builds one: |
supercollider has no "without" stream function, this builds one: |
||
<syntaxhighlight lang="supercollider">( |
|||
<lang SuperCollider>( |
|||
var filter = { |a, b, func| // both streams are assumed to be ordered |
var filter = { |a, b, func| // both streams are assumed to be ordered |
||
Prout { |
Prout { |
||
Line 3,667: | Line 3,667: | ||
answers: [ 529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089 ] |
answers: [ 529, 576, 625, 676, 784, 841, 900, 961, 1024, 1089 ] |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Swift}}== |
=={{header|Swift}}== |
||
< |
<syntaxhighlight lang="swift">func powGen(m: Int) -> GeneratorOf<Int> { |
||
let power = Double(m) |
let power = Double(m) |
||
var cur: Double = 0 |
var cur: Double = 0 |
||
Line 3,716: | Line 3,716: | ||
//961 |
//961 |
||
//1024 |
//1024 |
||
//1089</ |
//1089</syntaxhighlight> |
||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
Line 3,722: | Line 3,722: | ||
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. |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.6 |
||
proc powers m { |
proc powers m { |
||
Line 3,752: | Line 3,752: | ||
for {} {$i<30} {incr i} { |
for {} {$i<30} {incr i} { |
||
puts [filtered] |
puts [filtered] |
||
}</ |
}</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 3,768: | Line 3,768: | ||
=={{header|VBA}}== |
=={{header|VBA}}== |
||
< |
<syntaxhighlight lang="vb">Public lastsquare As Long |
||
Public nextsquare As Long |
Public nextsquare As Long |
||
Public lastcube As Long |
Public lastcube As Long |
||
Line 3,811: | Line 3,811: | ||
End If |
End If |
||
Next i |
Next i |
||
End Sub</ |
End Sub</syntaxhighlight>{{out}} |
||
<pre> 529 576 625 676 784 841 900 961 1024 1089 </pre> |
<pre> 529 576 625 676 784 841 900 961 1024 1089 </pre> |
||
Line 3,817: | Line 3,817: | ||
'''Compiler:''' >= Visual Studio 2012 |
'''Compiler:''' >= Visual Studio 2012 |
||
< |
<syntaxhighlight lang="vbnet">Module Program |
||
Iterator Function IntegerPowers(exp As Integer) As IEnumerable(Of Integer) |
Iterator Function IntegerPowers(exp As Integer) As IEnumerable(Of Integer) |
||
Dim i As Integer = 0 |
Dim i As Integer = 0 |
||
Line 3,851: | Line 3,851: | ||
Next |
Next |
||
End Sub |
End Sub |
||
End Module</ |
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()). |
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)) |
Return Squares().Where(Function(s) s <> Cubes().First(Function(c) c >= s)) |
||
End Function</ |
End Function</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,871: | Line 3,871: | ||
=={{header|XPL0}}== |
=={{header|XPL0}}== |
||
< |
<syntaxhighlight lang="xpl0">code ChOut=8, IntOut=11; |
||
func Gen(M); \Generate Mth powers of positive integers |
func Gen(M); \Generate Mth powers of positive integers |
||
Line 3,895: | Line 3,895: | ||
[for I:= 1 to 20 do Filter; \drop first 20 values |
[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 |
for I:= 1 to 10 do [IntOut(0, Filter); ChOut(0, ^ )]; \show next 10 values |
||
]</ |
]</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,904: | Line 3,904: | ||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Closure based solution. Similar approach to Go (first example). |
Closure based solution. Similar approach to Go (first example). |
||
< |
<syntaxhighlight lang="ecmascript">var powers = Fn.new { |m| |
||
var i = 0 |
var i = 0 |
||
return Fn.new { |
return Fn.new { |
||
Line 3,937: | Line 3,937: | ||
if (i > 19) System.write("%(p) ") |
if (i > 19) System.write("%(p) ") |
||
} |
} |
||
System.print()</ |
System.print()</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
Line 3,947: | Line 3,947: | ||
{{trans|Python}} |
{{trans|Python}} |
||
Generators are implemented with fibers (aka VMs) and return [lazy] iterators. |
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); |
var squared=Utils.Generator(powers,2), cubed=Utils.Generator(powers,3); |
||
Line 3,959: | Line 3,959: | ||
var f=Utils.Generator(filtered,squared,cubed); |
var f=Utils.Generator(filtered,squared,cubed); |
||
f.drop(20); |
f.drop(20); |
||
f.walk(10).println();</ |
f.walk(10).println();</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>L(529,576,625,676,784,841,900,961,1024,1089)</pre> |
<pre>L(529,576,625,676,784,841,900,961,1024,1089)</pre> |
||
Line 3,967: | Line 3,967: | ||
it just has been rewritten in a more functional style. |
it just has been rewritten in a more functional style. |
||
{{trans|Clojure}} |
{{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); |
var squared=powers(2), cubed=powers(3); |
||
Line 3,976: | Line 3,976: | ||
} |
} |
||
var f=[0..].tweak(filtered.fp(squared,cubed)) |
var f=[0..].tweak(filtered.fp(squared,cubed)) |
||
f.drop(20).walk(10).println();</ |
f.drop(20).walk(10).println();</syntaxhighlight> |