{"id":37110986,"url":"https://github.com/crosscode-nl/iterator","last_synced_at":"2026-01-14T13:10:20.657Z","repository":{"id":40304273,"uuid":"487279757","full_name":"crosscode-nl/iterator","owner":"crosscode-nl","description":"Implementation of iterators for go using generics","archived":false,"fork":false,"pushed_at":"2022-05-16T12:21:45.000Z","size":83,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2024-06-21T09:55:18.097Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/crosscode-nl.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-30T13:06:44.000Z","updated_at":"2022-05-15T11:52:14.000Z","dependencies_parsed_at":"2022-08-09T16:52:08.377Z","dependency_job_id":null,"html_url":"https://github.com/crosscode-nl/iterator","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/crosscode-nl/iterator","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crosscode-nl%2Fiterator","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crosscode-nl%2Fiterator/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crosscode-nl%2Fiterator/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crosscode-nl%2Fiterator/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/crosscode-nl","download_url":"https://codeload.github.com/crosscode-nl/iterator/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/crosscode-nl%2Fiterator/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28420832,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-01-14T13:10:20.145Z","updated_at":"2026-01-14T13:10:20.650Z","avatar_url":"https://github.com/crosscode-nl.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Iterator [![Total alerts](https://img.shields.io/lgtm/alerts/g/crosscode-nl/iterator.svg?logo=lgtm\u0026logoWidth=18)](https://lgtm.com/projects/g/crosscode-nl/iterator/alerts/) [![Go Report Card](https://goreportcard.com/badge/github.com/crosscode-nl/iterator)](https://goreportcard.com/report/github.com/crosscode-nl/iterator)\n\n## Introduction\n\nThis project is an implementation of iterators for go using generics. I started this project because I like the \nfunctional map/filter/reduce pattern that is offered by many languages. \n\nGo is a simple language - meaning that it is lean in features - but it offers functional principles in the form of \nclosures.\n\nGo did not support generics until version 1.18. Go 1.18.x is at the time of writing (2022-05-06) the latest release version.  \n\nI was wondering if Go would now allow us to write a good type safe iterator framework. \n\nI also wanted to evaluate the Gherkin/Cucumber BDD test framework [Godog](https://github.com/cucumber/godog).\n\n## Usage\n\nPlease take a look at the examples in [iterators_test.go](iterators_test.go), and read the [API documentation](https://pkg.go.dev/github.com/crosscode-nl/iterator).\n\n## Conclusions\n\n### Generics\n\nGo does not support Generics well enough to allow me to design an intuitive framework.\n\n   * Go does not allow for Generic methods. These are required for chaining the operations like: \n     ```go \n      FromSlice(sliceOfStructs).Map(toString).Filter(oneCharacterStrings).Reduce(mostCommonCharacter)\n     ``` \n   * Go is not able to infer types in cases where a generic struct is passed to a generic interface. This is\n     unfortunate because in Go it is expected for functions to accept interfaces and return structs. \n     ```go \n     // This will not compile.\n     iter := FromSlice([]int{1,2,3,4})\n     Map(iter, toString)\n     // This will compile, because we specify the generic type of int when calling the generic Map function.\n     iter := FromSlice([]int{1,2,3,4})\n     Map[int](iter, toString)\n     ```\n     \nThere are workarounds possible for the second issue, such as:\n   * Returning the generic interface from all functions and methods.\n   * Create a method in each type that returns a generic interface from the struct. \n\nReturning a generic interface means a struct can only implement that interface closes a lot of doors for future \nexpansion. \n\nCreating a method in each type that returns a generic interface can make the library harder to use, and is not a lot \nbetter than just specifying the generic type of the receiving function.\n\nSuch a workaround could look like this: \n\n```go\n     iter := FromSlice([]int{1,2,3,4})\n     Map(iter.I(), toString)\n``` \n\nInstead of: \n\n```go\n    iter := FromSlice([]int{1,2,3,4})\n    Map[int](iter, toString)\n```\n\nAlso, because there is no support for generic methods means no generic fluent API like constructs are possible.\n\nSo, I think the current design is the best design for this library yet and future versions of the Go compiler could \nhave improvements on generics which makes this library automatically friendlier to use. \n\n### Godog\n\n[Godog](https://github.com/cucumber/godog) is awesome. \n\n* It is possible to run Godog tests with `go test` by using the subtest functionality of Go. So it \n  will integrate in pipelines already configured for pure go tests.\n* It allows you to write tests in readable language. ([gherkin](https://cucumber.io/docs/gherkin/reference/) DSL)\n* It allows you to reuse test code which makes extending the tests easier the more tests you have written.\n* It generates skeleton code for the features that you have written.\n\nGodog does have some small issues\n \n* Sometimes it does not generate the correct regular expression in the step.   \n  In some cases these need small manual modifications. Not a big issues, because it is easy to modify by hand. \n* The captures in the step are passed as arguments to a function. Godog does not support all build-in types (yet?).\n* There is no 1.0.0 release yet.\n\nIt is a very usable library. The small issues I encountered where easy to workaround.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrosscode-nl%2Fiterator","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcrosscode-nl%2Fiterator","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcrosscode-nl%2Fiterator/lists"}