Skip to main content

better-functools

Better functools improves functional programming ergonomics in Python

Installation

$ pip install better-functools

Background

The library introduces 2 different operators for use with functions:

  • | which we'll call "pipe"
  • @ which we'll call "apply"

The following is an example:

Pipeline(inputs)
| func(itertools.combinations @ func.arg(Iterable[int]) @ bind(2))
| filter @ bind(sum @ compose(eq @ bind(2020)))
| map @ bind(prod)
| sum
| Pipeline.unwrap

This may look strange but we can break this down.

pipe

Pipeline wraps inputs and enables unix like pipes. So Pipeline(v) | fn is equal to Pipeline(fn(v)).

| Pipeline.unwrap is finally used to unwrap the Pipeline and extract the value.

apply

better_functools.apply includes a number of functions that implements @.

For example, map @ bind(prod) means bind prod to the first arg of map. More apply functions can be called directly too, the above expression is equivalent to bind(prod)(map).

The usual pattern is: some_value @ some_operator(args)

The @ operator takes some getting used to, but the main benefit is how chainable operators are.

add @ bind(1) @ bind(2)

reads left to right fairly well, but if we were to call directly:

bind(2)(bind(1)(add))

It's just a lot harder to read and we need more brackets.

Putting @ and | together

You can see that @ and | both facilitate some sort of "function chaining". So why add 2 different operators?

@ is higher precedence than | so it can be used in each stage of a pipe without brackets. Generally the idea is to use @ operators to build the function for each stage of a |.

Without @ functions are a lot harder to build inline and often must be defined explicitly elsewhere.

General Tips

Type Checking

  • The typing here is built for Pyright.
  • Mypy compatibility is okay, specific issues with mypy are highlighted in function docs.
  • Other type checkers simply lack the popularity for me to support actively.

functools.partial

Feel free to use functools.partial to create partial functions in place of bind and func. Both MyPy and Pyright has a custom type checking handler for partial. This is the best way to bind keyword arguments right now.

partial(itertools.combinations, r=2)

Metadata

Release files for better-functools 0.2.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for better-functools 0.2.0
File Size Uploaded
better_functools-0.2.0.tar.gz 36.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for better-functools 0.2.0
File Interpreter ABI Platform
better_functools-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 52.5 kB

Release files / better_functools-0.2.0.tar.gz

Download URL better_functools-0.2.0.tar.gz
Size 36.2 kB
Tags Source
SHA-256 checksum
How to use checksums
1e8c0d0dedb7e6abad435248dd35025e64d2071138bc5512b6b804c215b92236
BLAKE2b-256 checksum
How to use checksums
c20b4263253de9f86ba2e4b2629e516883de880fa89a6354f24f8120f7887391
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 4, 2025.

Transparency log

Release files / better_functools-0.2.0-py3-none-any.whl

Download URL better_functools-0.2.0-py3-none-any.whl
Size 16.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
bc5fb96bd87f641ee8b8b4dbdc7b0763c1941fd977607909a19b817319cf2f44
BLAKE2b-256 checksum
How to use checksums
e46a6afcf47aea02606bbc76350e8c00a3b96b71b67b632d67a4b6cddeef1bde
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Mar 4, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page