pipe

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 20, 2019 License: MIT Imports: 2 Imported by: 0

README

Go Pipe

GitHub GoDoc

Go Pipe is a simple implementation of pipe operator in Go.

What is it all about?

One of the most intereseting features of functional languages is the ability to easily compose functions. The function composition is the operation that takes two functions and produces another function in the way that the result of the second function is passed as the input argument of first one.

Function composition is so common in functional programming which most of the functional languages have defined a special operator, typically called a pipe operator, to make composition even simpler. For example, in Haskell we have the . (dot) operator, and Elixir defines the |> (pipe) operator:

append = fn list, item ->
  list
  |> Enum.reverse
  |> prepend.(item)
  |> Enum.reverse
end

Actually, in any programming language which supports functional style we can achieve the same result by applying functions consequently. For example in Go, we can write:

func h(x int) int {
    f := func(x int) int {
        if x < 0 {
            return -x
        } else {
            return x
        }
    }

    g := func(x int) int {
        return x * x
    }

    return f(g(x))
}

But the problem arises when one of the func's returns multiple values, as is common with returning errors. In that case we need to handle error specifically and write:

func h(x int) (int, error) {
    f := func(x int) (int, error) {
        if x < 0 {
            return 0, errors.New("x should not be nagtive")
        }
        return x, nil
    }

    g := func(x int) int {
        return x * x
    }

    y, err := f(x)
    if err != nil {
        return 0, err
    }

    return g(y)
}

This is not much complex for two func's, but it can easily become a burden if the number of func's grows.

To overcome this complexity I've written this library to make life simpler for those who love functional style like me. Go Pipe provides a Pipe func which composes one or more funcs into a pipeline func, which can be invoked anytime withing the code. Using Pipe func is very simple:

import . "github.com/aslrousta/pipe"

func h(x int) int {
    var result int

    pipe := Pipe(
        func(x int) int {
            if x < 0 {
                return -x
            } else {
                return x
            }
        },
        func(x int) {
            result = x * x
        },
    )

    pipe(x)
    return result
}

And, it can handle errors automatically:

import . "github.com/aslrousta/pipe"

func h(x int) int {
    var result int

    pipe := Pipe(
        func(x int) (int, error) {
            if x < 0 {
                return 0, errors.New("x should not be nagtive")
            }
            return x, nil
        },
        func(x int) {
            result = x * x
        },
    )

    err := pipe(x)
    return result, err
}

License

Go Pipe source is released to the public under MIT license.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Pipeline

type Pipeline func(...interface{}) error

Pipeline is the func type for the pipeline result.

func Pipe

func Pipe(fs ...interface{}) Pipeline

Pipe accepts zero or more funcs fs and creates a pipeline.

A pipeline syncs outputs and inputs of consequent funcs together, such that the output of i'th func is the input of (i+1)'th func. Each func can accept zero or one input argument and return zero or one value with an optional error.

The last func is called a sink which only accepts an input argument and returns no value except an optional error; unless its return value will be ignored.

If a func in the pipeline fails with an error during the invocation, the pipe is broken immediately and the invocation returns an error.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL