Live data from Hacker News

Things I Was Wrong About: Types

v5.chriskrycho.com

291–300 of 468 posts

Re: Things I Was Wrong About: Types

#291

I think a point not often brought up is that Java takes a stance against type inference. It argues that type inference can lead to bugs, because sometimes it doesn't infer the type you meant and makes code harder to read. So explicit types it is. Also inference slows down the compiler and similarly the auto-completion. Now, I'm in the camp where I don't really think static type checkers are all that great. I judge la…

Java's stance is flat wrong as a matter of practice. I don't believe I've once had the compiler infer a wrong type in a way that led to runtime bugs. If it did, we would all be rightfully annoyed with that compiler because it would be broken.

Once more, for the back of the room: Java does not count as an example of a worthwhile type system. Good types do not increase verbosity.

Re: Things I Was Wrong About: Types

#292

I see a lot of comments on HN the last few years that just assume the dynamic vs static debate was settled at some time. It never ended. Static typing merely became trendy because dynamic typing was the trend for many years (Ruby, PHP, Python, Perl, JavaScript). Like all fashion, things that are trendy will once again become untrendy, and the cycle repeats. With that said, it's important to note that type inference i…

> I see a lot of comments on HN the last few years that just assume the dynamic vs static debate was settled at some time. It never ended. Static typing merely became trendy because dynamic typing was the trend for many years (Ruby, PHP, Python, Perl, JavaScript). Like all fashion, things that are trendy will once again become untrendy, and the cycle repeats. It’s because the ergonomics of the previous generation of…

> no serious team is going to switch from C++ to scheme for the type inference alone

and also possibly because C++ has type inference

Re: Things I Was Wrong About: Types

#293
post #191

Earlier quoted context omitted.

Let me guess. You probably worked in small teams, mostly with code you co-wrote your whole carrier. You literary compare 3 languages that you happened to use and think that all there is to know about this argument.

No, the Haskell job was in a large financial service firm with a huge investment in Haskell. Many people on the team were even experienced with GHC compiler engineering. The code base was very large and cross-org. All the other jobs have been in large ecommerce firms, again with large codebases cutting across the org, and separate pockets of “small project” development here and there. I also have many years of experi…

> The best approach I ever saw to using Haskell at scale was to severely disallow any complex type system feature, like even disallowing lensing or custom type classes. Just ruthlessly stick only to basic language features and module oriented design.

I agree. It's not unlike what you can do with reflections and other dynamic features of dynamicaly-typed languages. So it's not a problem of static typing itself. It's a problem of taking a feature of the language and strangling the code with it.

I had to do some refactors of JS code where everything was a shapeless objects with random fields, as the language doesn't even nudge the developer into considerations like keeping consistent "shapes" of data. Had similar experiences with some Python code, where I had to fight both data types fuzziness, reflective-features inventions (hello __getattr__!) and OOP over-abstracted nonsense at the same time.

One way or another, in larger teams/projects dynamic typing just doesn't scale. Type system works like a most basic documentation / developer aid / consistency encouragment, even if it is pushed into complexity nightmare.

I don't think I've ever even seen a reasonably well working large project in a dynamically-typed language...

IMO, static typing gets blamed for problems that are usually caused by OOP: complexity caused by needless abstractions (mostly inheritance taxonomies).

Re: Things I Was Wrong About: Types

#294
I've been wondering where to fit Rust in my mental taxonomy of typed languages.

Normally, types are used to statically type check a program, but with borrow checking and lifetimes, types are used to validate concurrent writes to memory locations. That's a whole different use case. One I find much more useful to be honest.

It makes me wonder actually, could you have a language whose types are dynamic to the extent of type errors, but whose write accesses are still statically type checked?

Re: Things I Was Wrong About: Types

#295

Earlier quoted context omitted.

> I see a lot of comments on HN the last few years that just assume the dynamic vs static debate was settled at some time. It never ended. Static typing merely became trendy because dynamic typing was the trend for many years (Ruby, PHP, Python, Perl, JavaScript). Like all fashion, things that are trendy will once again become untrendy, and the cycle repeats. It’s because the ergonomics of the previous generation of…

> no serious team is going to switch from C++ to scheme for the type inference alone and also possibly because C++ has type inference

C++ has only recently acquired type inference, as have most of the others in the prior generation of statically typed languages.

Re: Things I Was Wrong About: Types

#296
post #95

> Type inference: because having to write out every type, however obvious, is an incredible waste of time. Person me = new Person(); is ridiculous. let me = new Person(); may seem like a small improvement, but spread over the body of an entire program and generalized to all sorts of contexts means that type annotations become a tool you employ because they’re useful — for communicating to others, or for constraining…

Personally, I prefer the type names to be at the start of the line, so I don't need to scan to the end of the line (or guess based on a function name). But I agree, it's a waste to type it all out. So I use an intelligent IDE that reduces the repetitive typing: So typing `Person.var` gives me `Person person = new Person();` or typing `Person person = ` will suggest `new Person()` Sure, it doesn't look as appealing wh…

My personal experience with C# and Typescript has been that explicit typing like that rarely provides much value. Explicit typing tells me one thing and one thing only: GetOwner() returns a Person. But when I have questions, they almost always fall into the realm of "details about the GetOwner() method" or "details about the Person type". I honestly am struggling to think of any examples when seeing a variables type answered all of my questions.

Honestly though, this is a tooling problem. There's no reason at all that developers should need to spend time encoding information into the source code that's already known to the compiler, but devs also need to use tools that can feed the compiler's knowledge back to them. Jetbrains Rider (and their Resharper extension for Visual Studio) have a set of options called inlay hints [1] that do this exact thing. Personally I tend to keep most of the type hints turned off because they do add a lot of clutter, but the feature is absolutely invaluable for parameter name hints.

[1]: https://www.jetbrains.com/help/rider/Inline_Parameter_Name_H...

Re: Things I Was Wrong About: Types

#297

I see a lot of comments on HN the last few years that just assume the dynamic vs static debate was settled at some time. It never ended. Static typing merely became trendy because dynamic typing was the trend for many years (Ruby, PHP, Python, Perl, JavaScript). Like all fashion, things that are trendy will once again become untrendy, and the cycle repeats. With that said, it's important to note that type inference i…

I actually wish you'd written more about this, this is important and doesn't get a proper discussion. If you could come up with some code examples of the problems you hinted at it would make a beautiful blog post.

Re: Things I Was Wrong About: Types

#298
post #225

Earlier quoted context omitted.

> Types are meant to document code. Without the annotations, you can't look at code and know what is going on With the rise of VSCode IntelliSense/JetBrains code inspection, do you believe this is still true today? The programmer now has easy ahead-of-time access to inferred types that used to become available only at compile time or runtime

Should it be expected that all programmers use these text editors and have access to these tools? As someone that likes to keep his editor simple (to an extent--I'm using VIM after all), I always get frustrated when people try to introduce policies or procedures that work for them and their preferred setup, and who look at me as an obstacle because I prefer a different setup. I'm of the opinion that code should be wr…

Well, to turn around your question: should languages enforce verbosity to satisfy a vocal minority using ancient tools? I'm not going to tell you what tools to use, but if your tools can't understand let/var/auto, then that's not my problem.

Re: Things I Was Wrong About: Types

#299
post #241

Earlier quoted context omitted.

Even though I learned C/C++ in school, I started off my career with a typeless language, Perl. I loved it for its simplicity and power to quickly spool up working code, but realized it was problematic to use for large projects for many of the same reasons you state. I then switched to a Java project and was immediately frustrated with types because of how verbose it was, but after a while I came to appreciate just ho…

In the Clojure world we use clj-kondo, maps, and spec to solve these problems We get editor time feedback of mistakes with optional type hints + light inferance via clj-kondo and a data modelling system that we can export out as database schema, JSON schema etc And dynamic enough constraint system to express something like all human names must be "Tony" only on Tuesdays The same constraint that can be shared server s…

You don’t miss type systems, because you’re using something very similar.

Re: Things I Was Wrong About: Types

#300
post #293

Earlier quoted context omitted.

No, the Haskell job was in a large financial service firm with a huge investment in Haskell. Many people on the team were even experienced with GHC compiler engineering. The code base was very large and cross-org. All the other jobs have been in large ecommerce firms, again with large codebases cutting across the org, and separate pockets of “small project” development here and there. I also have many years of experi…

> The best approach I ever saw to using Haskell at scale was to severely disallow any complex type system feature, like even disallowing lensing or custom type classes. Just ruthlessly stick only to basic language features and module oriented design. I agree. It's not unlike what you can do with reflections and other dynamic features of dynamicaly-typed languages. So it's not a problem of static typing itself. It's a…

> “ IMO, static typing gets blamed for problems that are usually caused by OOP: complexity caused by needless abstractions (mostly inheritance taxonomies).”

That’s fair, since most of the issues are caused by poor attempts to create “concepts” that match a problem domain and encode them in the type system, which is a very OO mentality. But it’s not exclusive to OO, you can get the same problems in functional languages or plain module languages too if you go too far with type system designs.

But functional languages offer plenty of ways to successfully avoid it too.

Nonetheless, I still argue that safety & correctness should be treated like resources, not absolutes. Safety and correctness are things you want more or less of, depending on costs (in terms of extensibility, extra code, rigidity, difficulty to onboard new people to conceptual complexity, etc.) no different than making memory trade offs for better runtime or vice versa.

Languages should facilitate thinking of enforced correctness as a gradual concept, like gradual typing in Python, so the programmer has freedom to make these choices. Languages should not dictate one way (eg always enforcing type safety), and especially not at the cost of extra code or complexity.

> “ One way or another, in larger teams/projects dynamic typing just doesn't scale. Type system works like a most basic documentation / developer aid / consistency encouragment, even if it is pushed into complexity nightmare.”

> “I don't think I've ever even seen a reasonably well working large project in a dynamically-typed language...”

My experience is the exact opposite. I’ve never seen a large codebase that is statically typed which doesn’t turn into a complete ball of mud with overlapping type system concepts that bring extensibility and innovation to a grinding halt and cause months of delays to adjust for even the simplest changes to business requirements.

Meanwhile the two largest code bases I’ve ever worked in (one was the entire search engine implementation of a giant tech company, the other was a document editing CMS system also at a large tech company) were both 100% Python on the backend, both on the order of 500k to 1MM lines of code, and working with them was very enjoyable. Plenty of tech debt and headaches like any big enterprise codebases, but none of the “grinding halt“ - “we can’t do anything like this because our earlier brittle commitments to certain type system designs would have to be fundamentally refactored to allow it” - sorts of existential, death of velocity kind of problems.

Post reply on HN