[Python-ideas] Optional Static Typing -- the Python Way
Nick Coghlan
ncoghlan at gmail.com
Tue Aug 19 15:27:08 CEST 2014
On 19 August 2014 06:15, Ethan Furman <ethan at stoneleaf.us> wrote:
> After reading through the OST threads, and learning a bit more about what
> static typing means, and the difference between nominal and structural
> subclassing, I think I have a better appreciation for the knee-jerk "no
> way!" reaction, and also how to make what seems like a foreign-to-Python
> concept pythonistic.
>
> The most-feared problem seems to be over-specification (it is certainly
> mine). I think the answer has been alluded to a couple times already, but
> just to hopefully bring it front and center:
The exact same fear was raised when ABCs were added in PEP 3119 - that
by formalising ABCs, we'd see a plethora of additional isinstance
checks as people tried to make things "fail fast". That fear turned
out to be spurious then, and I think it's spurious now (unless we
allow builtins to be used for type annotations - we shouldn't do that,
as I think it *would* cause problems when developers migrate to Python
from languages like C, Java and C#).
Most Python code should continue to be written without type
annotations - the use of annotations (and type checkers) should be
limited to projects (and organisations) that are large enough for the
additional complexity to be worth the hassle.
Anecdotally, my experience is that the split between proponents of
static and dynamic typing tends to divide along "team size" lines. If
someone thinks a team of 20 working on one project is "a lot of
people", then they're likely to favour dynamic typing for the
additional flexibility it offers. If they think such a team is small,
then they're more likely to want compiler enforced assistance in
ensuring that everyone is playing by the rules of the API.
Myself, I think the kind of structural typechecking offered by "pylint
-E" and the "optional type declarations" proposal starts looking far
more attractive the first time you're stuck at work after hours
debugging a production failure that happened due to a typo in an error
handling path that wasn't covered by your test suite. However, if your
code isn't in the category of "if this doesn't work, my
company/project/organisation stops until it is fixed", then type
assertions are unlikely to be worth the investment needed to write
them in the first place :)
Ultimately, my perspective is that Guido's proposal boils down to
having a nice syntax where:
def myfunc(a : KindX, b: KindY, c: KindZ):
...
is the moral equivalent of:
def myfunc(a, b, c):
assert isinstance(a, KindX)
assert isinstance(b, KindY)
assert isinstance(c, KindZ)
except done in a way that is more amenable to static analysis by
looking at the compiled AST, rather than actually executing the code.
Calling it "optional static typing" is probably a bad idea, since the
proposal isn't to change the type system itself - that will be just as
dynamic as it always has been. "optional type assertions" is probably
the most accurate, but then people may think it is *actually*
translated to runtime checks as I show above, which it won't be.
"optional type hinting" is probably the most reassuring term that
could be used, while still remaining accurate.
> Instead of either 'nominal' or 'structural', use our own 'dynamical'
> subclassing scheme.
>
> In other words:
>
> def spamify(current: datetime.date, moved:int) -> bool:
> # ONE_DAY is a one day time delta, previously declared
> days = ONE_DAY * moved
> proposed_date = current + days
> return it_works(proposed_date)
>
> The type checker will not look to see if 'current' is a datetime.date, but
> rather will check that what datetime.date's __add__ works with
> (datetime.delta) and then check that what is passed in for current has an
> __add__ that also works with datetime.delta.
>
> I think this would be far more valuable than just nominal as it follows
> duck-typing, and hopefully less work than structural as it's only checking
> the methods and attributes actually used.
ABCs already support ducktyping, and explicit registration, etc, etc.
We don't need a completely new type system, we can just file the rough
edges off the categories we have already defined, and fill in some of
the missing pieces (like allowing union types, which I seem to recall
being discussed back in the PEP 3119 time frame, but postponed until
more concrete use cases presented themselves).
We may even need to finally add String and BytesLike ABCs, but we've
been muttering about doing that for years.
Cheers,
Nick.
--
Nick Coghlan | ncoghlan at gmail.com | Brisbane, Australia
More information about the Python-ideas
mailing list