Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds transducers support #904

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft

Adds transducers support #904

wants to merge 1 commit into from

Conversation

thepabloaguilar
Copy link
Member

I have made things!

Checklist

  • I have double checked that there are no unrelated changes in this pull request (old patches, accidental config files, etc)
  • I have created at least one test case for the changes I have made
  • I have updated the documentation for the changes I have made
  • I have added my changes to the CHANGELOG.md

Related issues

🙏 Please, if you or your company finds dry-python valuable, help us sustain the project by sponsoring it transparently on https://github.com/sponsors/dry-python. As a thank you, your profile/company logo will be added to our main README which receives hundreds of unique visitors per day.

Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work!

.. code:: python

>>> from typing import List
>>> from returns.transducers import tfilter, reduce
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's import reduce from functools, because user might be confused: is it our reduce or default one?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to use our reduce since we have more features than the built-in reduce

>>> assert reduce(xform, my_list, []) == [0, 2, 4, 6]

"""
def reducer(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We tend to use decorator / factory naming when defining nested decorators

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, but I think using that pattern might be weird:

def tmap(function):
    def reducer(step):
        def map_(acc, value):
            ...
        return map_
    return reducer

def tmap(function):
    def decorator(step):
        def factory(acc, value):
            ...
        return map_
    return reducer

In fact transducers is not intended to be use as a decorator and I think tmap -> reducer -> map_ is more meaningful! 🤔

Callable[[_AccValueType, _ValueType], _AccValueType],
]:
"""
:py:func:`filter <filter>` implementation on a transducer form.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let's make the first line more user-friendly by removing :py:func: stuff.
It can be later in the body.

returns/transducers/transducers.py Outdated Show resolved Hide resolved
returns/transducers/transducers.py Outdated Show resolved Hide resolved
returns/transducers/transducers.py Outdated Show resolved Hide resolved
returns/transducers/transducers.py Outdated Show resolved Hide resolved
returns/transducers/transducers.py Outdated Show resolved Hide resolved
Copy link
Member

@sobolevn sobolevn left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work 👏



#: A singleton representing any missing value
Missing = _Missing()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Missing = _Missing()
Missing: Final = _Missing()

from returns.transducers.transducers import _Missing


def test_missing_singleton():
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def test_missing_singleton():
def test_missing_singleton() -> None:

And all other tests as well.



def test_reduce():
"""Should fail when iterable is empty and non initial value is given."""
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we? Raising exceptions is not something we do in this library (at least we try to).

Can we just return the empty sequence? Or do anything else?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

2 participants