4 ms·
The way static types can make development speed slower is not by forcing you to write the same code with extra types added in, but by forcing you to write diffe
by dan-robertson 5y ago
The way static types can make development speed slower is not by forcing you to write the same code with extra types added in, but by forcing you to write different code. In this sense it isn’t really an argument about static types vs dynamic types (imagine a language with no type checks where programs have undefined behaviour at run time on anything that would have been a static type error) but rather a statically typed language vs a dynamic language.
There are patterns or language features in dynamically typed languages which are very hard to translate to static types. I think Peter Norvig has some slides somewhere comparing OOP patterns to lisp, a more dynamic language, and that is the sort of thing I’m thinking of here. For language features, consider implementing an n-ary list map in Haskell vs Common Lisp. Or the typed equivalent of delimited continuations.
That said, research on the differences between languages is difficult and inconclusive. I would like to see more of it.
- qsort 5y ago> implementing an n-ary list map isn't that just flatMap? > typed equivalent of delimited continuations It's very clunky to do in Haskell, but conceptually they can be built on top of a monadic pipeline. In practice, the only case where statically typed languages force you to write different code is if: (a) the type system is too restrictive and dumb (no generics, awkward function types, etc). (b) you're trying to write a function that effectively returns monster types like Union[None, int, str, List[str]], which is common in dynamic languages but it's something you're not really supposed to do. I agree with your broader point, that static types can in fact slow down development, but I have a different model. Types are kind of two things at the same time: tags to tell the compiler how many bytes need to be allocated, and partial proofs of correctness of the program. The key observation of dynamic languages is that in most cases we can do without the first part: the runtime can handle that in the same way it handles memory management. I believe one of the mistakes of the original wave of dynamic typing proponents is that they kind of threw away the baby with the bathwater: the correctness part is important, and at least a form of optional typing should be provided. The real trouble is that it's not easy to conjure type systems that are both expressive and ergonomic to use for the average developer. Sufficiently advanced type systems are indistinguishable from math riddles, and in a working environment that can be frustrating.
- bopbeepboop 5y agoFor people for whom coding is an iterative, exploratory process, forcing type declarations upfront is not just slower… it’s a no-go. There’s no way to bootstrap that process for them: you’re asking for the output as an input. I think TypeScript has one of the best compromises. Also, I think people are understating how easy dynamic typing makes substitutions — everyone else is writing their class twice (interface + class) just to get the same flexibility.
- qsort 5y ago> For people for whom coding is an iterative, exploratory process, forcing type declarations upfront is not just slower... it’s a no-go. Is there any kind of programming task where it's too much to ask the programmer to know the type of the function he's writing? The only place I can imagine types being a burden is in a REPL (it's just boring to write them every time), but even then optional types like Python and TS are an unequivocal win (you're presumably going to move your code out of the notebook/repl and into proper source files at some point). > understating how easy dynamic typing makes substitutions Yeah so easy they're easily wrong. One of the worst problems of dynamic languages is that they don't have the concept of an interface, which makes it harder and not easier to write generic code. > everyone else is writing their class twice (interface + class) That's caveman Java right there. Interfaces with defaults (Java, Kotlin, even C# has something similar IIRC) can easily emulate dynamic patterns like mixins while preserving type safety and without the diamond problem.
- nicoburns 5y ago> Is there any kind of programming task where it's too much to ask the programmer to know the type of the function he's writing? I think the problem is that lots of type systems are inherently limited, so there may be patterns that you want to express that your type system simply can't, or that you have to write tons of boilerplate code to express. In languages like Java or C# that don't have Sum types, this can be as basic as "this value is a String or Integer". You have to write a class hierarchy to express this in Java. In JavaScript you simply accept a parameter and branch on `typeof value`. More powerful type systems allow you to express more patterns, but you still have to type them out. This can be done, but if you're doing exploratory work an unknown dataset then this can make the work much slower. And there be may little benefit.