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:
 
=={{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
 
Line 245 ⟶ 241:
 
// note: exponent not limited to ints
func powChnewPowGen(e float64) <-chanfunc() float64 {
chvar := make(chani float64)
goreturn func() (r float64) {
r = math.Pow(i, e)
// generate powers of non-negative integers
for i := float64(0); ; i++ {
ch <- math.Pow(i, e)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
chSqa, b := powChaf(), bf(2)
// of non-negative integers.
chFreturn :=func() make(chanr float64) {
func genMonotonicIncA_NotMonotonicIncB(outCh chan<- float64,
for {
aCh, bCh <-chan float64) {
for a, b := <-aCh, if a <-bCh; ;b {
if a > b { r = a
b a = <-bChaf()
continue break
} else if a < b {}
outChif <-b == a {
a = af()
}
b = bf()
}
a = <-aChreturn
}
}
 
func main() {
fGen := newMonoIncA_NotMonoIncB_Gen(newPowGen(2), newPowGen(3))
// square and cube generators
chSq := powCh(2)
chCu := powCh(3)
 
// filtered generator (in two lines)
chF := make(chan float64)
go genMonotonicIncA_NotMonotonicIncB(chF, chSq, chCu)
 
// collect results
for i := 0; i < 20; i++ {
<-chFfGen()
}
for i := 0; i < 10; i++ {
fmt.Print(<-chFfGen(), " ")
}
fmt.Println("")
}</lang>
}
</lang>
Output:
<pre>