Re:Implementing Function Overloading in Python
by BiteCode_dev on Thursday March 26, 2020 @08:55AM
(#22693027)
Again this is over-engineering. Put functions in modules to namespace them and be done with it.
If you really want types, use classes. It removes the need for single dispatch, creates a self documenting namespace and saves you an import when you want to do the calculation.
import math
from dataclasses import dataclass
@dataclass
class Rectangle:
length: int
breadth: int
def area(self) -> int:
return self.length * self.breadth
@dataclass
class Circle:
radius: int
def area(self) -> float:
return math.pi * self.radius ** 2
@dataclass is of course not mandatory, and just make the code shorter.
We are talking about very simple things here. No need to add complexity to them.
Re:Implementing Function Overloading in Python
by anentropic on Thursday March 26, 2020 @11:41AM
(#22694641)
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.
Re:Implementing Function Overloading in Python
by BiteCode_dev on Thursday March 26, 2020 @12:44PM
(#22695379)
> 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.
Re:Implementing Function Overloading in Python
by Waterluvian on Thursday March 26, 2020 @03:21AM
(#22691319)
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.
Re:Implementing Function Overloading in Python
by lordgrenville on Thursday March 26, 2020 @07:17AM
(#22692406)
Yes, my reaction to this was "this is horrifying Python, never do this in real life!" But also fascination at how malleable and subvertible it is once you go deep enough into the internals.
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:
Re:Implementing Function Overloading in Python
by oefrha on Thursday March 26, 2020 @01:00PM
(#22695562)
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.
Re:Implementing Function Overloading in Python
by throwaway_pdp09 on Thursday March 26, 2020 @08:52AM
(#22693005)
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.
Re:Implementing Function Overloading in Python
by throwaway_pdp09 on Thursday March 26, 2020 @08:54AM
(#22693021)
I remember reading the multimethods post and thinking it was wrong as it does not dispatch on all arguments, as dylan would (and I believe closure would too) - correct me if I'm wrong though.
Re:Implementing Function Overloading in Python
by goodside on Thursday March 26, 2020 @01:14PM
(#22695705)
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 a cool post from the author, though. I interpret this as more of an exploration of Python under the hood versus being a recommended production solution.
Python certainly could use a facility to do that based on an arbitrary predicate fn versus type comparison, though.
Python is well suited for this.. maybe it is time to throw a PEP in the ring.
Re:Implementing Function Overloading in Python
by joshuamorton on Thursday March 26, 2020 @03:10AM
(#22691273)
Functions.singledispatch allows overloading based on the type of the first argument, but doesn't allow complex overloads, like arg-count based or multi-type based.
Re:Implementing Function Overloading in Python
by emidln on Thursday March 26, 2020 @08:35AM
(#22692879)
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.
Re:Implementing Function Overloading in Python
by modo_ on Thursday March 26, 2020 @02:21PM
(#22696324)
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)
And you could achieve the same thing with built-in functools.singledispatch by designing your API better
e.g. the example given is:
What if you need to calculate the area of another shape that uses a single integer value as the parameter?With singledispatch and some types:
If you really want types, use classes. It removes the need for single dispatch, creates a self documenting namespace and saves you an import when you want to do the calculation.
@dataclass is of course not mandatory, and just make the code shorter.We are talking about very simple things here. No need to add complexity to them.
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.
Indeed. Less is more sometimes.
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.
Don't try to code in python like you code in another language.
Also, think about what your API is conveying. Overloading may make it less clear.
The snippet from this article is a good example of when not to do it:
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:
Or, most likely, put them in separated namespaces (using a module or a class), which does the same. It's very easy to abuse overloading because it tickles our need for refactoring. But it's a tool to solve a problem, not an end by itself.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.
<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.
It's just putting the original area() function in a module, not making it a method of a class. It's the simplest solution you can have, ever.
Adding an object is already more complex, and complexity needs to be justified. Just KISS if you can.
Guido's post on multimethods: https://www.artima.com/weblogs/viewpost.jsp?thread=101605
Clojure style multimethods: https://adambard.com/blog/implementing-multimethods-in-pytho...
Some sample code (I modified it to be commutative on the argument types):
https://gist.github.com/arunbear/caef7546d297c01fddbd3f67117...
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 a cool post from the author, though. I interpret this as more of an exploration of Python under the hood versus being a recommended production solution.
Python certainly could use a facility to do that based on an arbitrary predicate fn versus type comparison, though.
Python is well suited for this.. maybe it is time to throw a PEP in the ring.
Alternatively, you could also use the abstract base classes in the numbers module - https://docs.python.org/3/library/numbers.html
numbers.Number may be a good choice.
Still, you are right, overloading like this may be okay as a thought exercise, but would raise some serious questions during a code review. :)
nzxt^2: predicate based dispatch