I want to tell Python how I intend to use my variables, not type check.
def gcd(a: int, b: int) -> int:
while a:
a, b = b%a, a
return b
would work the same as:
def gcd(a, b):
a = int(a)
b = int(b)
while a:
a, b = int(b%a), int(a)
return int(b)
(we are filtering every assignment to a,b through an 'int', at the function call, and also every assignment in the function body)
Of course, we would expect most of the calls to 'int' to melt away, as the operations we are performing are well defined with respect to type
Happily, we would get the appropriate exceptions when calling with anything other than 'int'
===========
Duck Typing
===========
with respect to enforcing 'duck-typing', we could provide a callable 'duck_something'
def foo(f: duck_StringIO) -> str:
f.write("hello")
return f.getvalue()
would be the same as
def foo(f):
f = duck_StringIO(f)
f.write("hello")
return str(f.getvalue())
as before, a clever optimizer would recognize that getvalue was defined like this
def getvalue(self) -> str:
the upshot is that most of these 'type-enforcing' calls at assignments would melt away
==========
coercetype
==========
Container Types, I would avoid type-variables, because I don't understand them as well as I probably should
def min(a: T, b: T) -> T:
if a < b:
return a
else:
return b
instead
def min(a, b):
enforce return: coercetype(a, b)
if a < b:
return a
else:
return b
all returns would be filtered through the result of 'coercetype'
if we wanted to enforce type on a temp variable:
def min(a, b):
T = coercetype(a, b)
enforce temp: T
enforce return: T
...
===============
container types
===============
def int_sort(L: Sequence of int) -> int:
def list_of_int_sort(L: list of int) -> int:
the 'of' keyword is so that we avoid list(int)
===========
overloading
===========
'overloaded' looks for 'TypeError', moves on to the next signature
I assume will have an intellegent dispatch logic, so the minimum
number of signatures are tried
@overloaded
def min(a: iterable):
T = coercetype(*a)
enforce return: T
...
@overloaded
def min(x, y, *rest):
T = coercetype(x, y)
enforce rest: list of T
# rest = (list of T)(rest)
# and all other assignments to rest in the body of the function
# also use (list of T) to 'filter' and enforce type
enforce return: T
...