Hacker News new | ask | show | jobs
by camdencheek 1249 days ago
Fair criticism. The nice thing about the current API is it works with any input that's iterable (channels, slices, readers, etc.) and any output (callback, channel, append to slice, etc.). In most code I write, I avoid channels because I find them easy to misuse. I used channels in the examples because it's the easiest way to represent "some potentially unbounded stream of input."
1 comments

I just wrote a bunch of separate short functions for different types (channels, slices, maps). There is more code duplication but code itself is simpler, and less boiler-platey and more embeddable.

For example

    out := MapSlice(
       func(i int) string { return fmt.Sprintf("-=0x%02x=-", i) },
       MapSlice(
          func(i int) int { return i + 1 },
          MapSlice(
             func(i int) int { return i * i },
             GenSlice(10, func(idx int) int { return idx }),
          ),
       ),
    )
or piping workers

    out :=
       WorkerPoolBackgroundClose(
          WorkerPoolBackgroundClose(
             WorkerPoolBackgroundClose(
                GenChanNClose(3, func(idx int) int { return idx + 1 }),
                func(i int) string { return strconv.Itoa(i) },
                4),
             func(s string) string { return ">" + s },
             5,
          ),
          func(s string) string { return " |" + s },
          6)