ISTM the only time you come out a little ahead is if you know in advance that a function is going to be partialed (so you can decorate it), that you will need to partial arguments in other than a left to right fashion (otherwise a plain partial will suffice), that you won't use keyword arguments (the current partial works with keywords), and that you really dislike the lambda keyword (which neatly covers all cases from simple to complex without a new notation).
That said, this is a clever recipe. Kudos to the author for putting it together. I don't think it really rises to the level of "better" or "more intuitive", but it is an interesting experiment.
What if you have a function "f" that takes like 10 arguments and you need to pass it to a function "g" that expects as input a function takes 8 arguments.
I was gonna say cool for FP guys but alien to the Python world, but then i saw the f(..., x=1) syntax and decided you're a genius. Really nice idea.
In practice i worry about static checkers and IDE param hints though, how have you fared with these?
Not your fault at all, but mypy/pyright have very poor support for wrappers like this, and in IDEs it's common for their arg hints to devolve to a copout (args, kwargs) as well.
> Not your fault at all, but mypy/pyright have very poor support for wrappers like this, and in IDEs it's common for their arg hints to devolve to a copout (args, kwargs) as well.
You might be able to annotate it accurately with generics, ParamSpec and Concatenate[1].
High praise :-) I'm glad you like it! I don't know much about static checks / param hinting. TBH, I coded this up because I wanted to imagine how functions should work in Python as more of a fun exercise.
Accordingly there are a lot of things I have to do to make better_partial a strong tool for the community. I'll probably have time to work on the project again later in the week.
Hey, I use functools.partial a lot in my projects and I've always felt like it was pretty limited in the types of partial function application it could accomplish. I put together a modified version of partial over the weekend that I wanted to share / get feedback on. Let me know what you all think!
`functools.partial` has been bothering me for a long time and I've always thought it'd be nice to have something like the placeholder `·` that people use in math (i.e. `f(·, y, z)`). It didn't occur to me that a decorator might actually get us there without having to introduce new syntax. Nice project!
What specifically bothers you about functools partial? I think the decorator is nice in certain ways. However, then you have to decorate your code and guess where you’re going toy need the partials or create wrappers just to add the decorator which seems undesirable for a number of cases. I agree that partial has warts when it comes to inspection but at least they’re easy to make anywhere you want without having to apply any changes to the callee. Nice to have another option for partials though so that when you need these features there’s a way to get them.
Can these be serialized? One of my main uses for partial is passing things to multiprocessing pool.map. People often reach for lambda but it cannot be pickled/serialized so it fails.
In my opinion, I'd love to see this baked in as part of the language. Getting buy in from my team to use this in production is just not going to happen. But cool package though!
I'm sure it's nice, but adding another dependency to save some keystrokes in an edge case --- no thanks. If I want lots of partial application I'll use Haskell.
As pointed out, you could import _ directly into your namespace, or map it to some other shorthand name that doesn't interfere with your naming conventions.
Also note that the _ placeholder isn't the only way that better_partial helps you. You can also use ... to indicate that you want to omit all arguments except ones you explicitly pass as kwargs. For instance:
This is not a new idea. siuba (a dplyr-like Pandas alternative) is one project that does it, and it also has a "pipeline operator": https://github.com/machow/siuba
While it does solve the problem with functools.partial() forcing you to use keyword arguments in some cases, I don't think currying is a common enough operation to warrant a whole lib, or even a new syntax.
I'd rather see partial() promoted to a universal static method attached to any callable, so it's easier to discover, and use.
The work you've done is nice, but using a package for this issue gives off bad code smell. I'd much rather refine my functions and their relations rather than require an extra dependency that reduces readability for my coworkers.
whats wrong with functools.partial? I don't see that anywhere in the arguments.. all you say is "I find functools.partial unintuitive".. why? its a simple wrapper.
That said, this is a clever recipe. Kudos to the author for putting it together. I don't think it really rises to the level of "better" or "more intuitive", but it is an interesting experiment.