top | item 34346904

(no title)

camdencheek | 3 years 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."

discuss

order

ilyt|3 years ago

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)