Functional Experiment in Golang

ƒuego logo

ƒuego - Functional Experiment in Go

Tweet

fuego goreportcard

Buy Me A Coffee

ƒuego example

ƒuego example

Table of content

Overview

Making Go come to functional programming.

This is a research project in functional programming which I hope will prove useful!

ƒuego brings a few functional paradigms to Go. The intent is to save development time while promoting code readability and reduce the risk of complex bugs.

I hope you will find it useful!

Have fun!!

(toc)

Documentation

The code documentation and some examples can be found on godoc.

The tests form the best source of documentation. ƒuego comes with a good collection of unit tests and testable Go examples. Don't be shy, open them up and read them and tinker with them!

Note:
Most tests use unbuffered channels to help detect deadlocks. In real life scenarios, it is recommended to use buffered channels for increased performance.

(toc)

Installation

Download

go get github.com/seborama/fuego

Or for a specific version:

go get gopkg.in/seborama/fuego.v8

Import in your code

You can import the package in the usual Go fashion.

To simplify usage, you can use an alias:

package sample

import ƒ "gopkg.in/seborama/fuego.v8"

...or import as an unqualified dot import:

package sample

import . "gopkg.in/seborama/fuego.v8"

(toc)

Example Stream

    strs := EntrySlice{
        EntryString("a"),
        EntryString("bb"),
        EntryString("cc"),
        EntryString("ddd"),
    }
    
    NewStreamFromSlice(strs, 500).
        Filter(isEntryString).
        Distinct().
        Collect(
            GroupingBy(
                stringLength,
                Mapping(
                    stringToUpper,
                    Filtering(
                        stringLengthGreaterThan(1),
                        ToEntrySlice()))))
    }

    // result: map[1:[] 2:[BB CC] 3:[DDD]]

(toc)

Contributions

Contributions and feedback are welcome.

For contributions, you must develop in TDD fashion and ideally provide Go testable examples (if meaningful).

If you have an idea to improve ƒuego, please share it via an issue. And if you like ƒuego give it a star to show your support for the project - it will put a smile on my face! 😊

Thanks!!

(toc)

The Golden rules of the game

  1. Producers close their channel. In other words, when you create a channel, you are responsible for closing it. Similarly, whenever ƒuego creates a channel, it is responsible for closing it.

  2. Consumers do not close channels.

  3. Producers and consumers should be running in separate Go routines to prevent deadlocks when the channels' buffers fill up.

(toc)

Pressure

Go channels support buffering that affects the behaviour when combining channels in a pipeline.

When the buffer of a Stream's channel of a consumer is full, the producer will not be able to send more data through to it. This protects downstream operations from overloading.

Presently, a Go channel cannot dynamically change its buffer size. This prevents from adapting the stream flexibly. Constructs that use 'select' on channels on the producer side can offer opportunities for mitigation.

(toc)

Concept: Entry

Entry is inspired by hamt.Entry. This is an elegant solution from Yota Toyama: the type can be anything so long as it respects the simple behaviour of theEntry interface. This provides an abstraction of types yet with known behaviour:

  • Hash(): identifies an Entry Uniquely.
  • Equal(): defines equality for a concrete type of Entry. Equal() is expected to be based on Hash() for non-basic types. Equal should ensure the compared Entry is of the same type as the reference Entry. For instance, EntryBool(false) and EntryInt(0) both have a Hash of 0, yet they aren't equal.

Several Entry implementations are provided:

  • EntryBool
  • EntryInt
  • EntryFloat
  • EntryString
  • EntryMap
  • EntrySlice
  • Tuples

Check the godoc for additional methods each of these may provide.

(toc)

Features summary

Streams:

  • Stream
  • IntStream
  • FloatStream
  • CStream - concurrent implementation of Stream

Functional Types:

  • Maybe
  • Tuple
  • Predicate:
    • True
    • False
    • FunctionPredicate

Functions:

  • Consumer
  • Function:
    • ToIntFunction
    • ToFloatFunction
  • BiFunction
  • StreamFunction:
    • FlattenEntrySliceToEntry
  • Predicate:
    • Or
    • Xor
    • And
    • Not / Negate

Collectors:

  • GroupingBy
  • Mapping
  • FlatMapping
  • Filtering
  • Reducing
  • ToEntrySlice
  • ToEntryMap
  • ToEntryMapWithKeyMerge

Check the godoc for full details.

(toc)

Concurrency

As of v8.0.0, a new concurrent model offers to process a stream concurrently while preserving order.

This is not possible yet with all Stream methods but is available with e.g. Stream.Map.

Notes on concurrency

Concurrent streams are challenging to implement owing to ordering issues in parallel processing. At the moment, the view is that the most sensible approach is to delegate control to users. Multiple ƒuego streams can be created and data distributed across as desired. This empowers users of ƒuego to implement the desired behaviour of their pipelines.

Stream has some methods that fan out (e.g. ForEachC). See the godoc for further information and limitations.

I recommend Rob Pike's slides on Go concurrency patterns:

As a proof of concept and for facilitation, ƒuego has a CStream implementation to manage concurrently a collection of Streams.

(toc)

Collectors

A Collector is a mutable reduction operation, optionally transforming the accumulated result.

Collectors can be combined to express complex operations in a concise manner.
Simply put, a collector allows creating custom actions on a Stream.

ƒuego exposes a number of functional methods such as MapToInt, Head, LastN, Filter, etc...
Collectors also provide a few functional methods.

But... what if you need something else? And it is not straighforward or readable when combining the existing methods ƒuego offers?

Enters Collector: implement you own requirement functionally!
Focus on what needs doing in your streams (and delegate the details of the how to the implementation of your Collector).

(toc)

Known limitations

  • several operations may be memory intensive or poorly performing.

(toc)

Buy Me A Coffee

Comments
  • V11 type parameters

    V11 type parameters

    Please, ensure your pull request meet these guidelines:

    • [ ] My code is written in TDD (test driven development) fashion.
    • [ ] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [ ] I have provided / updated examples.
    • [ ] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • v11: transition to go 1.18 type parameters (WIP)

    v11: transition to go 1.18 type parameters (WIP)

    Please, ensure your pull request meet these guidelines:

    • [ ] My code is written in TDD (test driven development) fashion.
    • [ ] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [ ] I have provided / updated examples.
    • [ ] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • add Stream.Drop*

    add Stream.Drop*

    Please, ensure your pull request meet these guidelines:

    • [x] My code is written in TDD (test driven development) fashion.
    • [x] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [x] I have provided / updated examples.
    • [x] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • Fixed optional on nil value

    Fixed optional on nil value

    Please, ensure your pull request meet these guidelines:

    • [x] My code is written in TDD (test driven development) fashion.
    • [x] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [x] I have provided / updated examples.
    • [x] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • add README on Golang, Receivers and Functions

    add README on Golang, Receivers and Functions

    Please, ensure your pull request meet these guidelines:

    • [x] My code is written in TDD (test driven development) fashion.
    • [x] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [x] I have provided / updated examples.
    • [x] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • v11 type parameters & Go 1.18 mitigations

    v11 type parameters & Go 1.18 mitigations

    Please, ensure your pull request meet these guidelines:

    • [x] My code is written in TDD (test driven development) fashion.
    • [x] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [ ] I have provided / updated examples.
    • [x] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • updated readme

    updated readme

    Please, ensure your pull request meet these guidelines:

    • [ ] My code is written in TDD (test driven development) fashion.
    • [ ] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [ ] I have provided / updated examples.
    • [ ] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • Updated go mod deps

    Updated go mod deps

    Please, ensure your pull request meet these guidelines:

    • [x] My code is written in TDD (test driven development) fashion.
    • [x] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [x] I have provided / updated examples.
    • [x] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • Removed EntryMap.Append*, added EntryMap.Merge + ToEntryMapWithKeyMerge

    Removed EntryMap.Append*, added EntryMap.Merge + ToEntryMapWithKeyMerge

    Please, ensure your pull request meet these guidelines:

    • [x] My code is written in TDD (test driven development) fashion.
    • [x] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [x] I have provided / updated examples.
    • [x] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • Add collectors.ToEntryMap

    Add collectors.ToEntryMap

    Please, ensure your pull request meet these guidelines:

    • [x] My code is written in TDD (test driven development) fashion.
    • [x] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [x] I have provided / updated examples.
    • [x] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

  • FlatMap ordered concurrency

    FlatMap ordered concurrency

    Please, ensure your pull request meet these guidelines:

    • [x] My code is written in TDD (test driven development) fashion.
    • [x] My code adheres to Go standards I have run make lint, or I have used https://goreportcard.com/ and I have taken the necessary compliance actions.
    • [x] I have provided / updated examples.
    • [x] I have updated [README.md].

    Thanks for your PR, you're awesome! :+1:

Common functional data manipulation and abstraction patterns in Golang.

Functional Patterns in Golang GOMAD (Early stage) This package is still in an early stage of development. Feel free to open a PR and contribute or jus

Jan 8, 2023
Desenvolvendo-Sistema-Planejamento-Financeiro-GoLang - Developing a Financial Planning System with Golang

dio-expert-session-finance Pré Desenvolvimento Vamos criar um projeto no Github

Jan 27, 2022
Client-server-golang-sqs - Client Server with SQS and golang

Client Server with SQS and golang Multi-threaded client-server demo with Go What

Feb 14, 2022
Golang-action - A template repository for writing custom GitHub Actions in Golang

Golang Action A template repository for writing custom GitHub Actions in Golang.

Feb 12, 2022
Simple golang airtable API wrapper

Golang Airtable API A simple #golang package to access the Airtable API. Table of contents Golang Airtable API Table of contents Installation Basic us

Jan 5, 2023
(Golang) Go bindings for Discord

DiscordGo DiscordGo is a Go package that provides low level bindings to the Discord chat client API. DiscordGo has nearly complete support for all of

Jan 7, 2023
Golang client for ethereum json rpc api

Ethrpc Golang client for ethereum JSON RPC API. web3_clientVersion web3_sha3 net_version net_peerCount net_listening eth_protocolVersion eth_syncing e

Jan 7, 2023
A golang client for the Twitch v3 API - public APIs only (for now)

go-twitch Test CLIENT_ID="<my client ID>" go test -v -cover Usage Example File: package main import ( "log" "os" "github.com/knspriggs/go-twi

Sep 27, 2022
This is a Golang wrapper for working with TMDb API. It aims to support version 3.
This is a Golang wrapper for working with TMDb API. It aims to support version 3.

This is a Golang wrapper for working with TMDb API. It aims to support version 3. An API Key is required. To register for one, head over to themoviedb

Dec 27, 2022
a Go (Golang) MusicBrainz WS2 client library - work in progress
a Go (Golang) MusicBrainz WS2 client library - work in progress

gomusicbrainz a Go (Golang) MusicBrainz WS2 client library - a work in progress. Current state Currently GoMusicBrainz provides methods to perform sea

Sep 28, 2022
⚡️ SharePoint authentication, HTTP client & fluent API wrapper for Go (Golang)
⚡️ SharePoint authentication, HTTP client & fluent API wrapper for Go (Golang)

Gosip - SharePoint authentication, HTTP client & fluent API wrapper for Go (Golang) Main features Unattended authentication using different strategies

Jan 2, 2023
A golang package to communicate with HipChat over XMPP

hipchat This is a abstraction in golang to Hipchat's implementation of XMPP. It communicates over TLS and requires zero knowledge of XML or the XMPP p

Jan 3, 2023
Golang client for LastPass

Go client for LastPass Features login via user name and master password two-factor authentication with out-of-band mechanism such as push notification

Dec 23, 2022
A Golang SDK for Medium's OAuth2 API

Medium SDK for Go This repository contains the open source SDK for integrating Medium's OAuth2 API into your Go app. Install go get github.com/Medium/

Nov 28, 2022
Golang Mixpanel Client

mixpanel Mixpanel Go Client Donate to 1P8ccYhVt4ByLahuVXiCY6U185gmYA8Rqf Usage import "github.com/dukex/mixpanel" -- documentation on godoc Examples T

Dec 16, 2022
Golang client for PayPal REST API

Go client for PayPal REST API Coverage POST /v1/oauth2/token POST /v1/identity/openidconnect/tokenservice GET /v1/identity/openidconnect/userinfo/?sch

Dec 25, 2022
Simple no frills AWS S3 Golang Library using REST with V4 Signing (without AWS Go SDK)

simples3 : Simple no frills AWS S3 Library using REST with V4 Signing Overview SimpleS3 is a golang library for uploading and deleting objects on S3 b

Nov 4, 2022
golang library for textbelt.com

textbelt.com API for GO This library sends text messages to mobile phones using http://textbelt.com Installing go get $ go get gopkg.in/dietsche/textb

Nov 15, 2022
Scrape the Twitter Frontend API without authentication with Golang.

Twitter Scraper Twitter's API is annoying to work with, and has lots of limitations — luckily their frontend (JavaScript) has it's own API, which I re

Dec 29, 2022