https://github.com/halimath/golang-generics-kata
A programming kata to practice golang generics with functional programming
https://github.com/halimath/golang-generics-kata
Last synced: 3 months ago
JSON representation
A programming kata to practice golang generics with functional programming
- Host: GitHub
- URL: https://github.com/halimath/golang-generics-kata
- Owner: halimath
- Created: 2024-02-26T10:09:39.000Z (over 1 year ago)
- Default Branch: main
- Last Pushed: 2024-02-26T10:10:26.000Z (over 1 year ago)
- Last Synced: 2025-01-22T03:27:31.352Z (4 months ago)
- Language: Go
- Size: 19.5 KB
- Stars: 1
- Watchers: 1
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# golang generics kata
A coding kata to learn generics with golang and practice building a library to
enable functional programming style with common collections.# Exercise
Build a library with example tests that provides datastructures and functions to
represent ordered sequences of elements with common operations in a functional
way.The datastructures should be able to support different sources of input, i.e.
* pre-allocated sources - ordered lists of elements, i.e.
slices or arrays with varying element types
* generator sources - i.e. finite and infinit ranges of integral types
(those that have a "natural" successor)
* streaming sources - i.e. elements that are read from i/o sources (files,
network, databases) or from `chan`nels - either one at a time or in bulksThe lib should provide implementations for common operations on those
datastructures, that somehow transform, filter or discard elements, i.e.* `map` - apply a mapping function converting elements from on datastructure
returning a new datastructure holding the converted elements
* `filter` - return a new datatype that contains only those elements matching
a given _predicate_ function
* `find` - find all elements matching a given _predicate_ function
* `first` - find the first element to match a _predicate_ function
* `take` - only take the first `n` elements from a datastructure returning a
new one
* `skip` - skip the first `n` elements from a datastructureThese operations should be _combineable_ (i.e. via chaining, composition, ...).
The lib should provide implementations that serve as a _sink_ for the datasources,
i.e.* `reduce` - aggregate elements from a datastructure by applying an aggregator
function one element at a time and return the final aggregation result
(i.e. calculate the `sum` or `product` of numbers)
* `collect` - collect elements from the datastructure into a go slice# Challenges
1. Create the library with approprate structure and tests (use
[Go example tests] to showcase your lib)
1. Make sure to implement at least _two_ different _sources_ for datastructure
(i.e. slices, ranges)
1. Make sure to implement at least two transformer operations (i.e. `map` and
`filter`) and at least two consumer operations (i.e. `collect` and `reduce`)
1. Write benchmark tests to compare the time and memory utilization of your
lib in contrast to an _idiomatic_ go implementation of the same algorithm.## Advanced Challenges
You may take the following challenges into account when designing the library
and especially the libray's API.* How to handle operations that might fail (i.e. `map` with the ability to
return an `error` in addition to the regular transformation result)? How
should the overall operation behave if the mapping function fails to transform
a single element?
* How to partition transformation work (i.e. for `map`) onto separate goroutines?
How to ensure the results are recollected "in order"? How to ensure goroutines
do not leak?
* How to improve performance for memory allocating operations (i.e. `collect`ing
elements into a slice)? How can you handle the case that the length of some
datastructures is known in advance while it is unknown for others?## Benchmarkung examples
You can use the following examples as benchmarks:
1. Calculation on generated sequence
1. Produce an infinte range of natural numbers starting at `x`.
1. Multiply each element of that range by `y`.
1. Select only those numbers that are even.
1. Calculate the sum of the first `z` of such numbers.
1. Use values like `x == 19, y == 3, z == 17`.1. Parse, filter and aggregate a logfile of JSON-lines
1. Read a logfile of JSON-lines (each line is a self-contained JSON object).
1. Parse every line as JSON into an appropriate datastructure (i.e. `map` or `struct`).
1. Only consider those messages, that have
* a `app` field that is not empty
* a `severity` field containing either `error` or `warn`
1. Aggregate statistics on number of (filtered) log events per `app`.
* To run benchmarks on this example use the [testdata generator](./cmd/testdata-generator/)
to generate files of configurable sizes (these are not added to this repo)[Go example tests]: https://go.dev/blog/examples