is it possible to create function pipelines in go language, where output of one function is directly conventionality into input of another function.
Please discuss it in the comments if it's not clear and you need more info.
Other functional languages provide some constructs, for instance it's then
in javascript with promises
, in java they use andThen
with lambdas
, and with c#
it's FunctionExtensions
. Shell programs like unix also provides buitin method called pipes |
func processA(test TestObj) {
// do something
return test
}
func process B(test TestObj) {
//do something
return test
}
func processC(test TestObj) {
//do something
return test
}
so can we do something similar like
var obj = TestObj{}
processA(obj)
.then(processB)
.then(processC)
jim, the second example uses the channels? can you please provide a code example using my code.
I am also not exactly sure what you want to do, however here is an example of a linked list implementation in Go.
package main
import "fmt"
type LinkedList struct {
value interface{}
next *LinkedList
}
func (oldNode *LinkedList) prepend(value interface{}) *LinkedList {
return &LinkedList{value, oldNode}
}
func tail(value interface{}) *LinkedList {
return &LinkedList{value, nil}
}
func traverse(ll *LinkedList) {
if ll == nil {
return
}
fmt.Println(ll.value)
traverse(ll.next)
}
func main() {
node := tail(5).prepend(6).prepend(7)
traverse(node)
}
So, as you can see, it is possible to chain
methods using what is known as the fluent
or builder
interface. IMO above example is an appropriate place to do so. https://www.martinfowler.com/bliki/FluentInterface.html
Now if you want to do an async / non blocking request, then I would use channels / goroutines. It's not really a promise, but you can certainly handle on success/error if you wanted.
func NonBlockingGet(url string) <-chan []byte {
c := make(chan []byte, 1)
go func() {
var body []byte
defer func() {
c <- body
}()
res, err := http.Get(url)
if err != nil {
return
}
defer res.Body.Close()
body, _ = ioutil.ReadAll(res.Body)
}()
return c
}
func main() {
promise := NonBlockingGet("http://example.com")
// can do other stuff here - because doing a non-blocking get request.
log.Println("This will output before the response length")
body := <- promise // Will wait here till promise is resolved.
log.Printf("response length: %d", len(body))
}
I hope that this helps. As said in comments above, this is not javascript and we shouldnt try to be. However, instead of assigning <- promise
to body
, you could always pass <- promise
as an argument into a function.
I was seeking for this kind of pattern as well without any luck. It's very common to other language but not in golang
Anyway, you may find this usefull https://github.com/open-zhy/fn-pipe
It basically uses reflection in order to map all your inputs and outputs through your functions