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

Friendly ping from dry-python/returns #4

Open
sobolevn opened this issue Apr 21, 2020 · 4 comments
Open

Friendly ping from dry-python/returns #4

sobolevn opened this issue Apr 21, 2020 · 4 comments

Comments

@sobolevn
Copy link

Hi @Niriel! Thanks a lot for building this project. It looks amazing.

Currently we are working on better typed FP stack in Python. It has some great results already, but also some limitation.

During this release I am focused on working with callables, recently I did fully typed partial function: https://returns.readthedocs.io/en/latest/pages/curry.html And now I researching @curry decorator. I would ideally love to see something very similar to your solution.

So, there are several ways for us to continue:

  1. We can collaborate on this together: in this case we will just recommend your library in our docs and treat as a separate but complimentary package. I can also help with some other features we need for these projects to be compatible: like mypy plugin and python[3.6, 3.7] support
  2. We can tests all cases we need and port everything directly into returns project and I will add you as a collaborator
  3. I can continue from here alone if you have no interest or time to maintain this library. In this case I can probably use some of the code you wrote (which is allowed under MIT license)

What suits you best?

Cheers,
Nikita Sobolev

@Niriel
Copy link
Owner

Niriel commented Apr 22, 2020

Hello!

I have some free time these days so I'd be happy to work on it.

I like the idea of keeping yummycurry its own package, in the tradition of doing one thing and doing it well. I'm curious to see it used in the real world (so far I just made it for myself); there are definitely things I've not thought about when I wrote it.

About Python 3.7: the main "problem" is the introduction of the positional-only arguments introduced in 3.8, which yummycurry expects. This feature needs to be switched off for earlier Python versions. Not sure how to do that nicely. I could at least setup some tox magic to automate the testing on various versions; that would be a first step.

Give me a couple of days to get familiar with my own package again; I've been busy with GUI stuff lately, which is as far as FP as you can get, so I need to refresh my memory :D.

@sobolevn
Copy link
Author

sobolevn commented Apr 22, 2020

Thanks a lot, @Niriel! I would love to help you with the mypy stuff.

Let me better explain why I push currying so much for returns.

Currently, all types we provide are not actually monads. Because they are not applicative.
This was intentional, because without @curry the only possible way to achieve working .apply method with several arguments is overusing lambda functions. We will end up with something like this:

Some(3).apply(Some(2).apply(Some(1).map(lambda a: lambda b: lambda c: a + b + c)))

But, when we would have typed curry, we will be allowed to use:

@curry
def some_three(a: int, b: int, c: int) -> int:
     return a + b + c

Some(3).apply(Some(2).apply(Some(1).map(some_three)))

Which is times better!

So, our goal for the next release (not the one we are working on right now) to add .apply and @curry.
And while .apply is our own stuff, @curry can be imported from whatever package user prefers as long as it is properly typed, that's 100% fine by me.

Related: dry-python/returns#342

@Niriel
Copy link
Owner

Niriel commented Apr 22, 2020

I have no idea how to write a MyPy plugin; any help or suggestion would be lovely indeed.

What is Some here? Looks like the Identity functor. Is the name taken from a language I don't know? And yes, lambdas are a nightmare to write, read and debug :D.

How "properly typed" are we talking about, though? What signature should I give my curry function? Is f:Callable[..., A] good enough for its first parameter? It's quite hard to be more explicit. Actually it's even worse, as yummycurry.curry also takes non-callable objects (it just returns them). I guess Union can take care of that but we really cannot go very far.

I'm curious about your monads. apply is usually not a problem, it's pure/return/wrap that's difficult. The lack of return-value polymorphism makes it hard to write a function a -> f a where f is an applicative or a monad that we don't know because it's not passed as a parameter.

@sobolevn
Copy link
Author

sobolevn commented Apr 22, 2020

@Niriel we have a lot of hacks to fight HKT in python 😆 I have even tried to bring this into a separate mypy plugin.

As I said, I can take the mypy part. I have done quite a lot of work with mypy. For example, here's our plugin for the similar feature, we type partial function: https://github.com/dry-python/returns/blob/master/returns/contrib/mypy/_curry.py And here are our type-tests to showcase real-life examples: https://github.com/dry-python/returns/tree/master/typesafety/test_curry

And I want something similar for @curry. Let me show you some examples:

@curry
def x(a: int, b: int) -> int:
    return a + b

reveal_type(x)  # Would be Overloaded([(def a:int -> def x: int -> int), (def a: int, b: int -> int])

And the same for all possible argument types and values, including default values, kw and pos only, args and kwargs. And including Generics and @overloads.

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

No branches or pull requests

2 participants