Generator/Exponential: Difference between revisions
Content added Content deleted
(→{{libheader|libco}}: Add some ugly code to check for memory allocation, and to free memory. C is being an awful language.) |
(→{{header|Go}}: better implementation. replaced entire program.) |
||
Line 232: | Line 232: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
Most direct and most efficient on a single core is implementing generators with closures. |
|||
Generators can be implemented directly in Go by a channel fed by a goroutine. |
|||
Thus a "function returning a generator" corresponds to a function that creates a channel, starts a goroutine that will send values on the channel, and returns the channel. The function powCh does this, starting a function literal as the goroutine. The returned channel corresponds to a generator. |
|||
The "generator that filters..." is implemented without an extra function, simply by creating the channel and starting a (previously declared) function as a goroutine. Here too, the created channel, chF, corresponds to a generator, once the goroutine has be started for it. |
|||
<lang go>package main |
<lang go>package main |
||
Line 245: | Line 241: | ||
// note: exponent not limited to ints |
// note: exponent not limited to ints |
||
func |
func newPowGen(e float64) func() float64 { |
||
var i float64 |
|||
return func() (r float64) { |
|||
r = math.Pow(i, e) |
|||
// generate powers of non-negative integers |
|||
i++ |
|||
return |
|||
} |
|||
}() |
|||
return ch |
|||
} |
} |
||
// given two functions af, bf, both monotonically increasing, return a |
|||
// this long function name to indicate that the filtering |
|||
// new function that returns values of af not returned by bf. |
|||
// logic works only because squares and cubes are both |
|||
func newMonoIncA_NotMonoIncB_Gen(af, bf func() float64) func() float64 { |
|||
// monotonically increasing over the specified domain |
|||
⚫ | |||
// of non-negative integers. |
|||
⚫ | |||
func genMonotonicIncA_NotMonotonicIncB(outCh chan<- float64, |
|||
for { |
|||
aCh, bCh <-chan float64) { |
|||
if a < b { |
|||
r = a |
|||
a = af() |
|||
break |
|||
} |
|||
if b == a { |
|||
a = af() |
|||
} |
|||
b = bf() |
|||
} |
} |
||
return |
|||
} |
} |
||
} |
} |
||
func main() { |
func main() { |
||
fGen := newMonoIncA_NotMonoIncB_Gen(newPowGen(2), newPowGen(3)) |
|||
// square and cube generators |
|||
⚫ | |||
chCu := powCh(3) |
|||
// filtered generator (in two lines) |
|||
⚫ | |||
go genMonotonicIncA_NotMonotonicIncB(chF, chSq, chCu) |
|||
// collect results |
|||
for i := 0; i < 20; i++ { |
for i := 0; i < 20; i++ { |
||
fGen() |
|||
} |
} |
||
for i := 0; i < 10; i++ { |
for i := 0; i < 10; i++ { |
||
fmt.Print( |
fmt.Print(fGen(), " ") |
||
} |
} |
||
fmt.Println("") |
fmt.Println("") |
||
⚫ | |||
} |
|||
⚫ | |||
Output: |
Output: |
||
<pre> |
<pre> |