4 ms·
While on the subject of static typing, is anyone aware of any good argument against it?
by rualca 6y ago
While on the subject of static typing, is anyone aware of any good argument against it?
- vardaro 6y agoBarrier for entry for new developers. I think JavaScript's huge success in the last decade is primarily attributed to the plug-and-play dependency ecosystem and dynamic typing Beyond that, not much
- rualca 6y ago> Barrier for entry for new developers. What's the barrier exactly? And keep in mind typescript's growing popularity and momentum, which states quite clearly that the javascript community is more than willing to tolerate added layers of complexity just to be able to use static typing.
- Clubber 6y agoI think it being first to market in a browser was probably the most important aspect of it being so successful. Microsoft tried VBScript and it got some take-up , but it was ultimately too late. It was also free. At the time, IDE's and compilers were pretty expensive in the Windows world.
- oddity 6y agoStatic typing inherently requires you to prove things about your program, but there are many contexts where you don't fully know the properties you'd like to prove, or the type system isn't sufficiently powerful to express the properties that are actually interesting. In these contexts (live coding, prototyping, quick throwaway scripts, etc...) static typing can be more of a hindrance than an asset. However, once you pivot into needing maintainable software with more guarantees about correctness, static typing becomes extremely important. The problem for python is that it originated as a language for less-formal programs but cultural and labor-market forces resulted in those programs getting shipped as production software. It's not so elegant when it's being bolted on, and there's a large subset of python developers today who genuinely don't need it.
- rualca 6y ago> Static typing inherently requires you to prove things about your program Doesn't it just require you to express the interface you're already using and expecting to use? > The problem for python is that it originated as a language for less-formal programs but cultural and labor-market forces resulted in those programs getting shipped as production software. That's not a problem at all, as Python's type annotations and mypy clearly demonstrate.
- oddity 6y agoThat's one way to view it, yes. And with unsound type systems, generally, that's the workflow. Your program is a proof that the interface can be implemented. The challenge is that sometimes the interface doesn't express much that's interesting and, with more sound type systems, your program might be correct but inexpressible. > That's not a problem at all, as Python's type annotations and mypy clearly demonstrate Gradual/Optional typing is a great way to solve the split needs, but I was making the argument for why people might not want to use static typing in python even though it's available.
- rualca 6y ago> Gradual/Optional typing is a great way to solve the split needs, but I was making the argument for why people might not want to use static typing in python even though it's available. Forgive me for asking, but did you made any point that provides any basis for refusing to use static typing? I mean, failing to meet an artificial and unmettable and largely subjective bar regarding academic purity of type system implementations is not a valid argument. The average pythonista does not care about convoluted type theories if all he does is pass a string or int to a function, and doesn't want his program to blow up if they pass by mistake an int instead of a string.
- bko 6y ago> Doesn't it just require you to express the interface you're already using and expecting to use? Depends on the type system. Some type systems have a lot of ceremony around types and force you into contrived abstractions. For instance, in Scala, if you wanted to have a function that can print a name of an animal or person, you could overload the function, create a "nameable" trait and have both Person and Animal implement it, or create a union type. In typescript you could just write sayHello(thing: {name: string}) { ... } or a union type sayHello(thing: Person | Animal) or even Pick out a group of parameters of both Person and Animal sayHello(thing: Pick<Person | Animal, "name">) Same with Omit Types in typescript are incredibly flexible and useful despite being discarded at compile time. I hope python goes down this route.
- yen223 6y agoI've used a variety of languages in my career, both statically-typed and dynamically-typed[0]. I generally like both. Here's my take against static typing: 1. Static type checkers increase compile times. This is an acceptable tradeoff if they can catch bugs at compile time, but not if they still still allow bugs to occur at runtime. 2. If you're building a system which has to interact with other systems a lot, static types can be a hindrance if your static type system and their type system don't agree on fundamental things like how data should be modelled. This manifests itself as things like the Object-Relational Impedance Mismatch[1]. You would end up writing a lot (A LOT) of code to bridge the two, and in general, more code = more bugs. 3. Static type checkers can have bugs or quirky behaviour. This can lead to a lot of wasted time, and/or inelegant workarounds that makes your code less understandable (and therefore, more likely to have bugs in the future). This is one that I encountered recently: https://typelevel.org/blog/2018/05/09/product-with-serializable.html https://typelevel.org/blog/2018/05/09/product-with-serializa... 4. It's surprisingly hard to find any research that can demonstrate that static type checkers actually lead to fewer bugs. [0] Python, Clojure for dynamically-typed languages, Typescript and Scala for statically-typed languages [1] https://en.wikipedia.org/wiki/Object%E2%80%93relational_impedance_mismatch https://en.wikipedia.org/wiki/Object%E2%80%93relational_impe...
- rualca 6y ago> 1. Static type checkers increase compile times. It should be noted that this potential impact on compile times amount to a few seconds. > 2. If you're building a system which has to interact with other systems a lot, static types can be a hindrance if your static type system and their type system don't agree on fundamental things like how data should be modelled. I fail to understand how failing to comply with a contract is a type checking problem, and one which goes away if you no longer perform validations. > 3. Static type checkers can have bugs or quirky behaviour. This can lead to a lot of wasted time, and/or inelegant workarounds that makes your code less understandable (and therefore, more likely to have bugs in the future). I'm not sure if your example is valid, as in your blog you quite openly state that the root cause of your bug was your failure to specify the right return type. You can't really fault a system by complying with the definition you've provided. > 4. It's surprisingly hard to find any research that can demonstrate that static type checkers actually lead to fewer bugs. A quick search in Google Scholar for "static type bugs" popped about 4k search hits, the first of which is an article on quantifying detectable bugs on javascript which states that switching to typescript allowed 15% of public bugs to be detected.
- schwartzworld 6y agoHonestly, my experience with Typescript has been less than ideal. I would rather not have static typing than have static typing jammed on top of a dynamically typed language. Compared to the type system of rust or elm, TS is hot garbage.
- dhucerbin 6y agoI think arguments can be only made against specific type systems (implementation). If I could express my domain constraints in type system I would happily use it, but often this is not possible or it’s very hard. Then you need to decide if it’s worth the trouble. Maybe your runtime code gets complicated to conform to type systems and hinders readability? Or maybe compiler can prove very little about your code (old example with type of function for reversing a list)?
- deleted 6y ago[deleted]
- deleted 6y ago[deleted]
- neolog 6y agoStatic typing is normally about "the types are known at compile time". With modern JIT compilers, the difference between compile time and run time isn't so clear, so the question loses its meaning.
- tobiasSoftware 6y agoI'm designing a programming language that started with the goal of being similar to a statically typed version of Python. What I've discovered is that by far the best argument against static typing is datastructure design. A dynamically typed language's datastructures don't need to know anything about what they store. This is typically done behind the scenes as storing pointers to the data instead of the data itself, and then the data can be dynamically cast to the appropriate type when used. The result is that a list is simply a list and feels very natural for a programmer to interact with. On the other hand, a statically typed language's datastructures have to make one of three ugly compromises. Java uses Generics, where the type is erased, causing interactions with datastructures to act dynamically typed while everything else in the language is statically typed. While this sounds as simple as dynamically typed languages, in reality the border between the statically typed and dynamically typed parts of the code are complex with odd syntax such as "<T extends Comparable<T>>" or "<? extends T>". C++ uses Templates, where special functions called templates have extra syntax for the caller to specify what type is used. The template function is then copy-pasted behind the scenes with its variable type replaced with the specified type. This maintains the static typing but at a high cost as it leads to strange, complex syntax and ugly, hard to read errors. Finally, C uses manual memory allocation. This prevents data structure libraries that easily work with multiple datatypes from being able to be created. However, C uses an interesting trick to provide support for simple arrays: the size of the array is the size of the element times the number of elements, and the memory address of index i is the base pointer of the array plus i times the size of the element. Using these mathematical sleights of hand, C can appear to provide datastructure support, but in reality this support only extends to arrays of a fixed size. I'm sure there are plenty of ways around this to actual build complex datastructures in C, but in my opinion none of those ways are nearly as friendly as dynamic typing, generics, or templates.
- Gibbon1 6y agoSmall comment, C# also has generics, but unlike Java doesn't do type erasure. I remember that because of an essay on type erasure by a CS professor that researches language design. His comment is a sign your your language and compiler are well designed is the ability to do type erasure. And what's really important is to not do type erasure.
- closeparen 6y agoA mix of Rich Hickey talks and my own experiences. Possibly just Rich Hickey. a) You're going to write unit tests anyway. Type errors are not especially likely to slip through good testing, nor are they the most interesting kinds of bugs that can slip through good testing. b) Null is a value of the wrong type, and most type systems let that one through. c) Values have a habit of coming from outside the boundaries of the type system. Sockets, files, etc. You will always have to deal with (or reject) arbitrarily wacky inputs at runtime. c) Static typing leads programmers to overspecify data and make programs unnecessarily brittle. Many struct/record types could be replaced with maps + runtime checking that the appropriate keys are present, while letting other keys pass through. Then our programs would not so often require modification to support new uses. (TBH I think Go's type system, of all things, takes a decent step toward this one with its implicitly satisfied interfaces).
- aszen 6y agoI think many of these points are valid for a type system like Java's but they hold less ground for other languages a. Yes tests are still needed but you need far less of them thanks to type you can focus testing on the critical logic instead of validating input and output types. b. Solved issue in modern pl, even php considers null a value of separate type. c. This is a good point, but with values coming from outside the system, I'm forced to do run time checking because of types which makes the whole program more less error prone. d. This is a very valid point for most mainstream typed programming languages, row polymorphism is one technique which helps here. Every function only specifies the key's it needs to work so it can receive arbitrary records. I believe this is also possible in python by typing out dict keys and values.
- closeparen 6y agoYes, I am looking forward to better type systems (and community habits/norms around those type systems) solving most of these problems. In particular, I would like to see the community gain enough faith in the safety guarantees of more advance type systems to back off of blind line coverage mandates. But today we have Go and Java's type systems, and the same coverage mandates as Python and Node. In particular I would like to see the compiler enforce that you either return a legitimate value or raise an exception, and that the caller does not go down a path that calls for a value if an exception was raised. I hate that a reference can get 10 miles away before you discover there's no data there, and it being wrapped in Option or ? or a technically-not-null zero value doesn't mitigate that.