
Why I Prefer Dynamic Typing Over Static Typing (2017) - porjo
http://www.smashcompany.com/technology/why-i-prefer-dynamic-typing-over-static-typing-the-speed-of-adapting-to-change
======
OskarS
> For the programming that I do, I am often creating new architectures.
> Therefore I need dynamic typing.

He seems to consider static typing equivalent to "locking down" an
architecture, that when you use static typing you're locked in to a certain
way of doing it, and you're stuck with it. In my experience of working with
large codebases with both dynamically and statically typed languages, the
opposite is true.

Static typing frees you up to make changes to interfaces in a way that dynamic
typing does not. For instance, if i want to add or remove a parameter to a
function in a statically typed language, it's trivial. I just do it, and the
compiler goes "ok, this function is called from these 4 places, so just fix
those" and you now are assured that everything will work.

That doesn't work in dynamically typed languages. There's no reliable way to
change an interface and be confident that you haven't broken anything (+/\-
extremely good linters, but those aren't perfect in the way a compiler is).
This leads to a "never change this function, you can break all sorts of
things" attitude that simply doesn't exist with static typing, where the
compiler can just tell you what you need to fix.

There are perfectly valid arguments in favor of dynamic typing (it's arguably
easier, often faster to work with etc.) but this particular one is extremely
silly. The exact opposite is true.

~~~
klmr
Good test coverage and test-first philosophy _can_ make this problem go away,
but it always requires that you didn’t make an error in your tests. I always
found this argument bizarre: I write tons of tests but I know that I’m
fallible, and writing such tests is time-consuming. Why not let a static type
checker do the work for me, with less chance of error?

~~~
twoquestions
That's another reason I like (good) static types, it's a bunch of compiler-
included documentation and testing that I don't need to write!

~~~
erik_seaberg
Also a good reason for defining and using the most specific subtypes possible.
In some domains, "this arg is a string" is useless for validation or
documentation because _everything_ is a string. Is it really a URL? a UUID? a
serialized timestamp? a property name?

~~~
woolvalley
That's called something being stringly typed, and it's a code smell. You make
URL classes, UUID classes, timestamp classes, enums, etc to replace the
strings.

------
icholy
> Static typing does not live up to its promises. If it did live up to its
> promises, we would all use it, and the fact that we don’t all use it
> suggests how often it fails.

[https://en.wikipedia.org/wiki/Argumentum_ad_populum](https://en.wikipedia.org/wiki/Argumentum_ad_populum)

~~~
CogitoCogito
What a bizarre argument. You could replace "static" with "dynamic" and you
would have an equivalent argument that would just as strongly (i.e., in fact,
weakly) argue against dynamic typing. This logical hole is obvious enough to
drive a bus through. I don't understand how the author wouldn't have noticed
it.

~~~
fdgionionoi
The logical hole is not obvious. If it were obvious, we would all notice it,
and the fact that the author didn't notice it suggests it's not obvious.

~~~
Varcht
I guess this is what happens when everyone gets a trophy.

------
taude
Written on chalk board:

I will not participate in Hacker News Static vs Dynamic typing debates.

I will not participate in Hacker News Static vs Dynamic typing debates.

I will not participate in Hacker News Static vs Dynamic typing debates.

I will not participate in Hacker News Static vs Dynamic typing debates.

I will not participate in Hacker News Static vs Dynamic typing debates.

Stay strong, Me

~~~
rkangel
The problem with the debate is that it's all based on personal preference and
anecdotes, all of which are subject to cognitive biases. What we really need
is a proper study, but they are notoriously hard.

The debate fundamentally comes down to 'under what circumstances is the extra
cost of working with a static type system worth it for the benefits'.

For a 15 line helper script of the sort I've just written, Python with its
dynamic typing is (to me - a proponent of static typing) the fastest thing to
work with due to the low overhead. To me there is a threshold of project
complexity where the cost-benefit ratio flips. Is that actually true? Does
that vary for all people?

~~~
IronBacon
> _What we really need is a proper study, but they are notoriously hard._

Here you go: " _A large-scale study of programming languages and code quality
in GitHub_ "[0]. I've only read the abstract (are we OK on sharing sci-hub
links? [1]), spoiler alert, according to this research some languages are more
defect prone than others but the effect is small.

[0] [https://cacm.acm.org/magazines/2017/10/221326-a-large-
scale-...](https://cacm.acm.org/magazines/2017/10/221326-a-large-scale-study-
of-programming-languages-and-code-quality-in-github/abstract)

[1] sci-hub.se/10.1145/3126905

~~~
rkangel
I'm aware of this study, and a couple of others. They are all only looking at
one area of productivity though, because that's the available data. In this
particular case, there's no indication of development time required to achieve
that level of bugginess. Maybe in practice all projects do enough work to
reach an average level of reliability, but then what's interesting is how much
developer time is required to get there.

It's a total cost analysis that's interesting - and there's a lot of costs.
Cost of development, how that varies depending on required time to market,
cost of bugs (fixing them, and loss of sales due to customer reliability
concerns), cost of complexity as software has to be maintained over time.

~~~
IronBacon
> _but then what 's interesting is how much developer time is required to get
> there._

Yeah, good point. I read an old research where they tried to test the
"productivity" offered by different languages, but then it became difficult to
asses the experience of the different developers...

------
dleslie
> In a dynamic language I could simply work with a deeply nested data
> structure of maps and lists, and I’d handle the casting at the very end of
> the process. In a dynamic language, I could treat everything as a string
> till the very end, and then cast to integers or dates or floats or strings
> as needed. In a dynamic language, I could write the code faster, with less
> errors, and with less code.

Nothing described is impossible, or even hard, for a statically typed language
to do.

Perhaps I misunderstand them, but author seems to be under the impression that
static typing doesn't allow for type conversions.

> In static-type languages such as Java, I’m forced to go with either #1 or
> #2, and they are both bad options.

That's simply not true.

------
bunderbunder
I have experienced the same pain as the author many times, and, though I
mostly work with Java by day these days, when possible I would much more
happily reach for Python when I'm needing to hack on a REST API.

But I don't think this particular issue has much, if anything, to do with
dynamic vs. static typing. It's mostly about how clean and elegant Python's
way of handling JSON is compared to the black hole of viral enterprise-y
overdesign that is Jackson, Java's _de facto_ standard library for dealing
with JSON.

With Python, JSON is deserialized to, in essence, a dictionary that maps keys
to values, where the values are either strings, arrays of values, or
dictionaries.

With Jackson, it's exactly as awful as TFA describes.

But I can easily imagine a Java library where JSON deserializes to some
"JSONEntity" type that can act as either a string, a list of entities, or a
string->entity map. And then I could interact with that in the same loose,
don't-force-me-to-worry-about-details-I-don't-currently-care-about way that I
do in Python. Perhaps one even already exists. It doesn't seem a far-fetched
dream - I've used similar libraries for other static languages.

TBH, I haven't looked, because, even if I found one, I'd still be compelled to
use Jackson, anyway. Because Jackson has been around forever, and Jackson is
now so deeply entrenched that nobody working in the Javaverse can even fathom
life without it. Suggesting such a thing would be heretical.

~~~
sirbranedamuj
Jackson supports a workflow like you describe.

[https://fasterxml.github.io/jackson-
databind/javadoc/2.2.0/c...](https://fasterxml.github.io/jackson-
databind/javadoc/2.2.0/com/fasterxml/jackson/databind/JsonNode.html) and
related classes/functions.

------
phaedrus
I saw a talk by an npm developer who dismissed type checking as "just another
kind of unit test" for your code (and advocated instead dynamic typing and
manual unit tests). It bothered me enough to think about what was wrong with
what he said long after the talk. I realized the difference is type checking
takes the place of infinite numbers of unit tests: unit tests only assert an
"exists"; type checking proves "forall".

The linked article, however, is a whole other level of incorrect thinking and
drivel.

------
mattnewport
"Static typing tends to be used in areas where legal regulations create needs
that outweigh programmer productivity."

This is rather a broad generalization that doesn't seem accurate to me. It's
at least misleadingly phrased if it's not intended to imply that this is the
main reason or primary domain where static typing is used. Performance is a
major reason static typing is preferred in many domains like games development
for example where legal regulations are largely irrelevant.

~~~
Retra
I mostly use static typing because I don't want the intended behavior of the
program to be described solely in my head.

~~~
tabtab
That may be asking too much of a programming language not intended for AI.

What I see between each approach is tradeoffs. Which one has the net benefit
may ultimately depend on personality, domain, and shop practices. It's one of
those architectural holy wars that may never end.

~~~
Retra
I do the vast majority of my programming in Rust and Python. I love both of
those languages, but the fact is, the problem that static typing causes me in
Rust is that I have to write a lot more code, but it is all pretty much rote.
The problems that dynamic typing causes me in Python is that I have to
evaluate large chunks of the program to figure out what it means. These are
totally different kinds of frustration, but I can put up with the rote stuff
because it doesn't distract me from thinking, but having to question what the
code I'm looking at can do requires much more creative thinking and detective
work that leaves me less able to passively think about anything else.

They're both manageable, really.

------
SkyPuncher
Static typing is fantastic in a closed system. It's predictable and reliable.

My problem is nearly every type system breaks down when you try communicate
with something outside of the closed system (e.g. API calls, 3rd party
integration, etc).

An API returns an unexpected data type, Missing a field that's supposed to be
required, Starts returning a number as a string because they changed their ID
system, etc.

It always seems to end up in types where every field is optional - defeating
the purpose of having types in the first place.

~~~
klmr
The API problems you cite aren’t prevented in dynamically typed systems. If
anything they are worse, because they could lead to silent failures, whereas a
statically typed API statically checks and guarantees the contract. Contrary
to what you imply, a statically typed API _can’t_ return an unexpected type.
That’s an advantage.

> It always seems to end up in types where every field is optional

“Always”? Not by a long shot. These situations where this is the case can be
isolated and dealt with explicitly. You may object to the explicitness but —
again, for reasons of robustness — proponents of static typing prefer this.

~~~
pmontra
> whereas a statically typed API statically checks and guarantees the contract

I didn't work much with static typed languages lately, so I'm really puzzled
by your comment. If I expect an int in the age field of a JSON response and
the server suddenly sends me a string, maybe with value "NaN", how do you
check for that at compile time? I expect the program to either crash or manage
the error at run time (try/catch, die-and-restart a-la-Erlang, etc)

Maybe JSON doesn't count as "statically typed API", but how many of them do
common Internet services expose to the public? And how to we make sure that
the server or any in between proxy doesn't misbehave and violates the
contract?

~~~
klmr
There are different kinds of APIs. You seem to be talking about inherently
dynamic ones, such as your JSON blob example. Of course you cannot statically
guarantee their contents, which is why statically typed JSON layers provide
ways of asserting a schema. Using such schema checkers is best practice even
in dynamically typed languages.

Either way, you _need_ to handle such failures, both in statically and in
dynamically type-checked languages. The only difference is whether the
handling happens explicitly throughout your code or automagically by an API
that gives you back a well-behaved object. And both of these ways are possible
in both static and dynamic languages (but static languages tend to go for the
latter, whereas dynamic languages tend to make you do the former).

------
noelwelsh
It's a fallacy to think that all statically typed languages are the same, and
all libraries in the statically typed languages are the same. It seems the
author is making these fallacies. My experience programming C, Java, and
Haskell---all statically typed languages---is vastly different.

------
neetodavid
I parse a lot of JSON in surprising and inconsistent formats and what works
best for me is to immediately sanitize the object (option 1 that they
describe) so that the rest of the code that operates on it can stay consistent

I'm interested in what an implementation of option 3 would look like. Is it
just some regex to find the relevant characters in the string?

~~~
MaulingMonkey
If I'm lucky, for web stuff, I can just write a typescript interface
definition or 5 to describe the JSON format, and suddenly I have working
intellisense, protection from typos (after the first), etc.

~~~
maxxxxx
That doesn't protect you from inconsistent input. You still may have to
sanitize.

------
rgoulter
I'd paraphrase as "for the case of consuming an external API, using generic
maps and arrays is more useful than strictly 'decoding' the data to a type
earlier than necessary". That kindof makes sense.

It seems a bit flame-y to see this as "dynamic typing is better than static
typing", though. -- It's more of a suggestion that a technique like "cast to a
type" where you don't need all the info in the type risks breaking when it
doesn't need to. It's better to make fewer assumptions when relying on things
you don't control.

If the external API changes, code breaks whether you were "dynamic" or
"static". "Just change the code" is as applicable to code in either case.

That said, it's kinda weird that an API can be both unreliable enough as to
not conform to a schema, but still reliable enough to trust the data you want
to get out of it.

------
Shacklz
> I have dealt with terrible APIs that were outside of my control. When I
> worked at Timeout.com, we had to pull in data from Ticketmaster and also
> Booking.com. These APIs were inconsistent, and they would change over time.
> They also left out fields, so all fields had to be treated as an optional,
> which it made it difficult to enforce a meaningful contract.

Wait what? Why would you ever work directly with the data that you grab in
some foreign API? You map the data that you actually need into some
datastructure of your own making, that you have control over, and that hardly
ever changes - unless you want it to. So when the API changes (or even worse,
you have to exchange it for whatever reason - it's foreign after all and not
under your control), all you have to do is change the mapping process, and
voilà, you're back in your own safely typed world.

------
tabtab
One thing that annoys me about static typing is that most of the CRUD
programming I do merely martials data back and forth between the screens and
database. Only a fraction is processed, or should be processed by the
application.

Things like null-ability, base-type, and max length should be supplied by the
database and therefore not echoed in source code per the Don't-Repeat-Yourself
principle (DRY), unless a custom deviation is necessary.

If the screen validation needs to know such info, it can get a majority of it
from the database dynamically. But, our stacks don't typically do this for
unknown reasons, and thus we reinvent the field attribute wheel in app code.

I posted a question similar to this on HN recently:
[https://news.ycombinator.com/item?id=19146439](https://news.ycombinator.com/item?id=19146439)

------
CharlesColeman
All of your data structures have types, whether you declare them or not. Your
code expects things to be a certain way, and if it's not, things break. Static
typing just means that you annotate you code with your expectations so you can
get some automated error and consistency checking.

Automation is good, right?

With dynamic typing, you need to _manually_ write more unit tests to get the
same level of confidence. That's just not worth it for anything important.

~~~
YouAreGreat
> All of your data structures have types ... Static typing just means that you
> annotate ...

 _Programs_ have (static) types, data does not. Static typing removes correct
programs from the language. Try this in some ML-like language:

    
    
        let selfapply f = (f f) in
        let identity x = x in
        selfapply identity 42
    

If you transcribe this to (e.g.) Lisp, it will return the number 42. The
program is short, simple, and safe, but well-regarded static type systems
can't cope.

~~~
erik_seaberg
Any static constraint is likely to rule out good and bad programs. The
tradeoff is how irreplacable those good programs are vs. how dangerous those
bad programs are. "endofunction over either integers or endofunctions over
integers (or over endo…)" is cute but I wouldn't lose a lot of sleep from
underconstraining that domain.

------
rhinoceraptor
It's pretty obvious what you do if a field in a JSON object is optional, you
use an optional type. Any good statically typed language has that.

------
franzwong
If real world API is as chaotic as he mentioned, how can he even know the data
is trustable?

From his Java's example, I can't see how he can fix with dynamic language. He
still needs to validate the API response and throw exception even he uses
dynamic language. Unless he uses something like functional "Maybe", so he can
safely process the response.

~~~
bunderbunder
I think the crux of the issue is that the way formats like JSON and XML are
typically handled in Java forces you to validate more than you need to,
earlier than you need to.

It makes it very difficult to comply with Postel's Law.

~~~
klmr
> It makes it very difficult to comply with Postel's Law.

Not really, since “handling” doesn’t mean “throw errors”. But regardless,
Postel’s Law is often seen as a failure in hindsight. See the “Criticism”
section on its Wikipedia page. In general you _don’t_ want to comply with
Postel’s Law.

~~~
bunderbunder
Handling _shouldn 't_ mean "throw errors".

But the whole process of creating Beans or immutable POJOs and then decorating
them with annotations seems to invariably lead you down a path where, if
you're dealing with a particularly hoary API, you've either got to create a
ridiculous number of single-use DTOs to handle all the edge cases, or define a
manageable number of DTOs that unfortunately also place more stringent
requirements on the input data than are strictly necessary.

~~~
klmr
Well Java is just an incredibly bad poster child for static typing. But even
in Java you can do better by using modern sum types. Defining a “ridiculous
number of single-use DTOs” isn’t actually a problem in languages that support
this well (e.g. by allowing you to create anonymous tuples). But as you’ve
said yourself: this only applies to “pretty hoary APIs”. Why not take the
opportunity to create a better API (through a wrapper, if you have no control
over the original API)?

------
manishsharan
Dynamic language proponents make the case about programmer productivity being
better with dynamic languages. That may be the case but I have found that
integrating systems where one system is coded in a dynamically typed language
and others are written in statically typed languages is a nightmare.

------
tabtab
One thing that annoys me about static typing is that most of the CRUD
programming I do merely martials data back and forth between the screen and
database. Only a fraction is processed, or should be processed by the
application.

Things like null-ability, base-type, and max length should be supplied by the
database and therefore not echoed in source code per the Don't-Repeat-Yourself
principle (DIY). If the screen validation needs to know such info, it can get
it from the database dynamically. But, our stacks don't typically do this for
unknown reasons, and thus we reinvent the field attribute wheel in app code.

(I posted a question similar to this on HN recently:
[https://news.ycombinator.com/item?id=19146439](https://news.ycombinator.com/item?id=19146439)
)

~~~
maxxxxx
I am a big friend of static typing but I agree that there should be a better
connection between the types in the database, the types in the programming
language and the UI validation logic. Some ORMs help but I think this could be
simpler.

~~~
tabtab
ORM's have a big learning curve, especially troubleshooting, and tie your
stack to an ORM brand. But the worth of ORM's are probably another topic.

I'd like to see a data-dictionary-driven approach where most of field info
comes from a data dictionary, and only deviations need to be defined locally.
(Or perhaps create and mark dummy columns in the data dictionary that are
slated to be used for local customization.)

I suppose one could push a button and have static classes or definitions
generated for the source code from the data-dictionary, and thus still have a
statically typed system. It's still duplication of field attribute info, but
at least it's systematic duplication.

I used to use systems/tools that integrated the database, business logic, and
UI; and they reduced the amount of typing and code rework by a large amount.
The multi-layered approach may give us cross-vendor flexibility, but at the
cost of more code diddling to wire up the interfaces between all the layers.
Layer independence seems to increase duplication of field-related info. Back
then I could spend more time on requirements and analysis and less on code
wiring and re-wiring. Now we waste too much time dealing with low-level
repetitious grunt work.

------
glorioustao
There is a good talk I just watched a few days ago on this topic: Static
Versus Dynamic Typing [1][2], which listed the pros and cons of different
typing systems, using racket and ocaml as examples:

[1]
[https://courses.cs.washington.edu/courses/cse341/18wi/videos...](https://courses.cs.washington.edu/courses/cse341/18wi/videos/unit6/captioned/120-static-
vs-dynamic-one.m4v)

[2]
[https://courses.cs.washington.edu/courses/cse341/18wi/videos...](https://courses.cs.washington.edu/courses/cse341/18wi/videos/unit6/captioned/121-static-
vs-dynamic-two.m4v)

------
maxxxxx
The best I can make of these discussions is that there is no oneand true
answer. Some people prefer dynamic typing and some prefer static typing. I
myself prefer static especially while I am developing something new because I
feel I can be more aggressive in making changes because the compiler tells me
immediately what broke. But other smart people feel the other way.

So I guess both sides are right but it’s good to think about what suits you
best and then embrace that.

------
intrasight
I type with two fingers. Would that be dynamic typing? :)

~~~
tabtab
Only if you've had too much coffee.

------
coldtea
> _Why I prefer dynamic-typing over static-typing: the speed of adapting to
> change_

Funny, that's the same reason I prefer static typing.

> _In How ignorant am I, and how do I formally specify that in my code? I said
> that I liked to add run-time contracts to a function as I better understand
> it. When I first write a function, I may not know for sure how I will use
> it._

Which is irrelevant. You still know that the "customer_name" argument to it
will be a string and the "age" will be an integer, no?

> _For the programming that I do, I am often creating new architectures.
> Therefore I need dynamic typing._

Non seguitur.

> _Consider dealing with JSON in Java. Every element, however deeply nested,
> needs to be cast, and miscasting leads to errors._

Another bad argument. First, if you don't cast, and expect an integer like 55
but get a string like John, your program has an error. The difference is that
in a dynamic language your program will continue to run doing stupid things
instead of crashing in the miscast.

> _Given JSON whose structure changes (because you draw from an API which
> leaves out fields if they don’t have data for that field) your only option
> is to cast to Object, and then you have to guess your way forward, figuring
> out what the Object might be._

You can trivially have a JSON parser that returns a list of map of the 6-7
valid JSON types (maps ("objects"), floats/"integers", strings, booleans,
null, arrays).

You don't need to deserialize to specific object structure/schema as is the
default mode in some parsers, if that's what you want to avoid.

If you dislike the verbosity of getting nested elements in Java, that's a Java
thing, not a static typing thing. Heck, it's very easy in Haskell (what with
lenses and stuff).

With a language that supports Optionals and try or has a map index operator
and list/map literals, it's more like JS or Python than Java.

If you just want to extract a deeply nested element, and not care what it is,
but still use it, I'm not sure how that works.

Do you expect the object at e.g. resp["x"]["y"]["z"] to change types
randomnly?

> _Static typing does not live up to its promises. If it did live up to its
> promises, we would all use it, and the fact that we don’t all use it
> suggests how often it fails._

"Proper weight does not live up to its promises. If it did live up to its
promises, we would all be on it it, and the fact that many are obese suggests
how often it fails"

How about some uses of dynamic typing are for specific, constrained, use cases
(e.g. glueing, quick scripts) and it increasingly breaks down with larger
codebases and multi-developer projects?

Larger codebases and multi-developer projects either don't use dynamic typing
(most huge projects the world relies on, from compilers to browsers, and from
OSes, to all kinds of embedded hardware, games, desktop apps, etc, are done in
one of C/C++/Java), and others (e.g. large websites) are moving towards some
kind of types (e.g. Typescript and Flow).

~~~
pmontra
> You still know that the "customer_name" argument to it will be a string and
> the "age" will be an integer, no?

I've seen integers sent as strings and others as integers in the same JSON.
Datetimes stored as strings in three different formats by the same application
in the same column of the same table, etc. The real world is really messy.
Writing a new program is definitely quicker with a language like Ruby or
Python for me (especially Ruby.) Working with Java is like walking with a cast
on a leg.

But you know, every project and every developer is different, that's why we
are using so many different tools. The OP accounts for that in the "There are
many arguments in favor of static-typing" paragraph.

~~~
coldtea
> _I 've seen integers sent as strings and others as integers in the same
> JSON._

You still need to know what they are in each case, regardless of dynamic vs
static typing (it's a matter of whether the language has weak vs strong typing
or overly accommodating coercion).

If you get an integer value as string for example, Python won't let you add it
to another integer you got as integer. So you'll need to know what they are to
treat them accordingly in your processing even in a dynamic language.

In such case, you can also read them as a variant type on a static language,
that's eg. one of the 7 allowed types in JSON (you don't know whether a JSON
primitive might be int or string, but you know it wont be suddenly a Date type
or a Foobar instance).

------
dtech
> The widespread use of PHP, Ruby, Python and Javascript suggest that dynamic
> typing is useful. [...] If static typing lead to greater programmer
> productivity (via a reduction in bugs) then corporate America would only use
> statically-typed languages. But it doesn’t.

Yes, that is why Java and C++ are such tiny unknown little used languages

~~~
tabtab
JavaScript is mostly forced via Web "standards" and probably would fade into
oblivion if not for browser ties. Thus, I wouldn't include it in such a list.
(Not an argument for or against either typing party.)

~~~
majewsky
Same for PHP. It owes its popularity to early 2000s webhosting providers where
only PHP was supported for server-side processing.

~~~
tabtab
All languages that have been around a while have warts. One learns to work
around the rough spots.

------
eckza
Dynamic typing is great for partially implementing solutions to problems that
you don't fully understand.

This isn't always a bad thing, because sometimes "any implementation of a
product" is vastly superior to that product not existing, and works well
enough, often enough, that any edge cases can be ignored safely.

------
mmartinson
Maybe this should be called "Why I Prefer Dynamic Typing Over Java"

------
makkesk8
I love both for different reasons and pick my flavor according to the size and
complexity of the project.

Seems fair enough?

------
fromthestart
I have three personal reasons to prefer static compiled over dynamic
interpreted

1\. Refactoring. In, say, c++, you change a signature, or a member name, and
your IDE provides you with a neat, comprehensive list of errors to fix, if
you're even performing the change manually. Contrast that with python, for
instance, and I have to rely on what appear to be heuristics if I use an IDE
to propagate a change, or otherwise repeatedly hit run to change everything
that I've broken, and pray I didn't miss any code paths that'll bite me later.
Maybe I'm just not writing pythonic code, but I find it rather difficult to
maintain large codebases in python for this reason.

2\. Focus. I realized that having a constant stream from a trusted linter
makes it really easy to stay on task. I can throw out a bunch of scaffolding
and then fill in the blanks based on the constant stream of errors, pre
compilation. Sure, in pycharm I can run code analysis to get a list of
probable errors, but given the nature of dynamic languages, there'll be plenty
that's missed and plenty that isn't necessarily right, and not having a
project wide linter in real time isn't the same.

3\. Understanding APIs and library internals. There is a TON of use
information that comes for free with explicit static typing, especially for
scientific/numerical code. In python I frequently find myself having to look
up simple function use because arguments, names, and returns can be ambiguous.
In a typed language, I know exactly what goes in, what goes out, and how to
structure my data appropriately. The difference in coding speed is huge, and I
don't have to run the code nearly as often to make sure I'm doing things
right.

Why anyone would choose python for large projects eludes me!

~~~
pacala
> Why anyone would choose python for large projects eludes me!

"Mypy is an experimental optional static type checker for Python that aims to
combine the benefits of dynamic (or "duck") typing and static typing." [0]

[0] [http://mypy-lang.org/](http://mypy-lang.org/)

