Documentation
¶
Overview ¶
proto gives Go operations like Map, Reduce, Filter, De/Multiplex, etc. without sacrificing idiomatic harmony or speed.
The `Proto` type is a stand-in approximation for dynamic typing. Due to Go's powerful casting and type inference idioms, we can approximate the flexibility of dynamic typing even though Go is a statically typed language. Doing so sacrifices some of the benefits of static typing AND some of the benefits of dynamic typing, but this sacrifice is fundamentally required by Go until such time as a true 'Generic' type is implemented.
In order to use a Proto-typed variable (from here on out, simply a 'Proto'), you will generally have to cast it to a type that you will know to use based on the semantics of your program.
This package (specifically, the other files in this package) provide operations on Proto variables as well as some that make Proto variables out of 'traditionally typed' variables. Many of the operations will require the use of higher-order functions which you will need to provide, and those functions commonly will need you to manually "unbox" (cast-from-Proto) the variable to perform useful operations.
Examples of the use of this package can be found in the "*_test.go" files, which contain testing code. A good example of a higher-order function which will commonly need manual-unboxing is the `Filter` function, found in "filter.go". `Filter` takes as its first argument a filter-function which will almost certainly require you to un-box the Proto channel values that it receives to perform the filtering action.
Finally, a word on the entire point of this package: while it is named after the Proto type that pervades it and guides its syntax, the true nature of the `proto` package lies in cascading channels, rather than in dynamic typing. In fact this package might be more appropriately named after channels. Maybe `canal` would have been a better name. I wanted to bring the syntax and familiar patterns of functional programming idioms to the power and scalability of Go's goroutines and channels, and found that the syntax made this task very simple.
You may find, as I did, that the majority of the code in this package is very 'obvious'. At first I was concerned by this - much of the code is very trivial - but now I feel pleased by the re-usability and natural 'correctness' of `proto`. Look at this package not as some monumental time-saving framework, but rather as a light scaffold for a useful and idiomatic style of programming within the existing constructs of Go.
Ultimately, though, you're going to be typing the word Proto an awful lot, and thus the type became the eponym.
Index ¶
- func Demultiplex(fn FilterFn, recv chan Proto) (passed chan Proto, failed chan Proto)
- func Filter(fn FilterFn, recv chan Proto) (send chan Proto)
- func Map(fn MapFn, recv chan Proto) (send chan Proto)
- func Multiplex(inputs ...chan Proto) (send chan Proto)
- func PFilter(fn FilterFn, recv chan Proto) (send chan Proto)
- func PMap(fn MapFn, recv chan Proto) (send chan Proto)
- func PTrigger(fn TriggerFn, count int) (send chan Proto)
- func Reduce(fn ReduceFn, recv chan Proto) (send chan Proto)
- func Send(vals []Proto) (send chan Proto)
- func Splice(a chan Proto, b chan Proto)
- func Trigger(fn TriggerFn, count int) (send chan Proto)
- type FilterFn
- type MapFn
- type Proto
- type ReduceFn
- type TriggerFn
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
func Demultiplex ¶
Separate an input channel in to two output channels by applying a filter function (see `Filter`). The first output channel will get the values that passed the filter, the second will get those that did not.
func Filter ¶
Filter the channel with the given function. `fn` must return true or false for each individual element the channel may receive. If true, the element will be sent on the return channel. As usual, this function does not block beyond the time taken to set up the returned channel.
func Map ¶
Apply `fn` to each value on `recv`, and send the results on the return channel. Order is preserved. Though `Map` does not block, it is not parallel - for a parallel version, see `PMap`.
func PFilter ¶
Exactly like `Filter`, but every filter application gets its own goroutine. Order is NOT preserved. As a rule of thumb, `PFilter` is only preferable over `Filter` if `fn` is very expensive or if the consumer of the result channel is very slow and buffering would be preferred (thus keeping up consumption rates of `recv`).
func PTrigger ¶
Exactly like `Trigger`, but each trigger happens in parallel. Order is NOT preserved.
func Reduce ¶
Reduce the `recv` channel by repeatedly applying `fn` on pairs of values until only one value remains. The first invocation of `fn` will receive the first two values from `recv`, all subsequent invocations will receive progressive elements from `recv` *in order* - that is, `fn` may or may not be associative. If `recv` receives only one value, `fn` will not be called and the first and only value will be sent as the result. If `recv` receives no values, `nil` will be sent (as a Proto type) as the result. Regardless, `recv` will always receive one value and then be closed.
func Send ¶
Given a slice of Proto's, send them on a newly created channel and then close that channel. If the slice is empty, this does the correct thing - it creates the channel, and then closes it promptly. As expected, this function does not block beyond the setup time.
func Splice ¶
Sends all items from channel `a` to channel `b`, and then closes `b`. Does not close `a`. Does not block. This function is useful, eg, when trying to create a loop of procedures that return channels - take the output channel of the last element in the chain, create a channel for the input to the first element in the chain, and link them using Splice.
Types ¶
type FilterFn ¶
Filter function type definition. A FilterFn is given a single Proto and must decide whether to return `true` or `false`, meaning "filter" or "don't filter" respectively. The implementer will probably need to unbox the Proto argument to a more useful type manually.
type Proto ¶
type Proto interface{}
The Proto type. (Get it?)