Live data from Hacker News

Diminishing returns of static typing

blog.merovius.de

251–260 of 632 posts

Re: Diminishing returns of static typing

#251
It's far more useful to implement validation and type checking via introspection and interrogation of type, quantity, structure, size, or some other property at runtime in a dynamic programming language than to pedantically have to type all your variables. Most interesting types are far from the basics of different size numbers, string and objects anyway. It's better to trade a fast and quick runtime type error than a lengthy compile-time type checking process, because less code needs to be evaluated at run-time to expose the type error. See the "Worse is better" principle in language design.

Wouldn't it be great if we can use the computer to figure out what the types should be by a runtime evaluation of the code and save precious human time for things only humans can do?

I don't have to think or decorate my speech with types of noun, verb, pronoun, adjective etc. when I speak, but I'm still able to communicate very effectively, because your brain is automatically adding the correct type information based on context that helps you understand what I'm saying, even with words that have multiple types. Granted, natural language is different than programming language but there was once a trend to try and make programming languages more like human language, not less so.

Re: Diminishing returns of static typing

#253
post #237

Earlier quoted context omitted.

Sure, but to bring it back to the original question, the fact that you can trivially distinguish floating point from word types already means statically typed languages are easier to optimize than dynamically typed languages for numerical programs. And there are all sorts of optimizations like this that simply aren't available to dynamically typed languages. Tracing JIT can only take you so far.

OK, but that wasn't the original question. (There are also all sorts of optimizations that can't be done statically, so I guess there's that.)

The original question asked whether static typing is needed when maximal performance is required. If we understand "maximal" to mean literally, "no more performance can possibly be squeezed out", then it simply is. Static typing might not be sufficient for this case, but it is necessary.

Re: Diminishing returns of static typing

#254

Earlier quoted context omitted.

Does it work in the presence and (ab)use of dynamic features? (e.g., when you have lots of decorated functions) Or is it just a best effort thing? (i.e., only works when your code would actually be expressible in a static way)

This is a continuum... in many statically typed languages there are regularly used paths that lead outside the realm of the language-defined type system as well. Consider dynamic class loading in Java, dlopen / reinterpret_cast in C++ etc.

> This is a continuum.

It is not. A language feature is either amenable to static analysis (not necessarily type checking) or it is not.

> Consider dynamic class loading in Java, dlopen / reinterpret_cast in C++ etc.

This actually emphasizes my point. Features that are not amenable to static analysis are problematic for tooling.

Re: Diminishing returns of static typing

#255

Earlier quoted context omitted.

I'm so happy to see the pendulum swing the other way, because when JavaScript was becoming popular, and Ruby and Python had a popularity renaissance (around mid to late 2000s), I had a lot of online arguments about the value of static typing. People were complaining about static typing for the dumbest reasons (it's too 'wordy'). It started as a backlash against old-school enterprise Java development (which was fair,…

> Thank God people are coming to their senses. There are no senses to come to. Static and dynamic typing each have their own benefits, and there are genuine tradeoffs to choosing one over the other. That we are even having this debate in 2017 shows that the world of typing is not a "solved problem" and there are still good reasons to use one over the other for various reasons.

>Static and dynamic typing each have their own benefits,

I struggle to think of any benefits of dynamic typing on a reasonably sized code-base (e.g. 50k+ LOC).

Re: Diminishing returns of static typing

#256
post #200

What amuses me in all "static typing versus..." discussions, is that it usually it is the comparison between two camps: Camp A: Languages with mediocre static typing facilities, for example: -- C (weakly typed) -- C++ (weakly typed in parts, plus over-complicated type features) -- TypeScript (the runtime is weakly typed, because it's Javascript all the way down) Camp B: Languages with mediocre dynamic typing faciliti…

Perhaps it's because the languages you mentioned barely register in statistics(aside from Clojure maybe). Maybe it's simply hard to have both a good type system and a friendly learning curve?

>friendly learning curve

To be honest, i love Common Lisp, it might be the most powerful programming language out there, but it's not easy to learn at all. In part because, being a truly multi-paradigm language, you should better make sure you are well versed in most programming paradigms first, otherwise you won't leverage the full power of Lisp. Not to mention the paradigm of meta-programming and DSLs, something that is usually new to programmers foreign to Lisp.

However, languages like Clojure and Smalltalk can be rather easy to learn, and they are fairly powerful.

Smalltalk was designed to be taught to kids!!

Re: Diminishing returns of static typing

#257

Earlier quoted context omitted.

At a place I worked at once, it was "use Microsoft for everything". So yeah.

Yeah but that's more a matter of the criteria to decide on the right tool. Nobody would say "I intend to use the wrong tool for the job."

> Nobody would say "I intend to use the wrong tool for the job."

...but there's plenty of sales charlatans out there who will say "I intend to get the manager of that IT dept to make its developers use my tool for the job, and I don't care if my tool is the right one or the wrong one."

Re: Diminishing returns of static typing

#258

Earlier quoted context omitted.

PyCharm gets it right 99% of the time. That 1% is hardly worth switching the a different language.

IME, add that 1% to another "1% isn't worth switching" argument with some other Python deficiency and then to another and so on, and reasonable case for choosing other languages can be made. I'm not saying Python should be abandoned for all projects, but we should be careful with "but if we make everyone use this one tool, and this one tool does it right almost all of the time, so we're good" arguments.

I'm reading Type-Driven Development with Idris right now exactly because I don't think Python is always the correct choice. I just don't find slight improvements in IDE features to be relevant.

Re: Diminishing returns of static typing

#259

Earlier quoted context omitted.

> Thank God people are coming to their senses. There are no senses to come to. Static and dynamic typing each have their own benefits, and there are genuine tradeoffs to choosing one over the other. That we are even having this debate in 2017 shows that the world of typing is not a "solved problem" and there are still good reasons to use one over the other for various reasons.

>Static and dynamic typing each have their own benefits, I struggle to think of any benefits of dynamic typing on a reasonably sized code-base (e.g. 50k+ LOC).

Cheap and plentiful dev talent. Grab any random guy (and at these shops it's always guys) off the street and bang you've got a python dev.

There's always going to be an agility multiplier so long as VC is flowing and getting an mvp and a high head count is worth more than any kind of sustainable product.

Re: Diminishing returns of static typing

#260

Static typing prevents bugs in code to the degree that the programmer can correctly encode the desired behavior of the program into the type system. Relatively little behavior can be encoded in inexpressive type systems, so there's a lot of room for bugs that have nothing to do with types. A lot more behavior (e.g. the sorts of invariants mentioned in agentultra's top level comment) can be encoded in a more expressiv…

> I already have a set of practices that usually prevent relatively simple type mismatches Care to share those practices? I also primarily work (this year, at least) in dynamically typed languages.

I think it depends on language and context a lot so I can only give some vauge advice. A lot of the idea is to write code that only does the one thing you know you need it to do, does it very simply and fails very obviously when it's not used correctly. In some cases your instinct is to make things as generic as possible at the first pass. Preemptive abstraction pays off more in statically typed languages, in my experience, because it saves you the time of refactoring a type system in place if you turn out to need flexibility later. But in dynamic languages it can introduce complexity that hides bugs.

Simple type-level errors come up the most when you have types that are easily conflated. That tends to happen when you have functions that accept more than one type of thing or output more than one type of thing - avoid that. Avoid polymorphism and OOP patterns that set up a complicated type hierarchy or override methods - you don't want any instance where you end up with something that looks a lot like one type of thing but isn't. Type hierarchies can often be factored out into behaviors provided by modules that supply functions that operate on plain data structures. For variables and parameters, stick to really simple types to whatever degree it's possible, e.g. language primitives, plain old data-container objects and "maybe" types (e.g. things that could be a primitive or null) when absolutely necessary (and check them whenever you might have one). Use union types extremely sparingly. Assignment/creation bottlenecks are useful: try to have only one source for objects of a certain type that always constructs them the same way (so you don't end up with missing fields).

A lot of programmers coming from a language with a stronger type system (especially when transitioning from OOP languages to functional or hybrid languages) tend to be nervous about writing functions without a guarantee about what kind of inputs they'll see, so they try to compensate for the lack of type safety by building functions that can cope with whatever is thrown at them. The idea is that this makes the function more robust but ironically, this tends to make bugs a lot harder to track down. In my experience it's better to write functions with specific expectations about their input that fast-fail if those aren't met, instead of trying to recover in some way - garbage-in-exceptions-out is better than garbage-in-garbage-out. If you send the wrong kind of thing to a function, you want it to throw an error then and there, and you'll likely catch it the first time you test that code.

A lot of the idea of this kind of advice is to shift the work that would be done by the compiler's type system to the very first pass of testing - if your program is basically a bunch of functions that only take one sort of thing in each argument slot, only emit one sort of thing as a result and fail fast when those expectations are violated, you'll typically see runtime type errors the first time those functions get executed, which is a lot like seeing them at compile time.

Post reply on HN