Why would you constrain a function like `square` to only accept `int`s and `float`s? What if I want to square, say, a `fractions.Fraction`?
Why would you constrain a function like `square` to only accept `int`s and `float`s? What if I want to square, say, a `fractions.Fraction`?
It's like duck typing with a built-in Audubon society taxonomy chart.
You can always do whatever you want at runtime, it's still python.
IMHO, duck typing is strictly inferior to interface typing. You'd define a `Number` interface which `int`, `float`, ect all implement.
Duck typing has been fundamental to Python for a long time. Do you think we're seeing a shift away from it? In the future, do you think "Pythonic" code will include significant use of explicit interfaces?
We have been since at least the introduction of abstract base classes; even in purely dynamic python, having the ability to more explicitly declare and interrogate intent than pure duck typing is frequently useful.
> do you think "Pythonic" code will include significant use of explicit interfaces?
Sure, as it already does via abcs. But it will also still use lots of duck typing, though over time more of it will be “static duck typing” by way of protocols.
But of course give the slightest whiff of types and the type police will come and want to shove types down your throat all the way
>>> import numpy as np
>>> np.array("asdgh")**2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: ufunc 'square' not supported for the input types, and the inputs could not be safely coerced to any supported types according to the casting rule ''safe'' >>> import numpy as np
>>> np.mat(((1,0),(0,1)))**2
matrix([[1, 0],
[0, 1]]) >>> np.array([[1, 0], [0, 1]])**2
array([[1, 0],
[0, 1]])
Here: >>> np.array([[1, 2], [3, 4]])**2
array([[ 1, 4],
[ 9, 16]])
>>> np.mat([[1, 2], [3, 4]])**2
matrix([[ 7, 10],
[15, 22]])
The real problem with the np.array("asdgh")**2
example is squaring doesn't make sense for character data.Matrix vs. array squaring has other issues too, as matrix squaring only works with square matrices:
>>> np.mat([1, 2])**2
[...]
LinAlgError: Last 2 dimensions of the array must be square
>>> np.array([1, 2])**2
array([1, 4])I think typing_extensions.Protocol helps support the general duck typing "any object that has method x", though there are some implementation issues w/ dataclasses and such..
That won't help if I want to square a matrix, or a polynomial.
> typing_extensions.Protocol helps support the general duck typing "any object that has method x"
Even if there's a `powerable` protocol that could be used to annotate `square` and `cube`, how would you annotate a slightly more complex function like `poly`?
def square(x): return x**2
def cube(x): return x**3
def poly(x): return 3 * x**2 + 2 * xWhat’s you want is something like “commutative multiplication”
From comments? They are again limited by the authors imagination. From reading the source?
How do you find out that a function exists, what it accepts, and what it does normally?
> From comments? They are again limited by the authors imagination.
Sure, but an author which much experience with duck typing will typically write documentation that specified that expected methods (informal structural “types”) rather than nominal types.
With the static equivalent (protocols), it’s conceivable that this is also discoverable via tooling.
In quite a few cases where one would overload a mathematical operation to, say, sum two objects of certain type, it'd be better to explicitly type out the operation as a functor/lambda.
How would you use type annotations to show that `square` accepts a matrix (as well as an int, float, rational number etc.)?
Semi-seriously: by specifying the input type is a Monoid.
Not really. Doing so won't cause an error at runtime, but it will produce an error when you run the type checker.
Tell the type-checker to buzz-off by any number of means, including # type: ignore
It's to enable tooling, but not just autocomplete. The main purpose of typing is preventing type-related bugs, though making editor autocompletion and other editor information more robust is a not-insignificant additional benefit.
PEP 484 (created 29-Sep-2014, accepted 22-May-2015) wasn't motivated by VS Code (announced April 29, 2015).
Edit: Microsoft Python Language Server has it (i read)
With CPython they don't. Cython actually uses annotations to optimize the generated code.
It's essentially type-safe duck typing. In the case of square, you say i want x and y to support the multiply-operator, but i don't care what type they are otherwise.
Available since 3.8: https://www.python.org/dev/peps/pep-0544/