Skip to main content
# Implicit lambdas

[![Build Status](https://www.travis-ci.com/BlackHC/implicit_lambda.svg?branch=master)](https://www.travis-ci.com/BlackHC/implicit_lambda) [![codecov](https://codecov.io/gh/BlackHC/implicit_lambda/branch/master/graph/badge.svg)](https://codecov.io/gh/BlackHC/implicit_lambda) [![PyPI](https://img.shields.io/badge/PyPI-blackhc.implicit_lambda-blue.svg)](https://pypi.python.org/pypi/blackhc.implicit_lambda/)

This package adds support for implicit lambdas, so you can write `map(_ + 5, a_list)` instead of `map(lambda x: x + 5, a_list)`.

The code uses Python 3.7 features for brevity. The package could easily be made to work with earlier version. Please submit an issue if there is need.

Implicit lambdas are implemented using code generation. They are as fast as regular lambdas when running python with `-O` to enable optimizations.

```
--------------------------------------------- benchmark: 3 tests -----------------------------------
Name (time in ns) Mean StdDev Median OPS (Mops/s)
----------------------------------------------------------------------------------------------------
test_normal_lambda 196.3468 (1.01) 140.7775 (2.32) 166.9600 (1.0) 5.0930 (0.99)
test_il_lambda 196.6705 (1.01) 113.9049 (1.88) 171.6000 (1.03) 5.0846 (0.99)
test_op_chain 195.0673 (1.0) 60.6268 (1.0) 176.2300 (1.06) 5.1264 (1.0)
----------------------------------------------------------------------------------------------------
```
`il_lambda` uses implicit lambdas. `normal_lambda` uses a regular lambda. `op_chain` uses functools.partial and the operator module.

Without `-O`, lambdas with a more verbose `repr` are created:

```python
assert repr(_ + 5) == "<LambdaDSL: lambda x: (x + 5) @ {}>"
```

This results in up to 20% slower execution for very simple expressions. (A new type is created on the fly to hold the expression and resolving a call using a custom `__call__` is sufficient to incur such a penalty.)

For more complex expressions, the overhead will become negligible.

Python expressions are fully wrapped, including index operations `[]` (using `__getitem__`), member access (using `__getattribute__`) and any calls (`__calls`). This results in great flexibility.

To disambiguate between calls within the lambda and calling a lambda, implicit lambdas have to be explicitly converted into a callable/regular Python lambda.

`to_lambda` turns an implicit lambda expression into a Python lambda.

`auto_lambda` adds support for implicit lambdas to existing functions that take callables.

Wrapped versions of `builtin`, `functools` and `itertools` are provided out-of-the-box.

## Installation

To install using pip, use:

```
pip install blackhc.implicit_lambda
```

To run the tests, use:

```
python setup.py test
```

## Example

To enable implicit lambdas, import placeholder symbols as needed and import wrapped builtin functions to use implicit lambdas interchangably with regular ones.

Usually, `to_lambda` and other helper functions don't need to be called.

```python
from blackhc.implicit_lambda import _, x, y, to_lambda
from blackhc.implicit_lambda.builtins import map
```

Implicit lambda provides wrappers around all common builtins.

```python
a_list = list(range(10))

mapped_list = map(_ + 2, a_list)

assert list(mapped_list) == list(range(2, 12))
```

There are also wrappers that turn builtins into lazy functions. A wrapped function provides a `._` version that can be used within an implicit lambda.

```python
mapper = to_lambda(map._(x + 2, _))

mapped_list = mapper(a_list)

assert list(mapped_list) == list(range(2, 12))
```

Implicit lambdas supports nested expressions

```python
mapped_list = map((_ << 3) * 3 - 23 * _ + 2, a_list)

assert list(mapped_list) == list(range(2, 12))
```

More useful reprs are available in __debug__ mode (just don't use `-O` when running python):

```python
another_lambda = to_lambda((_ << 3) * 3 - 23 * _ + 2)
assert repr(another_lambda) == "<lambda x: ((((x << 3) * 3) - (23 * x)) + 2) @ {}>"
```

or:

```python
assert (repr((_ << 3) * 3 - 23 * _ + 2) ==
"<LambdaDSL: lambda x: ((((x << 3) * 3) - (23 * x)) + 2) @ {}>)"
```

Implicit lambdas support multiple arguments, too:

```python
assert to_lambda(x * y)(5, 3) == 15
```

## Performance measurement

Run

```python
python -O -m pytest -k test_performance --benchmark-warmup=on --benchmark-autosave --benchmark-disable-gc
```


Metadata

Release files for blackhc.implicit-lambda 0.4.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 blackhc.implicit-lambda 0.4.0
File Size Uploaded Provenance
blackhc.implicit_lambda-0.4.0.tar.gz 21.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for blackhc.implicit-lambda 0.4.0
File Interpreter ABI Platform
blackhc.implicit_lambda-0.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 44.5 kB

Release files / blackhc.implicit_lambda-0.4.0.tar.gz

Download URL blackhc.implicit_lambda-0.4.0.tar.gz
Size 21.0 kB
Tags Source
SHA-256 checksum
How to use checksums
196a8f96fa8903d4b265a3838c8a922c0901930d0c83df6a89bd2af8a71df367
BLAKE2b-256 checksum
How to use checksums
aff5975490e7bd548b01653f2f8a462242cc14272853e6482372f3442df74cda
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.12.1 pkginfo/1.4.2 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.1

Release files / blackhc.implicit_lambda-0.4.0-py3-none-any.whl

Download URL blackhc.implicit_lambda-0.4.0-py3-none-any.whl
Size 23.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b72217e512cbcf9e80caa321c5eddfe3c04342c19bab2f74a0f75331b9316462
BLAKE2b-256 checksum
How to use checksums
b4de508b673abf7d1898cf50ce685b83f82d6258b78219b4dc94cda0c358134e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/1.12.1 pkginfo/1.4.2 requests/2.21.0 setuptools/40.6.3 requests-toolbelt/0.8.0 tqdm/4.28.1 CPython/3.7.1

Security for blackhc.implicit-lambda 0.4.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

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