Yes I agree, if I was writing this for my own project I'm pretty sure I would do what you have done and use classes with an `area` method. (FWIW I think the dataclass approach is nicer for this example than namespacing separate `area` functions using modules)
You could define it as a typing.Protocol too.
My point was just that, even if for some reason you prefer function overloading, the restrictions needed to fit within the constraints of functool.singledispatch arguably lead to cleaner code than the complicated mess in the OP article.
This would look messy if you implemented as just a single function with variable no of kwargs that you sniffed in the body, and I don't think applying function overloading alone as OP has done solves the underlying problem.
> My point was just that, even if for some reason you prefer function overloading, the restrictions needed to fit within the constraints of functool.singledispatch arguably lead to cleaner code than the complicated mess in the OP article.
I love Python as a "hack it into a Frankenstein monster for fun" language because of how much power you have to get under the hood. For that reason I love articles like this.
But I'm not sure you'd ever want to implement overloading for practical uses. Just utilize optional arguments and some branching logic within the function. But even then, rethink how much you're trying to pack into a function.
Here, you have 2 functions that do 2 fundamentally different things. One is calculating an area for a circle. The other one is for a rectangle. When you have 2 different signatures, it's often a sign the process is very different, and you should signal that in your API.
If you scan code using those, your brain cannot quickly parse it. It needs to process "area(), ok but of what, well, it has only x param, so I guess this is for z". The overloading gimmick has little value for the reader, but a real cost (not to mention in python it actually slows the run time)
The better solution is simply to make it explicitly 2 functions with good names:
There's really nothing wrong with having two different signatures, it's a pretty pythonic way to do things. It's harder to document for sure, but other than that hardly a problem in many cases.
This post unfortunately reads like one of those Java programmer discovers Python (except not really) posts, but for C++. In general if you find yourself inventing a new paradigm for a 30-year old language you just started working with, it's reason enough to doubt you're doing something suboptimal. However, in this case the author is actually very familiar with Python, so I'm kinda confused.
The first part seems the wrong way to do it (treating it as an example). You would presumably overload area() on the object type, not on individual parameters representing the object's geometry. 'circle.area(r)' is even weirder - extracting radius just doesn't make sense here.
<SomeGeometricObject>.area() is right AFAICS.
Which I think is what you're getting at anyway.
But IMO overloading used right is cleaner than not having overloading.
This borders on spam. This is the third time you’ve submitted this post in the past two months and the feedback is no more positive this time.
Yes, you can do just about anything in Python. But single dispatch is usually a bad idea, and implementing it yourself instead of using the Python stdlib is always a bad idea.
There’s nothing wrong with showing off programming curiosities, but this isn’t presented in that context. The more often you post it, especially without heeding or engaging with feedback, the more annoying it becomes.
IMHO, multiple dispatch is unpythonic and you should use it only if you really need it. Also OP's implementation is missing typing information and differentiates functions only by length of arguments. Though probably that's the reason I do not like this idea in python because it's not a statically typed language.
This is not hard to write if you care about it (dispatching on data in addition to dispatching on type). Clojure-style multimethods with python-style type dispatch or data result dispatch can be had for under 150 lines. It's not particularly useful unless you are porting code or otherwise writing very unpythonic code.
Charitably interpreted: A better programmer knows using a fancy feature _can_ result in better code, but, also knows that fancy features usually aren't required to write good code (and that fancy features can turn good code into bad code when reached for too quickly)