Higher Order Functions using Golang Generics (Hack Days 2022)

hoff: Higher Order Functions (and Friends) Go Reference

Golang 1.18+ implementations of common methods/data structures using Go Generics

Requirements

  • Go 1.18 or newer (must support Generics)

In Development

Please note: this package is still under development and may change in the future. We will attempt to maintain as much backwards compatibility as possible for future changes, but this is still a v0.x release and things might change.

Mash that Star button and OBLITERATE the Watch button to follow our changes.

Running tests/benchmarks

Run the tests and benchmarks for the project using this command:

go test -v -bench=. -race ./...

CI/CD and Github Actions

This project is configured to use GH Actions to automatically test/benchmark the project whenever pushes occur. See the .github/workflows folder for all the details.

Contributing

Contributors must sign the Shopify CLA before your PR can be accepted/merged.

Authors

License

hoff is released under the MIT License.

Comments
  • Refactor Result Values, Errors and add Error method

    Refactor Result Values, Errors and add Error method

    • add Error method that coalesces the Results error messages into one error with the messages joined, comma-separated
    • update Values only return non-error result values, Errors to only include errors from Results with errors
    • add Example tests, update existing to reflect new logic
  • Creates `maps` package

    Creates `maps` package

    This PR suggests creating the maps package extracting these functions from utils/ — it is named maps to avoid conflict with Go's native map keyword.

    On top of that:

    • Adds docs top all public functions
    • Adds examples top the docs of all public functions
    • Adds tests for all public functions (only MapConcurrent was tested)
    • Adds benchmark for all public functions

    Breaking changes

    No function passed as an argument expects the index as the last argument

    | Function | Before | After | |---|---|---| | MapError | func(In, int) (Out, error) | func(In) (Out, error) | | MapContextError | func(context.Context, In, int) (Out, error) | func(context.Context, In) (Out, error) | | MapConcurrent | func(ctx context.Context, T1, int) (T2, error) | func(ctx context.Context, In) (Out, error) |

    The reason is that this way functions don't need to internalize the business logic of the functional map (i.e. functions shouldn't care about the index). It looks like we're not using this indexes in the codebase, and we can wrap the error to provide the index in error messages (that is implemented in this PR).

  • chore: tweak github actions

    chore: tweak github actions

    • Add composite action to setup go and download deps
    • Runs tests and benchmarks
    • Runs example app and ensures build
    • Add matrix support for different golang versions (I'm using 1.18.0 and 1.18.1 because they are the only ones supporting generics rn, but the idea is to be able to test again all major versions 1.18.x, 1.19.x and so on....)
  • Move all utils into the project root, `main` namespace.

    Move all utils into the project root, `main` namespace.

    • Should be accessible as hoff.Filter etc in consumer packages
    • add common.go and define contextKey there so it doesn't get redeclared
    • update some of the docs for flatmap, make errors lowercased in tests
    • use make to create string slices in for_each_test
    • gofmt auto-formatting
  • Use a forked lcov-reporter-action version that fixes an error in the original action

    Use a forked lcov-reporter-action version that fixes an error in the original action

    Original issue reported on Dec 3, 2021, no fix available yet: https://github.com/romeovs/lcov-reporter-action/issues/33

    Fixed in this fork PR: https://github.com/osmind-development-org/lcov-reporter-action/pull/1

    And released: https://github.com/osmind-development-org/lcov-reporter-action/releases/tag/v0.3.2

  • Added Unit Tests for ForEach

    Added Unit Tests for ForEach

    This PR adds a Unit test for the ForEach generic function.

    To tophat:

    • Run go test -v utils/forEach.go utils/forEach_test.go to test only the ForEach.
    • Run go test -v to run the whole test suite.

    What to look for:

    • Hoping for suggestions on how I can refactor the test suite to reduce code duplication. I think there is potential to use generics inside the tests as well.
  • Migrate off probot-CLA to new GitHub Action

    Migrate off probot-CLA to new GitHub Action

    Hello 👋

    We are deprecating probot usage, so all Shopify repos should be migrated to use new GitHub CLA Action.

    You can see how this works in vscode-shopify-ruby repo.

    If you have any questions, please reach us on Slack.

    After you merge this PR, make sure to update branch protection settings (if you have any):

    1. Go to Settings > Branches > Edit main (or any default) branch
    2. Remove the CLA check from probot (click x): image
    3. Add CLA check from GitHub action: image
  • Adds badge and link to the docs

    Adds badge and link to the docs

    Adds Go's standard docs badge linking to the official docs:

    image

    Since we don't have more badges yet, I suggested to leave it in the title line — we can move to a deidcated line once we add more badges ; )

  • Add utils from Shopify/shopify-monitoring-api

    Add utils from Shopify/shopify-monitoring-api

    • Copy over the utils from the observability monitoring api project along with existing tests
    • These could be moved to the top-level if we don't want the utils package namespace?
  • Makes `Chunk`s examples to runnable

    Makes `Chunk`s examples to runnable

    I noticed there was a couple of pure text examples in Chunk's docs:

    image

    They are not well-formatted, making it difficult to follow. So I moved them to runnable examples, which looks better and are ran and tested automagically when we run go test:

    image

  • Ensure that Filter methods return empty slice when nothing matches

    Ensure that Filter methods return empty slice when nothing matches

    • previously if the filter matched nothing, []T(nil) would be returned, rather than an actual empty slice []T{}
    • this is because we weren't initializing the out return value, so if nothing matched the filter, it would just return the default value of nil
    • add Example and "No Matches" tests
  • Create a gh-pages docs website

    Create a gh-pages docs website

    A readme is good, but a cool looking documentation page is like hitting the big leagues.

    Develop a slick, cool looking homepage and publish on GH pages.

    https://docs.github.com/en/pages/getting-started-with-github-pages/configuring-a-publishing-source-for-your-github-pages-site#choosing-a-publishing-source

Extended library functions using generics in Go.

Just few extended standard library functions for Golang using generics.

Dec 16, 2021
Helper functions for common scenarios, using Go generics.

zeroflucs generics When writing Go code for Go 1.17 or below, we've all written more than our fair share of methods to check "does this slice contain

Feb 18, 2022
Functional tools in Go 1.18 using newly introduced generics

functools functools is a simple Go library that brings you your favourite functi

Dec 5, 2022
Optional type using Go 1.18 generics.

go.eth-p.dev/goptional Generic Optional (or Go Optional, if you prefer) goptional is a package that provides an implementation of an Optional[T] monad

Apr 2, 2022
Use is a go utility library using go1.18 generics

use use is a go utility library using go1.18 generics created by halpdesk 2022-01-22 use/slice Map updates a slice by applying a function to all membe

Jan 22, 2022
Optimal implementation of ordered maps for Golang - ie maps that remember the order in which keys were inserted.

Goland Ordered Maps Same as regular maps, but also remembers the order in which keys were inserted, akin to Python's collections.OrderedDicts. It offe

Jan 3, 2023
subtraction operations and also parentheses to indicate order of operations

basic parsing expose a Calculate method that accepts a string of addition / subtraction operations and also parentheses to indicate order of operation

Feb 22, 2022
Code Generation for Functional Programming, Concurrency and Generics in Golang

goderive goderive derives mundane golang functions that you do not want to maintain and keeps them up to date. It does this by parsing your go code fo

Dec 25, 2022
Experimenting with golang generics to implement functional favorites like filter, map, && reduce.

funcy Experimenting with golang generics to implement functional favorites like filter, map, && reduce. 2021-12 To run the tests, you need to install

Dec 29, 2021
A collection of functional operators for golang with generics

fn fn is a collection of go functional operators with generics Getting Started P

Jul 8, 2022
Golang 1.18+ Generics implementation of Set methods

Golang Generics: Set A golang 1.18+ implementation of Set using Go generics Installation $ go get -u github.com/chrispappas/golang-generics-set Quick

Oct 26, 2022
Calling functions by name and getting outputs by using reflect package.

Invoker A library to call (invoke) functions by taking names and sample inputs of those functions as parameters. And returns the types and values of o

Dec 20, 2021
Experiments with Go generics

generics Quick experiments with Go generics algebra, a generic square root function for float, complex and and rational. future, a concurrent cache ("

Dec 31, 2022
Example code for Go generics

go-generics-example Example code for Go generics. Usage $ go build -gcflags=-G=3 Requirements Go 1.17 or later Advertise Go 言語にやってくる Generics は我々に何をも

Dec 30, 2022
Collection of unusual generics usecases in Go

Unusual Generics Type parameters or Generics in Go designed to reduce boilerplate for container data types like lists, graphs, etc. and functions like

Dec 14, 2022
Package truthy provides truthy condition testing with Go generics
Package truthy provides truthy condition testing with Go generics

Truthy Truthy is a package which uses generics (Go 1.18+) to create useful boolean tests and helper functions. Examples // truthy.Value returns the tr

Nov 11, 2022
Go Library for Competitive Programming with Generics

Go Library for Competitive Programming with Generics Go used to be a difficult language to use for competitive programming. However, with the introduc

Dec 21, 2022
A library that provides Go Generics friendly "optional" features.

go-optional A library that provides Go Generics friendly "optional" features. Synopsis some := optional.Some[int](123) fmt.Printf("%v\n", some.IsSome(

Dec 20, 2022
experimental promises in go1.18 with generics

async go a prototype of "promises" in go1.18. note: this is just an experiment used to test alternate patterns for dealing with asynchronous code in g

Dec 23, 2022