My efforts to port http://www.youtube.com/watch?v=f6kdp27TYZs to Clojure.
func boring(msg string) {
for i := 0; ; i++ {
fmt.Println(msg, i)
time.Sleep(time.Second)
}
}
(defn boring [msg]
(loop [i 0]
(println msg i)
(Thread/sleep 1000)
(recur (inc i))))
Output:
(boring "boring!")
; boring! 0
; boring! 1
; boring! 2
; boring! 3
; ...
Added random sleep interval of 1 to 1000ms.
func boring(msg string) {
for i := 0; ; i++ {
fmt.Println(msg, i)
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
}
}
func main() {
boring("boring!")
}
(defn boring [msg]
(loop [i 0]
(println msg i)
(Thread/sleep (rand-int 1000))
(recur (inc i))))
(defn -main [& args]
(boring "boring!"))
main
runs forever.
func main() {
go boring("boring!")
}
(defn -main [& args]
(go (boring "boring!")))
main
now returns immediately.
Now, while the goroutine is executing concurrently, we sleep for two seconds before exiting.
func main() {
go boring("boring!")
fmt.Println("I'm listening.")
time.Sleep(2 * time.Second)
fmt.Println("You're boring; I'm leaving.")
}
(defn -main [& args]
(go (boring "boring!"))
(println "I'm listening.")
(Thread/sleep 2000)
(println "You're boring; I'm leaving."))
Output:
I'm listening.
boring! 0
boring! 1
boring! 2
boring! 3
boring! 4
You're boring; I'm leaving.
func boring(msg string, c chan string) {
for i := 0; ; i++ {
c <- fmt.Sprintf("%s %d", msg, i) // Expression to be sent can be any val.
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
}
}
func main() {
c := make(chan string)
go boring("boring!", c)
for i := 0; i < 5; i++ {
fmt.Printf("You say: %q\n", <-c) // Receive expression is just a value.
}
fmt.Println("You're boring; I'm leaving")
}
(defn boring [msg c]
(loop [i 0]
(>!! c (str msg " " i))
(recur (inc i))))
(defn -main [& args]
(let [c (chan)]
(go (boring "boring!" c))
(dotimes [_ 5]
(println (<!! c)))
(println "You're boring; I'm leaving.")))
func boring(msg string) <-chan string { // Returns receive-only channel of strs.
c := make(chan string)
go func() { // We launch the goroutine from inside the function.
for i := 0; ; i++ {
c <- fmt.Sprintf("%s %d", msg, i)
time.Sleep(time.Duration(rand.Intn(1e3)) * time.Millisecond)
}
}()
return c // Return channel to the caller
}
func main() {
c:= boring("boring!") // Function returning a channel.
for i := 0; i < 5; i++ {
fmt.Printf("You say: %q\n", <-c)
}
fmt.Println("You're boring; I'm leaving.")
}
(defn boring [msg]
(let [c (chan)]
(go (loop [i 0]
(>!! c (str msg " " i))
(Thread/sleep (rand-int 1000))
(recur (inc i))))
c))
(defn -main [& args]
(let [c (boring "boring!")]
(dotimes [_ 5]
(println (<!! c)))
(println "You're boring; I'm leaving.")))
func main() {
joe := boring("Joe")
ann := boring("Ann")
for i := 0; i < 5; i++ {
fmt.Println(<-joe)
fmt.Println(<-ann)
}
fmt.Println("You're both boring; I'm leaving.")
}
(defn -main [& args]
(let [joe (boring "Joe")
ann (boring "Ann")]
(dotimes [_ 5]
(println (<!! joe))
(println (<!! ann)))
(println "You're both boring; I'm leaving.")))
func fanIn(input1, input2 <-chan string) <-chan string {
c := make(chan string)
go func() { for { c <- <-input1 } }()
go func() { for { c <- <-input2 } }()
return c
}
func main() {
c := fanIn(boring("Joe"), boring("Ann"))
for i:= 0; i < 10; i++ {
fmt.Println(<-c)
}
fmt.Println("You're both boring; I'm leaving.")
}
I improved the Clojure version of fan-in
by letting it accept any number of channels. It'll sequentially iterate over them forever.
(defn fan-in [& ports] ; joe ->\___c
(let [c (chan)] ; ann ->/
(go (doseq [port (cycle ports)]
(>! c (<! port))))
c))
(defn -main [& args]
(let [c (fan-in (boring "Joe")
(boring "Ann"))]
(dotimes [_ 10]
(println (<!! c)))
(println "You're both boring; I'm leaving.")))