RxGo: Reactive Extensions for the Go Language
github.com
github.com
[1] "Reactive" is a type of system not an implementation, and you implement reactive systems using pretty much any programming/architectural style. http://www.wisdom.weizmann.ac.il/~harel/reactive_systems.htm...
[2] https://twitter.com/headinthebox/status/739915645811228672 , http://www.inf.fu-berlin.de/lehre/SS13/Sem-Prog/material/EST...
This library sums up a lot of the language's problem : channels aren't the final word on concurrency, and go needs at least some way of making reusable code in a type safe manner.
An interface says this thing is unknown but it has at least these known methods
The empty interface means this thing is unknown and its methods are unknown
The first is preferable and the second is not often used.
What go doesn't provide is 1/ unknown but 2/ not. Which happens when you're creating a lib to be used later.
Well someone has made this, and now you can decide if it's worth it for you as an individual to decide whether you like it or not and then if you don't, then don't use it.
I don't use Go, but am a contributor to a Rx project for a different language. As such I am not interested in using this but genuinely curious about the potential (non)benefits of Rx in Go, especially given that they both promise to solve similar problems in very different ways. From experience HN is the prime place for such discussions.
I think HN would be a much worse place if we would only be allowed to cheerlead projects here.
And whatever we do, let's avoid discussing software design choices at all costs. Surely the gains in positivity will make us better programmers.
Go is great for dealing with the nitty-gritty of concurrency, but I find it hard to express a high-level vision of what's going on in my app/lib. This is why this project almost feels good. There's a clear view of what we're manipulating and how we're positioned relative to the data.
Has anybody else struggled with this?
The closest thing I've found to a solution has been go-mangos[0], a native go implementation of the scalable protocols. This is extremely useful for designing the data-flow of an application when I'm shuffling bytes around, but what I find myself wanting is an equivalent system for raw (i.e.: unserialized) Go data-structures.
I want to be able to do something like this (assume a hypothetical library to this effect called `portal`):
p0, _ := portal.NewPortal(iface, portal.REP) // iface is a types.Interface
p0.Bind("foo")
p1, _ := portal.NewPortal(iface, portal.REP)
p1.Dial("foo")
go func() {
for {
i, _ := p0.Recv() // `i` guaranteed to satisfy the interface represented by `iface`
i.DoSomething()
p0.Send(i)
}
}()
p1.Send(iRequest)
iResult, _ := p1.Recv()
I'm very curious to get some feedback on this idea. It's been gnawing away at my brain for a while now.With observables, there's a whole world on top of that. The simplest observable, when subscribed to, will cause the producer of content to start the production. If 3 consumers subscribe to an observable, then the producer will do it's work three times, once per subscription. Compare that to a channel, where a producer has no way of knowing if a consuer is available. Generally, they start the work immediately and try to stuff the result in a channel, regardless of whether there's a consumer on the other end. Moreover, when another consumer uses the same channel, you have two consumers fighting for the same result.
And since observables are transformable, there's a plethora of operators available (at least in rxjava). If you take the previous example, you might want to share the observable, replaying the last result, so that regardless of how many consumers subscribe to it, the producer will only do the work once, and the consumers will receive the same results. It will be quite a bit harder, though not impossible, to implement the same thing with channels.
Promises are all fine and dandy for "do this, wait for that, do that", but they are not powerful enough to express "every time this happens, do that".
I guess you're coming from a JS background as you are using the word "Promises". Imagine instead of registering a callback for mouse click events, you have a stream of mouse events where you can listen to. This is exactly how it works in Angular 2 [1].
[1] http://blog.rangle.io/observables-and-reactive-programming-i...
Now carefull, because it adds a lot of complexity, sometimes for very little gain, and sometimes for even harder to debug code. It also has a high learning curve, because it encourages you to make your code declarative rather than imperative, which isn't always obvious to do.
In practice, there's an abstraction jump with observables. Promise compositions are usually built in response to an imperative action. Observables are built to replace imperative event handlers altogether.