Skip to main content

Implicit lambdas

Build Status codecov PyPI

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:

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 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.

from implicit_lambda import _, x, y, to_lambda
from implicit_lambda.builtins import map

Implicit lambda provides wrappers around all common builtins.

    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.

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

    mapped_list = mapper(a_list)

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

Implicit lambdas supports nested expressions

    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):

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

or:

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

Implicit lambdas support multiple arguments, too:

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

Performance measurement

Run

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

Advanced features

Some operators are not supported directly because returning LambdaDSL would not work (__bool__, __contains__) or it could cause issues (__repr__).

There are wrapped builtins (bool._ and repr._) that can be used instead, or helper functions like contains and not_contains that are exported from implicit_lambda.

Additionally, implicit_lambda supports custom arg_resolvers that map placeholders to lambda function arguments. By default, strict_resolver is used. There is also from_allowed_signatures, which picks the first argument signature that contains all used placeholder arguments, and flexible_args, which supports more than a required number of arguments and a custom partial ordering of placeholders in the case of conflicts.

Metadata

Release files for implicit-lambda 0.4.1

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

Source distribution (sdist)

Source distribution for implicit-lambda 0.4.1
File Size Uploaded Provenance
implicit_lambda-0.4.1.tar.gz 22.4 kB Without provenance Details

Built distribution (wheel)

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

Total release size: 46.4 kB

Release files / implicit_lambda-0.4.1.tar.gz

Download URL implicit_lambda-0.4.1.tar.gz
Size 22.4 kB
Tags Source
SHA-256 checksum
How to use checksums
c4a918ce90b82804fcccc5d9060a0831e5fa73320c7d76298167436b240a09c5
BLAKE2b-256 checksum
How to use checksums
84da1f139052ab3f91f69ac7d30255e875975fe99028f6fc8621b81cb7a6e9ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Release files / implicit_lambda-0.4.1-py3-none-any.whl

Download URL implicit_lambda-0.4.1-py3-none-any.whl
Size 24.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
be064a1b1fdbc9247d36421175c8e9b028112f88f532485bf5c265d347049d22
BLAKE2b-256 checksum
How to use checksums
797ab9b38eaee17e34366b7e1e0c124abd04a5da200fdcc21a0f59ef0e5dd1e4
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.5

Security for implicit-lambda 0.4.1

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.

Release history Release notifications | RSS feed

This release

0.4.1 This release

2 release files No provenance

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