Skip to content

Commit

Permalink
Merge pull request #5 from life4/go1.18
Browse files Browse the repository at this point in the history
Go 1.18 generics!
  • Loading branch information
orsinium committed Dec 21, 2021
2 parents d2ed89b + 74e6933 commit bc0ff61
Show file tree
Hide file tree
Showing 152 changed files with 3,316 additions and 100,001 deletions.
21 changes: 21 additions & 0 deletions .drone.star
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
def main(ctx):
return dict(
kind="pipeline",
type="docker",
name="default",
trigger=dict(
branch="master",
),
steps=[
go_test(),
],
)

def go_test():
return dict(
name="go test",
image="golang:1.18beta1-alpine3.14",
commands=[
"go test -cover ./...",
],
)
53 changes: 0 additions & 53 deletions .travis.yml

This file was deleted.

104 changes: 38 additions & 66 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,94 +1,66 @@
# Genesis

[![Build Status](https://travis-ci.org/life4/genesis.svg?branch=master)](https://travis-ci.org/life4/genesis)
Generic functions for Go. Bringing the beauty of functional programming in Go 1.18+.

Missed golang generic stdlib for slices and channels.
**Features:**

**Some functions:**
+ Uses the power of Go 1.18+ generics.
+ No code generation.
+ No dependencies (except [is](https://github.com/matryer/is) for testing).
+ Pure Go.
+ Sync and async versions of all the main functions.
+ For slices and channels.

+ Filter, Map, Reduce.
+ Min, Max, Sum.
+ Permutations, Product.
+ Any, All.
+ Contains, Find.
+ Shuffle, Sort.
+ Range, Count, Cycle.
**When to use:**

And much more.
+ In a big project. More the project grows, more you find yourself writing oring generic code like "Min". Break the cyrcle.
+ In a team project. Each like of code you write means higher maintenance cost that in turn means loosing time and money.
+ In a pet project. Leave the boring stuff to us, focus on the fun parts.
+ When readability matters. `slices.Shrink` is a function with a human-friendly name and documentation. `s[:len(s):len(s)]` is a jibberish and black magic. Prefer the former.
+ When you miss some conveniences that come in other languages out-of-the-box.
+ When you write a highly concurrent code and don't want to manually implement code for cancellation, results collection and ordering, worker groups, context, etc.

**Features:**
**What's inside**:

+ Typesafe.
+ Sync and async versions.
+ For slices and channels.
+ Pre-generated for all built-in types.
+ `Filter`, `Map`, and `Reduce` for data processing on steroids.
+ `FilterAsync`, `MapAsync`, and `ReduceAsync` for making your code fast and concurrent with a single line of code.
+ `Grow` and `Shrink` for reducing memory allocations.
+ `Permutations` and `Product` for simple iterations.
+ `Shuffle` and `Sort` for randomization.
+ `Any` and `All` for simple flow control.
+ `Range`, `Count`, and `Cycle` for generating sequences.

And much more.

## Installation

```bash
go get github.com/life4/genesis
```

## Examples

Find minimal value in a slice of ints:
Find the minimal value in a slice of ints:

```go
s := []int{42, 7, 13}
min := genesis.SliceInt{s}.Min()
lambdas.Must(slices.Min([]int{42, 7, 13})) == 7
```

Double values in a slice of ints:

```go
s := []int{4, 8, 15, 16, 23, 42}
double := func(el int) int { return el * 2 }
doubled := genesis.SliceInt{s}.MapInt(double)
```

See [docs](./docs) to dive deeper.

## Custom types

Genesis contains pre-generated code for common built-in types. So, in most cases you can just use it. However, if you want to use genesis for custom types, things become a little bit more complicated. The first option is to use an empty interface. For example:

```go
type UserId int
ids := []UserId{1, 2, 3, 4, 5}
// https://github.com/golang/go/wiki/InterfaceSlice
idsInterface := make([]interface{}, len(ids), len(ids))
for i := range ids {
idsInterface[i] = ids[i]
}
index := genesis.SliceInterface{idsInterface}.FindIndex(
func(el interface{}) bool { return el.(UserId) == 3 },
)
fmt.Println(index)
// Output: 2
```

Another option is to generate genesis code for your own type.

## Generation

Install requirements

```bash
python3 -m pip install --user -r requirements.txt
slices.Map([]int{4, 8, 15}, func(el int) int { return el * 2 })
```

Re-generate everything for built-in types:
## Usage

```bash
python3 -m generate
```

Generate a new package with given types:

```bash
python3 -m generate
```
Genesis contains the following packages:

## [>>> DOCUMENTATION <<<](./docs)
+ [slices](https://pkg.go.dev/github.com/life4/genesis/slices): generic functions for slices.
+ [maps](https://pkg.go.dev/github.com/life4/genesis/maps): generic functions for maps.
+ [channels](https://pkg.go.dev/github.com/life4/genesis/channels): generic function for channels.
+ [lambdas](https://pkg.go.dev/github.com/life4/genesis/lambdas): helper generic functions to work with `slices.Map` and similar.

All code is autogenerated, so `go doc` output is quite messy. Hence we have [docs](./docs) folder with a nice generated documentation for everything. Enjoy.
See [documentation](https://pkg.go.dev/github.com/life4/genesis) for more information.

![](./gopher.png)
![mascot image](./gopher.png)

0 comments on commit bc0ff61

Please sign in to comment.