Home

Awesome

pneumatic

Pneumatic is a practical type-safe functional library for Go that uses Go 1.18 generics

var getTopUser = Compose3[[]Post, []Post, Post, UserLevelPoints](
	// Sort users by points
	SortBy(func (prevPost Post, nextPost Post) bool {
		return prevPost.User.Points > nextPost.User.Points
	}),
	// Get top user by points
	Head[Post],
	// Summarize user from post
	func(post Post) UserLevelPoints {
		return UserLevelPoints{
			FirstName:   post.User.Name.First,
			LastName:    post.User.Name.Last,
			Level:       post.Level,
			Points:      post.User.Points,
			FriendCount: len(post.User.Friends),
		}
	},
)

var getTopUsers = Compose3[[]Post, map[string][]Post, [][]Post, []UserLevelPoints](
	// Group posts by level
	GroupBy(func (v Post) string { return v.Level }),
	// Covert map to values only
	Values[[]Post, string],
	// Iterate over each nested group of posts
	Map(getTopUser),
)

posts, _ := getPosts("data.json")
topUsers := getTopUsers(posts)

fmt.Printf("%+v\n", topUsers)
// [{FirstName:Ferguson LastName:Bryant Level:gold Points:9294 FriendCount:3} {FirstName:Ava LastName:Becker Level:silver Points:9797 FriendCount:2} {FirstName:Hahn LastName:Olsen Level:bronze Points:9534 FriendCount:2}]

Example here

Development

Setup

  1. Clone go2go:
git clone git@github.com:golang/go.git $HOME/go2
git checkout dev.go2go
  1. Update go command to point to go2go
export GOROOT="$HOME/go2"
export PATH="$PATH:$GOROOT/bin"

alias go='$HOME/go2/bin/go'
  1. Clone pneumatic
git clone git@github.com:achannarasappa/pneumatic.git
  1. Symlink the working repo into the GOPATH
mkdir -p $GOROOT/src/github.com/achannarasappa
ln -s ./pneumatic $GOROOT/src/github.com/achannarasappa

go2go setup instructions

Usage

Example script that demonstrates some of what is possible with pneumatic:

go tool go2go translate ./**/*.go2 && go tool go2go run examples/functional-pipeline/main.go2

Note: The path to the data file will need to be replaced in order for the example to work. Issues with go path and go2go require this manual step

Tests

Run automated tests:

find . -maxdepth 1 -type d \( ! -name .\* \) -exec bash -c "cd '{}' && go tool go2go test" \;

API Reference

Godoc is one of the unsupported features of go2go so there is no API reference available on pkg.go.dev but you can find each function's documentation below:

Development Status & Roadmap

Experimental (Pre-alpha) - for experimental purposes only until a beta Go 1.18 compiler is released

The vision is to evolve pneumatic to match the latest implementation of Go generics until the final release in Go 1.18. The API is expected to undergo changes until the v1.0.0 release which will coincide with release of Go 1.18.

Known Tooling Issues

Since the go2go toolchain is experimental itself and many features found in the latest stable version of go are not implemented or do not work as expected.

Background

Motivation

There are many utility and functional programming libraries already for Go but there's a few areas where pneumatic seeks to make improvements:

Compiler

pneumatic uses an experimental compiler go2go which implements the features and contract defined in the proposal for go generics. Generics are expected to released as part of go 1.18 in early 2022. go2go may fall behind changes in the proposal but the expectation is that major aspects of the proposal will be retained in the final implementation.