In the spirit of toolz, we provide missing features for Python, mainly from the list processing tradition, but with some Haskellisms mixed in. We place a special emphasis on clear, pythonic syntax. These features make up the pure-Python core of unpythonic, and are meant to be used directly. We also provide extensions to the Python language as a set of syntactic macros that are designed to work together. Each macro adds an orthogonal piece of functionality that can (mostly) be mixed and matched with the others.
The macros provide an extension to the pure-Python layer, and offers features such as automatic currying, automatic tail-call optimization, lexically scoped let and do with lean syntax, and implicit return statements. Some of these macro features, like call-by-need (lazy functions), continuations (call/cc), and easy-to-use multi-expression lambdas with local variables, are not available in the pure-Python layer. Additionally, some pure-Python features like batteries for itertools do not have a macro layer equivalent. Check the documentation for the full sets of features.
The design considerations of unpythonic are based in simplicity, robustness, and with minimal dependencies. See our design notes for more information.
Currently none required.
MacroPy optional, to enable the syntactic macro layer.
Pure-Python feature set
Syntactic macro feature set: the second half of unpythonic.
Design notes: for more insight into the design choices of unpythonic
PyPI
pip3 install unpythonic --user
or
sudo pip3 install unpythonic
GitHub
Clone (or pull) from GitHub. Then,
python3 setup.py install --user
or
sudo python3 setup.py install
Uninstall
Uninstallation must be invoked in a folder which has no subfolder called unpythonic, so that pip recognizes it as a package name (instead of a filename). Then,
pip3 uninstall unpythonic
or
sudo pip3 uninstall unpythonic
2-clause BSD.
Dynamic assignment based on StackOverflow answer by Jason Orendorff (2010), used under CC-BY-SA. The threading support is original to our version.
Core idea of lispylet based on StackOverflow answer by divs1210 (2017), used under the MIT license.
Core idea of view based on StackOverflow answer by Mathieu Caroff (2018), used under the MIT license. Our additions include support for sequences with changing length, write support, iteration based on __iter__, in-place reverse, and the abstract base classes.
Thanks to TUT for letting me teach RAK-19006 in spring term 2018; early versions of parts of this library were originally developed as teaching examples for that course. Thanks to @AgenttiX for feedback.
The trampoline implementation of unpythonic.tco takes its remarkably clean and simple approach from recur.tco in fn.py. Our main improvements are a cleaner syntax for the client code, and the addition of the FP looping constructs.
Another important source of inspiration was tco by Thomas Baruchel, for thinking about the possibilities of TCO in Python.
Python clearly wants to be an impure-FP language. A decorator with arguments is a curried closure - how much more FP can you get?
-
Awesome Functional Python, especially a list of useful libraries. Some picks:
-
fn.py: Missing functional features of fp in Python (actively maintained fork). Includes e.g. tail call elimination by trampolining, and a very compact way to recursively define infinite streams.
-
more-itertools: More routines for operating on iterables, beyond itertools.
-
boltons: Like builtins, but boltons. Includes yet more itertools, and much more.
-
pyrsistent: Persistent/Immutable/Functional data structures for Python
-
-
List of languages that compile to Python including Hy, a Lisp (in the Lisp-2 family) that can use Python libraries.
Old, but interesting: