This library makes use of the newly released Go Generics in v1.18
to enable the melding of functional programming paradigms, and common Go function call patterns, all over top of Go's excellent channels implementation in a type safe
manner. Additionally, this library manages the lifecycle of channels and goroutines in a clear and easily reasoned manner, alleviating the details of implementation from the library user.
This library currently only imports the standard library and has no 3rd party dependencies. The current goal is to maintain this as long as possible. However, I am not opposed to importing 3rd party libraries for testing purposes or if a good case is made for the main libraries and it is not more appropriate for the implementation to exist in another repository. This is intended to be a straightforward implementation only at this time.
This library is a work in progress and will be released as v0.0.1
once:
- A stable-ish API exists in at least the
pipes
package. - 80-100% test coverage of at least the
pipes
package. - 80-100% test coverage of all known "gotcha" issues with channels.
- General documentation is available if not explicitly completed.
- Documentation of channel "gotcha" issues with channels.
Future home of README.md
library usage documentation... I'm getting to it. For now follow the soon to be completed first pass of the core pipes
package.
This library includes an examples
folder containing functional, if sometimes contrived, example implementations of library functionality.
Contributions are welcome at this time, but inclusion will be selective in scope to the near term core goals of the project until a more stable version is released and we can look at next stages if even appropriate.
Feel free to open an issue to discuss one of the below if one does not already exist. This should provide an opportunity to a documented discussion of the issue more in depth at the time it becomes a requested feature.
-
If our functionality is passed a
nil
chan
we should "gracefully" skip launching a worker for it, thus preventing accidental blocked reads for no actual useful reason. This should allow for channel lifecycle management as expected.- The
Chan[T]
,ChanPull[T]
, andChanPush[T]
should continue to implement the same functionality as expected from standard channel usage in Go on their associated API methods. - This behavior however does not make any effort to warn the library user that the channel was
nil
and that this is likely a bug in their implementation. We should decide whether we should implement this behavior with or without the ability to indicate this issue to the library user.
- The
-
Parameter ordering on methods and functions should be made consistent and friendly to the library user.
- Nothing fancy going on here. We just want to make things nice to work with generally.
-
Does any of our implementation need to be moved into an
internal
package?- Generally speaking I want to make every package a public API and not make use of
internal
. However this may be a better solution to gathering common worker code patterns as these may only be interesting to any library contributors.
- Generally speaking I want to make every package a public API and not make use of
Feel free to open an issue to provide an alternate implementation or just a discussion of the issue more in depth if one does not already exist. This should provide an opportunity to a documented discussion of the issue more in depth at the time it becomes a requested feature.
-
Some functionality on
Chan[T]
andChanPull[T]
cannot be implemented in a type safe manner currently due to the lack of support for parameterized methods. The Functional based implementation should be used instead to ensure type safe implementations.References:
Affected methods at time of writing are below but may not represent a full list:
Map
: currently implemented onChan[T]
andChanPull[T]
works withany
as it's mutated parameter. Use theMap
function instead if type safety is needed.MapWithError
: currently implemented onChan[T]
andChanPull[T]
works withany
as it's mutated parameter. Use theMapWithError
function instead if type safety is needed.MapWithErrorSink
: currently implemented onChan[T]
andChanPull[T]
works withany
as it's mutated parameter. Use theMapWithErrorSink
function instead if type safety is needed.Reduce
: currently implemented onChan[T]
andChanPull[T]
works withany
as it's accumulator parameter. Use theReduce
function instead if type safety is needed.ReduceAndEmit
: currently implemented onChan[T]
andChanPull[T]
works withany
as it's accumulator parameter. Use theReduceAndEmit
function instead if type safety is needed.Window
: currently implemented onChan[T]
andChanPull[T]
works withany
as it's accumulator parameter. Use theWindow
function instead if type safety is needed.Router
: currently NOT implemented on anyChan*[T]
as we cannot easily make use of thecomparable
constraint. Use theRouter
function instead.RouterWithSink
: currently NOT implemented on anyChan*[T]
as we cannot easily make use of thecomparable
constraint. Use theRouterWithSink
function instead.
-
FanIn
will not be able to be used on theChan[T]
andChanPush[T]
types asFanIn
as implemented currently will always close theout
channel. This complicates the reasoning of the channel lifecycle when used from the perspective ofChan[T]
andChanPush[T]
.