Hacker News new | ask | show | jobs
by falcolas 3225 days ago
This has not been my experience with strongly and statically typed systems. The biggest problem is the coding is not fast; especially if you make a change that requires "shaking the tree". Turnaround to me is as much about the code you write as it is the results you get from that code.

For example, I start my program thinking that I need a duck for all of my various waterfowl systems. However, four days into the coding process, I realize I need to allow for an ugly duckling to be passed around as well. Now I have four days worth of code to comb through and re-type. I could just use a refactoring tool to change all of the existing 'duck' types, but some of that code actually does need a duck, and won't work with an ugly duckling. So I have to come up with a more abstract type which can encompass both an ugly duckling and a duck, and refactor that into my program.

Eventually my code will be correct again, at least until I realize that a platypus needs to be included into my now-renamed aquatic_ecosystem as well.

The nice thing about strong and dynamically typed systems - I just start treating the incoming object as what I need it to be. No error chasing, no wading through four days worth of code. Yes, I'm more likely to have incorrect code, and it's probably going to show up while the code is running, and not before. Many times, that's a tradeoff I'm willing to accept.

My ideal system? I don't think at all about types. I just write code, and the (still fast) compiler will tell me when I'm passing something that doesn't quack to a function which expects quacks.

3 comments

A lot of people who stick with expressive static type systems find the process of fixing type errors quite enjoyable. I really like the experience -- I can go really fast confidently.

GHC does let you defer type errors until runtime but I never want to...

>A lot of people who stick with expressive static type systems find the process of fixing type errors quite enjoyable. I really like the experience

So maybe liking developing in them depends on having that personality trait? (or typeclass if you prefer, pun intended).

Maybe, I don't know. The psychology of programming language preference seems like a pretty interesting topic. Enjoying programming at all seems like it might depend on some quirks; I don't know if there's a significant difference to make you inherently prefer fixing type errors over fixing unit tests or whatever.
> find the process of fixing type errors quite enjoyable

I, myself, would rather be creating new functionality than fixing a litany of type errors. In fact, I'd rather go to a meeting than change several hundred instances of 'duck' to 'waterfowl', 'avian', and 'ugly_duck' (knowing that I'll probably have to go back and change it again later).

Different strokes for different folks, I guess.

Well... but usually those are actual errors that you would need to fix anyway.
Why would generalizing a type definition make an error?
In the places you use a specific concrete type you presumably did so for a reason, and now need to think about how the type change affects it. The parts of your code that are generic should have been written to be generic, and the parts where the type can be inferred from the lower-level functions involved should have left the type to be inferred from the lower-level functions involved.
What you are saying is like the people that would "rather write new functionality than tests"... Like, yeah, that would be nice, if you were able to write 100% bug free code, but you aren't so your tests are actually important in the goal towards a working product.
Well, I'd actually rather write unit tests than shake out type trees too, so no, the two statements aren't equivalent.

Why? Unit tests also check a lot more than the types being passed around, so they are a lot more useful in the long run. There are some type systems where this is perhaps not the case, but they certainly aren't the majority. The majority is "so do I go with a float or a double" or "I have to cast this int to an uint64 for this one function".

So use a good type system rather than a bad one. I mean if your point is "some popular type systems are so bad that they're worse than no type system at all" then I agree with you, but don't tar all type systems with that brush.
A language that is exceedingly popular and has a great type system and has great tooling for tests is Rust. When using Rust, it’s quite evident why you have to use both and not one or the other.

And when it comes down to it, in theory, proofs are better than tests, and Id say no one would disagree, and in practice, types are proof. Unfortunately, you can’t use types for proving everything, so that is where tests comes in.

Imagine a platform where you could indeed prove everything. I believe, but am not sure, that there is some languages that do this, like Idris.

Nowadays I feel that experience with some type system at least as powerful as Haskell's is required to criticize static typing... Well, of course, you can criticize it without such experience, but that only serves to look foolish when you complain about stuff that is solved for a decade.

Are you really complaining about lack of generics?

Come back to me when the most used programming languages have a type system like Haskell's. Then we can talk about the benefits of static typing over dynamic typing. Until then, static typing is mostly "expected a HashMap<i32, u64>, got a HashMap<i64, u64>" or other pedantic stuff like that which is only really meaningful to the compiler.
> Come back to me when the most used programming languages have a type system like Haskell's.

We never get there if the conversation about types is dominated by people who have only used Java-like type systems. Even ignoring that, demanding that powerful type systems be ubiquitous before discussing their benefits is a complete non sequitur. There's no excuse for ignorance, here.

You are confusing "static typing" with "algebraic typing", which is related but different.
> Yes, I'm more likely to have incorrect code, and it's probably going to show up while the code is running, and not before. Many times, that's a tradeoff I'm willing to accept.

I find the runtime errors I get from dynamically typed languages typically much clearer (and easier to debug) than many compile-time errors from C++ or Haskell.

I do like C's static type systems because it's needed for efficiency at runtime. (Re-) Compiling C can be close to dynamic execution for not-too-large applications. Often also C++ is needed for easy to use containers, but as some else said here it's really a tradeoff because compiles are much slower (I don't know why that is, but part may be because containers are re-compiled for every compilation unit that uses them).

And the overwhelming majority of bugs really appear on the first run of the dynamically typed code. The bugs that remain would have very often been also bugs with statically typed languages, since these are so ridiculously bad at expressing the simple invariants... They get unusable much faster than they get good at helping with bug-discovery.