Skip to content

Fun tricks for stream-style programming: the inevitable, sad but logical conclusion of iterators and generics in Go

License

Notifications You must be signed in to change notification settings

jasonbot/chains

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Feb 21, 2025
414432f · Feb 21, 2025

History

65 Commits
Nov 28, 2024
Nov 24, 2024
Nov 24, 2024
Dec 4, 2024
Dec 1, 2024
Feb 21, 2025
Nov 27, 2024
Dec 4, 2024
Nov 28, 2024
Feb 21, 2025
Dec 4, 2024
Nov 27, 2024
Dec 4, 2024
Nov 28, 2024
Dec 3, 2024
Feb 21, 2025

Repository files navigation

Chained Iterators in Go

I haven't done much in Go lately, and I definitely haven't played with generics or iterators yet. Why not do both?

So now you can do this:

myArray := []int{1, 2, 3}

returnArray := ChainFromSlice(
    []int{8, 10, 145, 3},
).Map(
    func(i int) int {
        return i * 3
    },
).Filter(
    func(i int) bool {
        return i%2 == 0
    },
).Slice()
// returnArray == []int{24, 30}

This library is meant to fill a void in some of the niceness I get in Python and Ruby -- you'll note there is a whole subset of Python's itertools library here.

Examples

Interesting examples live in cookbook_test.

Warts

The Go templating system is a little limited, so you can't do something like this:

arrayOfStrings := ChainFromSlice(
    []int{8, 10, 145, 3},
).Map(
    // Compiler can't infer you're going from Chain[int] to Chain[string]
    func(i int) string {
        return fmt.Sprintf("%v", i)
    },
)

The generic system does not allow for templated methods, so chaining methods and expecting to go from Chain[T] to Chain[V] isn't possible.

You need to give the templating system a hint with a junction, telling it there's 2 types involved:

mapFunc := func(i int) string { return fmt.Sprintf("%v", i) }
array := []int{1, 2, 3, 4}
// Converting type in .Map(), so the generic has to be aware of both types
returnArray := ChainJunction[int, string](ChainFromSlice(
    array,
).Filter(
    func(i int) bool {
        return i%2 == 0
    },
)).Map(
    mapFunc,
).Slice()
// secondreturnArrayArray == []string{"2", "4"}

About

Fun tricks for stream-style programming: the inevitable, sad but logical conclusion of iterators and generics in Go

Topics

Resources

License

Stars

Watchers

Forks

Languages