File: trampolines.rst

package info (click to toggle)
python-returns 0.26.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 2,652 kB
  • sloc: python: 11,000; makefile: 18
file content (44 lines) | stat: -rw-r--r-- 1,277 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
.. _trampolines:

Trampolines
===========

Python does not support TCO (tail call optimization), so any recursion-based
algorithms become dangerous.

We cannot be sure that
they won't cause ``RecursionError`` on deeply nested data.

Here's why we need trampolines: they allow to replicate tail call optimization
by wrapping function calls into :class:`returns.trampolines.Trampoline` objects,
making recursion-based function *always* safe.

Example:

.. code:: python

  >>> from typing import Union, List
  >>> from returns.trampolines import Trampoline, trampoline

  >>> @trampoline
  ... def accumulate(
  ...     numbers: List[int],
  ...     acc: int = 0,
  ... ) -> Union[int, Trampoline[int]]:
  ...    if not numbers:
  ...        return acc
  ...    number = number = numbers.pop()
  ...    return Trampoline(accumulate, numbers, acc + number)

  >>> assert accumulate([1, 2]) == 3
  >>> assert accumulate([1, 2, 3]) == 6

The following function is still fully type-safe:
- ``Trampoline`` object uses ``ParamSpec`` to be sure that passed arguments are correct
- Final return type of the function is narrowed to contain only an original type (without ``Trampoline`` implementation detail)

API Reference
-------------

.. automodule:: returns.trampolines
   :members: