

Dynamic type systems aren't even simpler
source link: https://hisham.hm/2020/01/20/dynamic-type-systems-arent-even-simpler/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

đ Dynamic type systems arenât even simpler
Alexis King just published a great blog post titled âNo, dynamic type systems are not inherently more openâ.
That reminded me of the talk I gave last year at FOSDEM, titled âMinimalism versus typesâ, where I advocated for static types from a slightly different angle. I tried to convince people that types in dynamically-typed programs are often more complicated than people realize. And often more complicated than in typical statically-typed languages.
People often say the opposite, that static type systems are more complicated, and dynamically-typed languages are simpler. At the surface level, this seems true: in a dynamic world you just go merrily declaring variables, assigning values and doing things with them, without ever having to write down any types, no matter how trivial or complex they are. Things canât get any simpler in the typing department than âdoing nothingâ, right?
Well, types are nothing more than the shapes and allowed behaviors of your data. So itâs not like you donât have shapes and behaviors in any program, regardless of the language⊠so, you have types, whether you write them or not. They are there, even in assembly language, even if at a conceptual level, as the sets of âvalid valuesâ your program can manipulate. And you have to think about them, and they have to make sense, and they have to do the right thing. So, in short, in a correct dynamically-typed program the types need to be just as correct as they are in a statically-typed one (or else youâll get runtime errors).
In other words, the types are there, but you have to run the type checker in your head. And you know whatâs funny? When people donât write down the types, they often end up with types that are often more complicated than the types from people who do write them. The complexity just goes under the radar, so it piles up.
One day you open that module which you havenât touched in six months, and you see a function call where the third argument is null. You need to remember what kinds of variables you can pass to that third argument, or read the whole source code to figure it out. You follow through the code to see all places that third argument is used and realize the accepted type of the third argument depends on what you give to the second argument. Congratulations, youâre dealing with a dependent type, which means youâve just surpassed Haskell in terms of type system complexity. Compilers that deal with this kind of type system are so complex they are effectively proof assistants (and are at the forefront of programming language research), and here you are dealing with those data types with your brain (and your faith in your ability to come up with sufficient tests) alone.
Given that there is no mechanical type checker to prescribe what is expressible, and that the dynamic runtime will accept anything as long as the program doesnât crash, when doing typechecking in your head you essentially have the worldâs most powerful and complicated type checker at your disposal. And once you start making use of this power, you end up dealing with the worldâs most complicated type system.
And when you give people expressive power, they use it. In my experience, people go wild constructing complicated structures in dynamic languages that they normally wouldnât in static languages. Itâs not that static languages are less powerful (Turing equivalence, blah blah), but they make the things youâre doing more obvious to you (Alexisâs post has some great examples). In a dynamically-typed program people are all to keen to make variables and data structures perform double or triple duty (âthis is a X but also a Y under circumstances Zâ), but when they have to write down what theyâre doing as types, itâs like a little conscience check, and they think twice before creating a more complex type for something that could be described in a simpler way (simple example: theyâll probably make two plain functions instead of making one function that takes a string argument that changes the behavior of other arguments). Static types nudge you towards simpler, less âcleverâ solutions (and we all know what kind of solution is more maintainable in the long run).
But okay, letâs assume we avoid âcleverâ and pick the same solutions in either. Writing the same program in a static or a dynamic language to process the same data in the same way, you will end up with values of roughly the same types in both. The fact that the variables have static types or not does not change that.
âBut in a dynamic language I donât have to write the types! Itâs less work!â
âNot having toâ write types but having to think about them anyway is like doing math ânot having toâ write anything down and doing all calculations in your head. How is it an advantage to not use pen and paper to track down your train of thought as you do a complex calculation, and instead be restricted to do it only in your head? And how is an advantage to not have a mechanical tool â like a calculator, which can actually compute the things you wrote down â to check whether what you wrote with pen and paper makes sense?
Iâm lazy, so I hate doing any math in my head. Iâll take writing things down and have a machine check it for me any day of the week. Why wouldnât I want the same when programming? Thatâs what computers are for, right? To save us from computing things in our head. So Iâll write my types, and have the compiler check whether they make sense, thank you very much. Itâs less work.
Follow
đŠ Twitter âȘ đ Mastodon âȘ RSS - posts in English, posts em PortuguĂȘs, todos / all
Latest posts
Search
Admin area
Recommend
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK