{"id":13850346,"url":"https://github.com/kulshekhar/fungen","last_synced_at":"2025-05-04T19:35:55.433Z","repository":{"id":66028467,"uuid":"47915109","full_name":"kulshekhar/fungen","owner":"kulshekhar","description":"Replace boilerplate code with functional patterns using 'go generate'","archived":false,"fork":false,"pushed_at":"2018-02-24T17:34:55.000Z","size":27,"stargazers_count":124,"open_issues_count":4,"forks_count":8,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-05-03T00:10:04.630Z","etag":null,"topics":["filter","functional","go","golang","map","reduce"],"latest_commit_sha":null,"homepage":"","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/kulshekhar.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,"governance":null}},"created_at":"2015-12-13T10:45:37.000Z","updated_at":"2025-04-23T11:54:50.000Z","dependencies_parsed_at":"2023-07-15T04:45:15.863Z","dependency_job_id":null,"html_url":"https://github.com/kulshekhar/fungen","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kulshekhar%2Ffungen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kulshekhar%2Ffungen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kulshekhar%2Ffungen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kulshekhar%2Ffungen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kulshekhar","download_url":"https://codeload.github.com/kulshekhar/fungen/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252390722,"owners_count":21740374,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["filter","functional","go","golang","map","reduce"],"created_at":"2024-08-04T20:01:07.463Z","updated_at":"2025-05-04T19:35:55.145Z","avatar_url":"https://github.com/kulshekhar.png","language":"Go","funding_links":[],"categories":["Go"],"sub_categories":[],"readme":"# fungen [![Build Status](https://api.travis-ci.org/kulshekhar/fungen.svg?branch=master)](https://travis-ci.org/kulshekhar/fungen)\n\n\nfungen is a tool that can be used with `go generate` to automate the creation of list like types and methods like Map, Filter, Reduce, etc on these types.\n\nThis allows you to use constructs like the following on lists of any types:\n\n```go\n\nmyList.Map(func(t type1) type1 {\n\n...\n\n}).Filter(func(t type1) bool {\n\n...\n\n}).Take(3).Reduce(initialValue type1, func (prev type1, current type1) type1 {\n\n...\n\n})\n\n```\n\nThe `Map` and `Filter` methods have parallel counterparts `PMap` and `PFilter` which can be used to parallelize time consuming operations.\n\n__Note:__ This tool uses standard golang constructs to make this functionality available on any type - standard and custom. Interfaces have NOT been used.\n\n## Motivation\n\nWhile the `for` loop in Go is quite nice, it still involves some boilerplate code. In my particular case, I realized that I could eliminate a majority of that code by using the following constructs:\n\n- __Map__ (apply a function to each member of a list and return the resulting list - of either the same type or a different type)\n- __PMap__ (parallel map)\n- __Filter__ (apply a function to each member of a list to retrieve only the ones that satisfy some criteria)\n- __PFilter__ (parallel filter)\n- __FilterMap__ (applies the filter(s) and map to the list members in a single loop and returns the resulting list containing members of the mapped type)\n- __PFilterMap__ (parallel FilterMap)\n- __Reduce__ (perform aggregation functions on a list)\n- __ReduceRight__\n- __Each__ (execute any function on each element of a list)\n- __EachI__\n- __Take__ (create a new list containing only the first n elements of another list)\n- __TakeWhile__ (take the first elements that satisfy a particular criteria)\n- __Drop__ (create a new list by excluding the first n elements of another list)\n- __DropWhile__ (exclude the first elements that satisfy a particular criteria)\n- __All__ (returns true if all the members of the list satisfy a function or if the list is empty)\n- __Any__ (returns true if at least one member of the list satisfies a function)\n\n## How to Use\n\nAssuming you have installed `fungen` (see below), you can start by including the comment in your file for `go generate` to process. Let's assume we want to use the above methods with a list of strings (type []string).\n\nAdd the following comment in your source code:\n\n```go\n//go:generate fungen -types string\n```\n\nNow run the `go generate` command in the same directory where this source file is located. This will generate a file named `fungen_auto.go` in this directory. This file will contain the type and method definitions that you'll need.\n\nIf you take a look at the file, you'll see that a new type has been created:\n\n```go\ntype stringList []string\n```\n\nIf you now use this type (`stringList`) in place of `[]string`, you'll be able to use all the above mentioned methods on that list of string.\n\n```go\n\nwords := stringList{\"calculator\", \"skip\", \"grape\", \"obtainable\", \"inexpensive\", \"panoramic\", \"powerful\"}\n\nwordsWithLengthLessThan7 := words.Filter(func(w string) bool {\n  return len(w) \u003c 7  \n})\n// wordsWithLengthLessThan7 = [skip grape]\n\n```\n\n## Installation\n\n```\ngo install github.com/kulshekhar/fungen\n```\n\n## Code Generation\nThe complete command to generate the code:\n\n```\nfungen -package PackageName -types comma,Separated,Types,With,Optional:Opt,short:Sh,names:n\n```\n\n### Use from source code:\n\n```go\n//go:generate fungen -types string,int\n```\nfollowed by\n```\ngo generate\n```\non the command line, in the directory where you wish the generated file to be stored.\n\n\n### Use From the command line:\n\n```\nfungen -types string,int\n```\n\nThis tool will generate as a file named `fungen_auto.go`.\n\n## Explanation of Options\n\n```\n-package PackageName\n```\n\nThe `-package` parameter is optional. If specified, it will generate the code file by using `package PackageName` at the top. If omitted, it will generate the code file by using `package main` at the top. \n\n```\n-types comma,Separated,Types,With,Optional:Opt,short:Sh,names:n\n```\n\nThe `-types` parameter takes a comma separated list of types for which the list type and methods on this type should be generated. eg: (int,string,uint,customType)\n\nEach of the comma separated values can themselves optionally be a colon separated value. If this is the case, the first part (before the colon) should be a valid type name (built in or custom) and the second is the name used in the names of the methods.\n\n```\n-filename filename.go\n```\n\nFilename for generated package (default \"fungen_auto.go\"). The `-filename` parameter is optional.\n\n```\n-methods Map,Filter\n```\n\nComma separated list of methods to generate. By default generate all methods.\n\nValid methods is: Map,PMap,Filter,PFilter,Reduce,ReduceRight,Each,EachI,Take,TakeWhile,Drop,DropWhile,All,Any,FilterMap,PFilterMap\n\n#### Example 1\n\nIf `-types int,string` is used, the types generated will be:\n\n```go\ntype intList []int\ntype stringList []string\n\n```\n\nThe following methods will be available on both these types:\n\n```\nMap\nPMap\nFilter\nPFilter\nReduce\nReduceRight\nTake\nTakeWhile\nDrop\nDropWhile\nEach\nEachI\nAll\nAny\n\n```\n\nAdditionally, the `intList` type will have the following methods:\n\n```\nMapString\nPMapString\nFilterMapString\nPFilterMapString\n```\n\nAnd the `stringList` type will have the following methods:\n\n```\nMapInt\nPMapInt\nFilterMapInt\nPFilterMapInt\n```\n\n#### Example 2\n\nIf `-types int:I,string:Str` is used, the names of the common set of methods generated will be the same as above. However, the types and the additional methods generated will have different names.\n\nThe types will be named as follows:\n\n```go\ntype IList []int\ntype StrList []string\n\n```\n\n\nThe `IList` type will have the following methods:\n\n```\nMapStr\nPMapStr\n```\n\nAnd the `StrList` type will have the following methods:\n\n```\nMapI\nPMapI\n```\n\n#### Feedback, critique and contributions are all welcome.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkulshekhar%2Ffungen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkulshekhar%2Ffungen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkulshekhar%2Ffungen/lists"}