Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/pakoito/komprehensions

Do comprehensions for Kotlin and 3rd party libraries [STABLE]
https://github.com/pakoito/komprehensions

functional-programming kotlin rxjava

Last synced: about 6 hours ago
JSON representation

Do comprehensions for Kotlin and 3rd party libraries [STABLE]

Awesome Lists containing this project

README

        

# Komprehensions

Komprehensions is a library to reduce boilerplate and simplify your call chains.

## Rationale

As your code starts getting more and more functional, you find that you want to chain multiple statements by helpers like `let`. This causes indentation levels to go quite high, and would often require that you split the code in several methods just to keep it readable.

```java
fun calculateDoubles(calcParams: Params) =
calcParams
.let { params ->
defrombulate(params.first, param.second)
.let { result ->
gaussianRoots(result)
.let { grtts ->
storeResult(params.first, params.second, result, grtts)
}
}
}
```

**Comprehensions** are a language feature that allow you to define such a chain in a way where every observable is a function at topmost indentation, yet still contains all the parameters received in the previous functions.

## Usage

### Let

Komprehensions contains functions `doLet()` for `let()`. Each takes from 2 to 9 function each with an increasing number of parameters, and returns an object of the type of the return of the last function.

```java
fun calculateDoubles(calcParams: Params) =
// chained with let()
doLet(
{ calcParams },
{ params -> defrombulate(params.first, param.second) },
{ params, result -> gaussianRoots(result) },
{ params, result, grtts -> storeResult(params.first, params.second, result, grtts) }
)
```

### Chainable

Komprehensions contains functions `doChainable()` for interface `Chainable`. Each takes from 2 to 9 function each with an increasing number of parameters, and returns a Chainable.

It's functionally similar to [let](https://github.com/pakoito/Komprehensions#let) but it's limited to types that are marked as Chainable. The recommended usage is to annotate sealed classes with it to indicate that they can be transformed between them.
An example is available in [this link](https://gist.github.com/pakoito/8043a42c2381112753cfdaab128cdc49) with a longer description given by ["A Domain Driven approach to Kotlin's new types"](http://www.pacoworks.com/2016/10/03/new-talk-a-domain-driven-approach-to-kotlins-new-types-at-mobilization-2016/).

A special thanks to [@Takhion](https://github.com/Takhion) for simplifying my initial implementation.

### map

Komprehensions contains functions `doMapIterable()` for `map()` chaining of `Iterable`. Each takes from 1 to 9 function each with an increasing number of parameters, and returns an `Iterable` of the type of the return of the last function.

### flatMap

Komprehensions contains functions `doFlatMapIterable()` for `flatMap()` chaining of `Iterable`. Each takes from 1 to 9 function each with an increasing number of parameters and returns an `Iterable`, then flattens the return into an `Iterable` of the type of the return of the last function.

## Komprehensions-rx

Komprehensions-rx is an extension module that allows chaining of [RxJava](https://github.com/ReactiveX/RxJava) `Observables`. It is available for both RxJava 1 and 2.

### Map comprehensions

Komprehensions-rx contains functions `doFlatMap()` for `flatMap()`, `doConcatMap()` for `concatMap()`, `doSwitchMap()` for `switchMap()`. Each takes from 1 to 9 function each with an increasing number of parameters, and returns an `Observable` of the type of the return of the last function.

```java
Observable getUserFriends =
// chained with flatMap()
KomprehensionsRx.doFlatMap(
{ profileClicks() },
{ position -> getUserFromProfile(position) },
{ position, user -> requestFriendListForUser(position, user.id) },
{ position, user, friends -> storeUserAndFriends(user, friends) },
{ position, user, friends, result -> toUserDisplayString(position, user, friends, result) }
);
```

### Compose comprehensions

Komprehensions-rx contains functions `doCompose()` for `compose()`. Each takes from 1 to 9 `Transformer` (RxJava 1.X) or `ObservableTransformer` (RxJava 2.X), and returns an `Observable` of the type of the return of the last one.

```java
Observable> getRelatives =
// chained with compose()
KomprehensionsRx.doCompose(
{ requestRelative("12345") },
validate(),
assureThreads(Schedulers.io(), AndroidSchedulers.main()),
respectLifecycle(activity),
toUILayerModel(),
groupSiblings()
);

Observable requestRelative(String id) { /* ... */ }

ObservableTransformer validate() { /* ... */ }

ObservableTransformer assureThreads(Scheduler in, Scheduler out) { /* ... */ }

ObservableTransformer respectLifecycle(Activity activity) { /* ... */ }

ObservableTransformer toUILayerModel() { /* ... */ }

ObservableTransformer> groupSiblings() { /* ... */ }
```

## Komprehensions-reactor

Komprehensions-reactor is an extension module that allows chaining of [Project Reactor](https://projectreactor.io/) `Flux` and `Mono` operators.

### Map comprehensions

Komprehensions-reactor contains functions `doFlatMap()` for `flatMap()`, `doConcatMap()` for `concatMap()`, `doSwitchMap()` for `switchMap()`. Each takes from 1 to 9 function each with an increasing number of parameters, and returns an `Flux` of the type of the return of the last function. It also contains functions `doFlatMapMono()` for `flatMap()` on the `Mono` operator. Each takes from 1 to 8 function each with an increasing number of parameters, and returns a `Mono` of the type of the return of the last function.

```java
Flux getUserFriends =
// chained with flatMap()
KomprehensionsReactor.doFlatMap(
{ profileClicks() },
{ position -> getUserFromProfile(position) },
{ position, user -> requestFriendListForUser(position, user.id) },
{ position, user, friends -> storeUserAndFriends(user, friends) },
{ position, user, friends, result -> toUserDisplayString(position, user, friends, result) }
);
```

## Distribution

Add as a dependency to your `build.gradle`
```groovy
repositories {
...
maven { url "https://jitpack.io" }
...
}

dependencies {
...
compile 'com.github.pakoito.Komprehensions:komprehensions:1.3.2'

// Extensions for RxJava 1.X
compile 'com.github.pakoito.Komprehensions:komprehensions-rx:1.3.2'

// Extensions for RxJava 2.X
compile 'com.github.pakoito.Komprehensions:komprehensions-rx2:1.3.2'

// Extensions for Reactor
compile 'com.github.pakoito.Komprehensions:komprehensions-reactor:1.3.2'
...
}
```
or to your `pom.xml`

```xml


jitpack.io
https://jitpack.io

com.github.pakoito.Komprehensions
komprehensions
1.3.2

com.github.pakoito.Komprehensions
komprehensions-rx
1.3.2

com.github.pakoito.Komprehensions
komprehensions-rx2
1.3.2

com.github.pakoito.Komprehensions
komprehensions-reactor
1.3.2

```

## Contributions

PRs and suggestions for new features welcome.

If you have any core function that is chainable, please PR against the main module. If the function is contained in any 3rd party dependency, create a separate module and PR it instead.

For any error report please send an issue with a full stack trace and reproduction steps.

## License

Copyright (c) pakoito 2016

The Apache Software License, Version 2.0

See LICENSE.md