Skip to content

junkdog/transducers-kotlin

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

46 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status

Transducers for kotlin

From the official clojure documentation:

Transducers are composable algorithmic transformations. They are independent from the context of their input and output sources and specify only the essence of the transformation in terms of an individual element. Because transducers are decoupled from input or output sources, they can be used in many different processes - collections, streams, channels, observables, etc. Transducers compose directly, without awareness of input or creation of intermediate aggregates.

Refer to CHANGELOG.md for latest updates.

Basic usage

transduce(xf = <transducer applied to every input>,
          rf = <what we do to the transduced input>,
          init = <initial state>,
          input = <iterable or finite sequence>)
// '+' composes transducers
val composedTransducer = filter { i: Int -> i % 5 == 0 } +
                         sum { i: Int -> i / 5 }
    
// applying transducer + step function to input
transduce(xf = composedTransducer,
          rf = { result, input -> result + input },
          init = 0,
          input = (0..20)
) assertEquals (1 + 2 + 3 + 4)

Kotlin-like shorthands for transducing straight into a collection: listOf, setOf, and mapOf take transducer and input.

listOf(xf = copy<Int>() +
            branch(test = { it % 4 == 0 },
                   xfTrue  = map { i: Int -> i * 100 },
                   xfFalse = map { i: Int -> i / 4 } +
                             distinct() +
                             map(Int::toString)),
       input = (1..9)
) assertEquals listOf("0", 400, 400, "1", 800, 800, "2")

New/Experimental Transducers

Experimental implies transducers not included with transducers-java.

new regular transducers

  • collect: input into a mutable collection, releases it upon computing the final result.
  • debug: prints debug statements.
  • distinct: no two equal elements shall pass.
  • head: takes the first elements of an iterable input.
  • pairCat: concatenates Pair<A, Iterable<B>> into Pair<A, B>.
  • resultGate: ensures completion is calculated once, used with branching/muxing transducers.
  • sort: collects and sorts all input.
  • tail: takes the last elements of an iterable input.

new higher-order transducers

  • branch: routes input through one out of two transducers, based on predicate.
  • join: turns List<Transducer<A, B>> into Transducer<List<A>, B>.
  • mapPair: creates pairs based on two transducers.
  • mux: input multiplexer, routing input over several transducer paths based on predicates.

new single item transducers

  • count: number of input.
  • sum: calculates sum, can be parameterized by a function for producing a custom value per input.

Refer to the API documentation and tests for details.

Original source code:

The code in this repository is based on https://gist.github.com/hastebrot/aa7b5366309d42270cc1, which in turn was based on the original port from transducers-java: Spasi's Transducers.kt and TransducersTest.kt from Oct 12, 2014.

Resources:

Getting started

Maven

<dependency>
    <groupId>net.onedaybeard.transducers</groupId>
    <artifactId>transducers</artifactId>
    <version>0.4.0</version>
</dependency>

Gradle

dependencies { compile "net.onedaybeard.transducers:transducers:0.4.0" }