3 ms·
This is a neat article, and a nice dive into Python. I think it also taught me, by prompting an immediate negative gut reaction to the basic idea, about an opi
by mumblemumble 7y ago
This is a neat article, and a nice dive into Python.
I think it also taught me, by prompting an immediate negative gut reaction to the basic idea, about an opinion about language features that I didn't know I had, let alone that I didn't know I had so strongly: I think that I officially believe that function overloading should only be used for two reasons: First, you can overload functions of the same arity to mimic dynamic typing in a static language. A print function that takes many types of argument, for example. Second, you can provide multiple arities to mimic optional arguments in a language that doesn't have them.
But the example in the argument, where the overload is for providing two different versions that do different things with their arguments, is not something I'd want to see in real code. There's just too much opportunity for confusion. For example, if I were familiar with `float area(int)` as a function that calculates the area of a circle, and and then encountered `area(int, int)`, I would guess that the return value is a float, and that the two ints are now the lengths of the semi-major and semi-minor axes of an ellipse.
And I'm having a hard time coming up with a better example for the article. Perhaps because function overloading just isn't a desirable feature in a language like Python.
- cuchoi 7y agoI don't miss it a lot in Python except for some cases such as: area(Circle circle): ... area(Square square): ... You could say "Ah! But that could be something that you define in each class, like square.calculate_area()". Yes, but sometimes you don't have access to the class. You could monkey-patch it but that's not something that I like to do.
- mumblemumble 7y agoThe Pythonic way to deal with that would be to just remember that Python is a dynamic language: def area(shape): if isinstance(shape, Circle): ... if isinstance(shape, Square): ... Or, if you want better coverage from your type checker, from typing import overload @overload def area(shape: Circle): ... @overload def area(shape: Square): ... def area(shape): if isinstance(shape, Circle): ... if isinstance(shape, Square): ... This still isn't real overloading. The last one is the one and only function. All the other two bits do is tell the static type checker what kinds of arguments it's prepared to support. edit: Scratch that, I think what I'd really go for in a simpler case like this would just be def area(shape: Union[Circle, Square]): ...
- closed 7y agoPython including functools.singledispatch I think is a strong indicator that function overloading IS pythonic (or at least pythonic enough to core python developers)
- joshuamorton 7y agoI don't know that I've seen singledispatch used anywhere, and the standard library includes a lot of unpythonic code (and entire modules). As a simple example, the unittest module is entirely unpythonic. Singledispatch was mostly included to handle specific cases where singledispatch is very clearly useful (the PEP mentions pprint and copy), but not as a generic tool for common end-user code.
- deleted 7y ago[deleted]
- int_19h 7y agoIn languages that have named arguments - Python being one - it's also possible to overload based on that. In effect, they become a part of the function name (kinda like Objective-C).
- closed 7y agoOne common use for function overloading is when you need the function to work on classes defined across several different packages. It's used a lot in R for this reason. You might want to have a function that operates on different models, but there are 60 modeling packages it might be used on.