Git Product home page Git Product logo

python-transducers's Introduction

Build Status Code health

NOTE: This project is going to sleep for the forseeable future. Active development of these ideas will take place over here.

================== python-transducers

Transducers for Python.

Transducers are a concept from clojure, or at least that's where I heard of them first. A transducer is a function that takes a reducer (i.e. the kind of function you would pass to functools.reduce) and returns another reducer. Transducers are a distillation of concepts like mapping and filtering (among other things) that are easily composable.

Note that this module is largely an exercise is "seeing how it works." It's not clear if there are any real practical benefits to using transducers in Python. While they do provide a certain conceptual clarity and have some pleasing properties, they may be slow, limited in applicability, and perhaps even non-Pythonic by some measure.

For more information, see Transducers are coming and the earlier Anatomy of a reducer, both by Rich Hickey.

Quickstart

Here's how you can implement Rich Hickey's example ((def xform (comp (map inc) (filter even?))) using transducers.

from functools import reduce
from transducers.compose import compose
from transducers.transducers import filtering, mapping

# A reducer for appending to a list.
def append(l, item):
    l.append(item)
    return l

# a transducer that maps "x + 1" over input values
inc = mapping(lambda x: x + 1)

# a transducer that filters out odd values
evens = filtering(lambda x: x % 2 == 0)

# a composite transducer of inc and evens -> inc(evens(seq))
odds = compose(inc, evens)

# Apply the composite transducer to the first 10 non-negative integers,
# building a list out of the results.
x = reduce(odds(append), range(10), list())

# See that you've indeed got [1, 3, 5, 7, 9]
assert x == list(range(1, 10, 2))

Testing

transducers testing uses Python's standard unittest and doctest modules. To run the tests, go to the root of the project and run:

python -m unittest discover transducers/test

MMutation testing

If you want to run mutation testing using mut.py, you can use an invocation like this:

mut.py --target transducers --unit-test transducers.test.test_coroutines transducers.test.test_transducers

This can be a bit fiddly, and it's mostly useful for developers. But it's fun to play with if you're interested in that kind of stuff. And of course you need to install mut.py yourself.

Coroutines

You may have noticed that there's a coroutines module in here as well. It turns out that coroutines and transducers are similarly composable, even to the degree that a single compose() function works for both of them. So in the interest of pure curiousity I've added a parallel coroutines modules to match the transducers. As with transducers, I have no idea if this is practical or useful, but it sure is pretty.

python-transducers's People

Contributors

rob-smallshire avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

rob-smallshire

python-transducers's Issues

Can transducers like `taking` actually limit the number of items processed?

As it is, all of the transducers always have to process all of the input elements. So something like taking simply ignores everything after the first n elements, though they still all have to be iterated.

This is wasteful at the very least, problematic if the user actually wants to otherwise handle the ignored values, and catastrophic if the input iterable is infinite.

Generate more efficient composite transducers

It might be neat to investigate using AST tricks or some kind of byte-code generation to create faster composite transducers. As they stand, each "nesting" involves a function call. We might be able to easily pull out the operative parts and string them together in a more efficient/faster form.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.