Live data from Hacker News

Things I Was Wrong About: Types

v5.chriskrycho.com

41–50 of 468 posts

Re: Things I Was Wrong About: Types

#41

I code without types. My "proof", that types do not pay for themselves goes like this: Every time I encounter a bug (during coding, testing or in production) I make a note what type of bug it was and how it could have been prevented. Types are way down on the list of what could have prevented the bug. Especially for production bugs, which are the most important of course. It is so rare, that a bug could have prevente…

[deleted]

Re: Things I Was Wrong About: Types

#42

I code without types. My "proof", that types do not pay for themselves goes like this: Every time I encounter a bug (during coding, testing or in production) I make a note what type of bug it was and how it could have been prevented. Types are way down on the list of what could have prevented the bug. Especially for production bugs, which are the most important of course. It is so rare, that a bug could have prevente…

I think it takes people who do not start out 'believing in types' (I was taught by pupils of dijkstra in NL so my belief in strict-as-possible has always been quite firm) a same kind of timespan / experience as the OP; experience (very) large weak/stringy typed projects, experience them for at least a few years full time and then, when the frustration sets in, try something which is the complete opposite like Haskell…

Working on a large scala codebase, I quickly learnt that 'compile time' in one language does not always happen before 'run time' in another language.

What matters is not the phase in which the bug is found but how close in absolute time finding the big is to writing it.

Re: Things I Was Wrong About: Types

#43
Interestingly quite similar to my own progression. I think working in modern typed languages ( Rust, Swift, Typescript ) is what primarily changed my viewpoint in a way that C and Java just couldn't.

In the last year I've transitioned from full time JS development to full time TS development and have been pleasantly surprised how easy the transition was for my personal projects. Previously I had been quite adamantly against TypeScript; seeing the type system as an unnecessary level of complexity given I already structured my code in quite strict ways. In most it helped me find 1 or 2 small errors, but it certainly helps reduce the amount of time I spend verifying the behaviour of code. It definitely has its flaws, but most of them are linked to its compatibility with JS and I don't think they can be resolved unfortunately.

Re: Things I Was Wrong About: Types

#44
post #32

For my use cases, the vast majority of errors with dynamic languages boil down to being able to run scripts that have undefined variables; I'm prone to (mental) typos, so if I had a dialect of Python that failed before runtime when undeclared references exist, I could probably cut the number of iterations I need to arrive at a working script by at least half. I've never found a valid use case for allowing undefined r…

pyflakes finds these. It has virtually 0% false positives and runs extremely quickly. Run it on save or in a git commit hook. (I agree that they should be a syntax error though)

Would be very difficult (or impossible) to make this a syntax error since

exec()

Modifies the global scope

Re: Things I Was Wrong About: Types

#45

To play against the current wave, and give a contrarian pov: I'm grown up with statically typed languages from C/C++/C#/Java and later and didn't know about dynamic languages till recently. 1. Which types are we talking about? - In earlier static-typed language, the processor-based types `uint64` looked very strict, optimized the code for hardware architecture. - Having mathematically and ontological correct types is…

Dynamic languages don't do away with such types, especially uint/float, etc. They just hide it away from you. The only thing it gives you is false confidence, where one day you end up doing operations on two floats because your untyped function is supposed to get numbers in, and you're left with 36.99999999999994$ on your bank account because it wasn't explicit.

So, you write unit tests to make sure that you only pass the rights types when calling it. Doing a very bad job at just being a bad compiler.

Now, I'll agree, the languages you mentioned are absolutely horrible with types. Types in C are basically nothing more than suggestions because you end up casting const away while laughing, C++ has std::types>>, C# and Java in the past were excessively verbose and required you to type every single thing. Java/C#/C++ finally got a bit better with that with auto/var.

Kotlin types and type inference are absolutely fantastic and make your code clearer.

2/ No, you don't write fooString, fooInteger, etc. You write foo(value: Int), foo(value: String) and let the type system resolve and tell you which ones are available, rather than relying on documentation and runtime type checkings that are plain bad. And if it makes sense, you can even declare them as extension functions, Int.foo()

3/ Yes you do. Unless you explicitly opt in to null values or you're using platform types, like calling code from Java with @Nullable/@NotNull annotation

4/ Nobody calls for generalizations all the time. You're not supposed to write generics for all your methods.

5/ Explicit definitions are uglier compared to duck typing and just going "yolo it has a .frobnicate() method that means I can call it" ? I agree that over time, they might become unyieldy, but once again, with a proper typechecker and type inference, they're a blessing. Using kotlin and writing

    when(this) { 
        is Frobnicator -> this::frobnicate
        is Zobtrinatex -> this::zobritnex
        else -> this@caller::defaultBehavior
    }.invoke()
gives you safety, checks that you're not mixing return types.

6, 7/ Depends. I've written some true abominations, yes. Typecript gets ugly when the libraries you're using abuse types horribly (React used to be absolute trash for that, declaring props was terrible). But then, you pay the cost once (at declaration), and get benefits through your entire app.

Don't write generics for a component, unless it makes sense. If you're exposing a Container and you can access the data inside and you require its type, okay, it makes sense. But don't do a Page, that's dumb.

Generics are a tool. Like C tells you to not abuse (void*), don't abuse generics. Use them with parcimony and your code will be better, give you more guarantess and literally write itself if you've got a competent IDE.

Re: Things I Was Wrong About: Types

#46
post #19

I once told a JavaScript guru colleague of mine that I was spending my free time dabbling in Haskell. His response was 'lol, why would you do that?'. His point was that spending time learning things that you're not going to be using directly any time soon is a waste of time. My point was (and still is), that learning such things opens up a completely new way of thinking about problems and potential solutions.

"Never learn anything you don't see immediate use of".

Such short term thinking could explain why dynamic typing is so appealing: simpler implementations, more possibilities than most mainstream static type systems, while requiring basically no learning at all.

Re: Things I Was Wrong About: Types

#47

I don't really see most of my code being improved that much by types and I also see a lot of extra complexity that people in the sphere I am (indie games) have to deal with when using typed languages. It just doesn't seem worth it. When you have to spend a lot of time fighting your language, and handling numerous extra concepts that don't exist in an untyped language because they don't need to, it feels like the peop…

Maybe it's a case of problem complexity. I think of types as a tool to help cope with certain things. If you're building a garden wall you probably don't need CAD. For a 747, you probably do. Though aircraft predate CAD so it's clearly not impossible to do without.

I dislike types in 30 lines of python because they're unnecessary complexity. I like them in 10000 lines of c++ because they do some of the thinking on my behalf.

Re: Things I Was Wrong About: Types

#48

I don't really see most of my code being improved that much by types and I also see a lot of extra complexity that people in the sphere I am (indie games) have to deal with when using typed languages. It just doesn't seem worth it. When you have to spend a lot of time fighting your language, and handling numerous extra concepts that don't exist in an untyped language because they don't need to, it feels like the peop…

What languages have you worked with? As per the OP, there are certain languages where types are much more expressive and add something to the programming experience.

Learning haskell changed a lot about the way I think about programs and that is even as someone who primarily writes in java.

Re: Things I Was Wrong About: Types

#49
I was a statically typed fanboy for most of my early career. C# and later F# were my daily drivers and still hold a fond place in my heart. More recently, I learned TypeScript and a bit of Haskell and Rust.

However, I think dynamic languages have their place. Most of my server side code involves parsing one string and transforming it into another (JSON to SQL or the like). Something like Clojure spec is really, really useful for this, and beyond that the remaining code doesn’t really materially benefit from static types.

At any rate for my typical web application, I now prefer dynamic languages, which is something I never thought I’d say.

One last thought: soundness is just one variable to optimize for, and it’s not as important as I once thought. For most parts of my application, rough edges are not a big deal. For the really important stuff (like payments), I always write tests and also do a fair amount of manual testing. And for that stuff, the bugs are almost always logic bugs that types wouldn’t have caught.

Re: Things I Was Wrong About: Types

#50

I don't really see most of my code being improved that much by types and I also see a lot of extra complexity that people in the sphere I am (indie games) have to deal with when using typed languages. It just doesn't seem worth it. When you have to spend a lot of time fighting your language, and handling numerous extra concepts that don't exist in an untyped language because they don't need to, it feels like the peop…

Aren't you falling into the same trap that the post explains? That there are nuances around when types are useful and not useful? An indie game developer might spend a lot of time designing methods of gameplay and artwork for the game, but that doesn't mean that types should go out the window for all levels of programming.

Wouldn't it be better to approach this by which problem we are trying to solve? A script that is run during development, where resources are unconstrained, and stability is not an issue, should absolutely value the time it takes to develop and maintain the script. So using a typed language may not be useful here. A situation where small optimizations make large improvements might benefit from a typed language, maybe a physics engine of a game intended for multiple platforms?

In the OP, the author approaches it from a "systems" perspective, that when you need either of the 3 scenarios, then you might consider using types. Type inference, Sum/tagged union types, and Soundness, which I think could easily apply to certain areas of game development. Ignoring the nuance around the issue, and being dogmatic that all scenarios in a given field do not need types is ignoring that what we're really doing is writing in languages that need to be interpreted by both humans and machines.

Post reply on HN