1. 4
  1.  

  2. 4

    There is no need to create a slice of single-value channels in Go, a single channel with or without a buffer more idiomatically implements the pattern.

    Rob Pike explicitly said, no generics

    This is also not true, to the best of my knowledge.

    1. 2

      Here’s a more idiomatic version of the Go code.

      // Definitions
      longComp1 := func() int { return 5 }
      longComp2 := func() int { return 6 }
      fs := []func() int{longComp1, longComp2}
      aggregate := func(a []int) { fmt.Println(a) }
      
      // Scatter
      c := make(chan int, len(fs))
      for _, fn := range fs {
          go func(fn func() int) { c <- fn() }(fn)
      }
      
      // Gather
      var results []int
      for i := 0; i < cap(c); i++ {
          results = append(results, <-c)
      }
      aggregate(results)
      
    2. 2

      I get that core/async Clojure code follows the Go channel example fairly close, but it seems misleading wrt the actual problem of starting two expensive computations and aggregating their results.

      This can be done in Clojure using futures as succinctly as it’s shown to be in Scala.

      1. 3

        Yup, Scala example could be translated directly as:

        (defn long-comp-1 [] 5)
        (defn long-comp-2 [] 6)
        
        (defn aggregate [i j]
          (println "i is" i "j is" j))
        
        (def result-1 (future (long-comp-1)))
        (def result-2 (future (long-comp-2)))
        
        (defn aggregated-future []
          (aggregate @result-1 @result-2))