• Stars
    star
    114
  • Rank 308,031 (Top 7 %)
  • Language
    Kotlin
  • License
    Other
  • Created about 8 years ago
  • Updated over 5 years ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

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

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.

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.

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 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 with a longer description given by "A Domain Driven approach to Kotlin's new types".

A special thanks to @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 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.

Observable<String> 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<T, U> (RxJava 1.X) or ObservableTransformer<T, U> (RxJava 2.X), and returns an Observable of the type of the return of the last one.

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

Observable<RelativeDto> requestRelative(String id) { /* ... */ }

ObservableTransformer<RelativeDto, RelativeDto> validate() { /* ... */ }

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

ObservableTransformer<RelativeDto, RelativeDto> respectLifecycle(Activity activity) { /* ... */ }

ObservableTransformer<RelativeDto, Relative> toUILayerModel() { /* ... */ }

ObservableTransformer<Relative, List<Siblings>> groupSiblings() { /* ... */ }

Komprehensions-reactor

Komprehensions-reactor is an extension module that allows chaining of Project Reactor 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.

Flux<String> 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

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

<repositories>
    <repository>
        <id>jitpack.io</id>
        <url>https://jitpack.io</url>
    </repository>
</repositories>

<dependency>
    <groupId>com.github.pakoito.Komprehensions</groupId>
    <artifactId>komprehensions</artifactId>
    <version>1.3.2</version>
</dependency>

<dependency>
    <groupId>com.github.pakoito.Komprehensions</groupId>
    <artifactId>komprehensions-rx</artifactId>
    <version>1.3.2</version>
</dependency>

<dependency>
    <groupId>com.github.pakoito.Komprehensions</groupId>
    <artifactId>komprehensions-rx2</artifactId>
    <version>1.3.2</version>
</dependency>

<dependency>
    <groupId>com.github.pakoito.Komprehensions</groupId>
    <artifactId>komprehensions-reactor</artifactId>
    <version>1.3.2</version>
</dependency>

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

More Repositories

1

FunctionalAndroidReference

Showcase project of Functional Reactive Programming on Android, using RxJava.
Kotlin
276
star
2

MarI-O

Github clone of MarI/O by SethBling
224
star
3

RxSealedUnions

Compile-time checked Unions of different types for Domain Modeling [STABLE]
Java
127
star
4

RxTuples

Simple tuples to use with RxJava [STABLE]
Java
112
star
5

RxPaper2

NoSQL storage with RxJava2 bindings [STABLE]
Java
100
star
6

RxPaper

NoSQL storage with RxJava bindings [STABLE]
Java
88
star
7

RxComprehensions

Reduce boilerplate in RxJava by abstracting chained operators like flatMap, concatMap, switchMap, or compose [STABLE]
Java
86
star
8

RxObservableDiskCache

Simple NoSQL disk cache for network responses [STABLE]
Java
86
star
9

FunctionalRx2

FunctionalRx2 is a collection of constructs to simplify a functional programming approach to Java and Android [STABLE]
83
star
10

JavaSealedUnions

Tagged Unions for the Java 8 connoisseur
Java
54
star
11

SongkickInterview

App handed in as part of Songkick's interview process
Java
51
star
12

RxFunctions

Advanced Function composition to use with RxJava [STABLE]
Java
49
star
13

FunctionalRx

FunctionalRx is a collection of constructs to simplify a functional programming approach to Java and [STABLE]
48
star
14

RxCurrying

Simple currying for FuncN and ActionN on RxJava [STABLE]
Java
38
star
15

RxSealedUnions2

Compile-time checked Unions of different types for Domain Modeling [STABLE]
Java
35
star
16

RxActions

Simple ActionN composition to use with RxJava [STABLE]
Java
33
star
17

RxPartialApplication

Simple partial application for FuncN and ActionN on RxJava [STABLE]
Java
30
star
18

RustyAndroid

Interoping Android's Java with Rust via JNA
C
28
star
19

RxTuples2

Simple tuples to use with RxJava2 [STABLE]
Java
22
star
20

RxMemoization

Simple Function result caching for RxJava [STABLE]
Java
20
star
21

RxObservableDiskCache2

Simple NoSQL disk cache for network responses [STABLE]
Java
14
star
22

javafxmobile-plugin-ensemble

Git clone of JavaFX on iOS and Android
Java
8
star
23

ToME---t-engine4

Github fork of ToME/TE4
Lua
8
star
24

CardGameFramework

Prototype framework to create card games on the fly
Java
6
star
25

RxCurrying2

Simple currying for FunctionN and ConsumerN on RxJava2 [STABLE]
Java
5
star
26

RxErrorAlgebra

Java
4
star
27

ggwp

A port of GGPO (https://github.com/pond3r/ggpo) to Rust
Rust
4
star
28

printableheroes

JavaScript
3
star
29

DT3

DT3 Game Engine by Smells Like Donkey Software Inc.
C
3
star
30

DOT

The open source version of the DOT AI Engine.
C++
3
star
31

react-jus

A React Component for polyominos on a grid
2
star
32

RxFunctions2

Advanced Function composition to use with RxJava2 [STABLE]
Java
2
star
33

RxMemoization2

Simple Function result caching for RxJava [Stable]
Java
2
star
34

RxPartialApplication2

Simple partial application for FuncN and ActionN on RxJava 2.X [STABLE]
Java
2
star
35

RxConsumers

Simple Consumer composition to use with RxJava [STABLE]
Java
2
star
36

RxJava2Consumers

Copy of the missing Consumer interfaces in RxJava2 available in RxJava2Extensions [Stable]
Java
2
star
37

pnpcut

Q&D script to process cards in bulk to 3x3 A4
JavaScript
2
star
38

ludumdare31

Project for LD31
Java
1
star
39

Gameroom

Test room for github development
1
star
40

buildmancer

A build theorycrafting boadgame you can play offline!
TypeScript
1
star
41

byuu

byuu is a multi-system emulator focused on performance, features, and ease of use.
1
star
42

HexUtils

Some utilities for working with hexagons, mostly based on http://www.redblobgames.com/grids/hexagons/
Java
1
star
43

2DEngine

2d engine for iphone games
1
star