I think what you're talking about here is static types getting in your way, not just types getting in your way.
Strong/weak types and dynamic/static types are really two different spectrums. People conflate strong types with static types and weak types with dynamic types, but they aren't really the same thing.
Static/dynamic just has to do with whether the types are checked at compile time or run time. Examples: Static: C, Haskell. Dynamic: Javascript, Python.
Weak/strong has to do with what kinds of checks the type system does. A strong type system is capable of checking a lot of different things for you. Static types are often stronger, but not always: for example, C is statically typed but its type system checks hardly anything: int* + int is perfectly valid. A list of programming languages from weakest-typed to strongest-typed might look something like: JavaScript, C, C++, Common Lisp, Perl, Scheme, Ruby, Python, Java, C#, OCaml, Haskell.
Static types are nice for projects which will grow large and where bugs are a big problem, but I think for the average HN person, static types aren't really necessary.
Strong types, on the other hand, are extremely useful. Even in a dynamically typed language, they aid in debugging a lot, because type errors occur much closer to where they're caused. In Python, for example, `"foo" + 42` immediately fails. But in JavaScript, you don't get an error until much later, perhaps when your webpage is mysteriously displaying "foo42".
Of course, there's a small cost to strong types: in the case where I actually do want to append a number to a string, I have to do `"foo" + str(42)`. But I think people tend to overstate this cost because it's visible. But if you look at the big picture, typing five extra characters takes a lot less time than debugging almost anything.
Also, among statically typed languages there is a significant difference between languages which make the programmer write out all the types and languages which offer type inference. I think most of the comments about types "getting in the way" come from experience with the former (C, C++, Java, C#). In a strongly- and statically-typed language with type inference (such as Haskell) even moderately complex programs can be written without any type annotations. The result looks a lot like a dynamically-typed program, but static types are still inferred and checked for consistency at compile-time. For example, this is a perfectly valid Haskell program:
import Control.Monad
import Control.Monad.Tardis
import System.Random
-- A solution for the Trapping Rain Water problem employing
-- the bidirectional state ("Tardis") monad.
-- https://www.geeksforgeeks.org/trapping-rain-water/
volume hs = sum . flip evalTardis (0, 0) . flip traverse hs $ \h -> do
x <- min <$> getPast <*> getFuture
modifyForwards (max h)
modifyBackwards (max h)
pure (max 0 (x - h))
main = replicateM_ 20 $ do
n <- randomRIO (3, 10)
hs <- replicateM n $ randomRIO (0, 10 :: Integer)
putStrLn $ show hs ++ " => " ++ show (volume hs)
Note that the only explicit type in the entire program is the `:: Integer` annotation on the upper bound for randomRIO. Without that annotation the program would be underconstrained, since the input to `volume` can a list of any type with Ord and Num instances.
Strong/weak is generally not a useful distinction because it has no formal meaning. What you're probably after is "expressiveness" and "soundness". So C's type system is unsound and it's types are inexpressive. Haskell's type system is sound and moderately expressive. Agda's type system is sound and expressive.
> Strong/weak is generally not a useful distinction because it has no formal meaning.
"This doesn't have a formal meaning, therefore it's not useful" is quite a logical leap you've got there.
I've got over a decade of professional programming experience in which "strong types" is a useful enough concept to help me do my job. "Soundness" certainly gives stronger guarantees, but it's more than I've needed.
I'm not aware of "expressiveness" having a formal meaning, but my informal definition has functioned for me so far.
> "This doesn't have a formal meaning, therefore it's not useful" is quite a logical leap you've got there.
It means that everyone defines strong and weak in their own way, which has happened in every type system debate I've seen over the past 15 years.
> "Soundness" certainly gives stronger guarantees, but it's more than I've needed.
Soundness is exactly the metric you need. Either you can rely on your type system not to lie to you, or you can't.
Programming language expressiveness means "Felleisen expressiveness". It's a metric approximated by source code compression, which is why the great programming shootout includes gzip metrics for source programs.
> It means that everyone defines strong and weak in their own way, which has happened in every type system debate I've seen over the past 15 years.
Okay, that's fair. Part of the reason I gave examples and defined the spectrum I was talking about was to address this problem, because I know people don't necessarily know what I'm talking about.
Even static typing very rarely gets in the way (it makes a few programs harder to express; but I find this relevant much less frequently than people think; and even then I’d argue that expressing the types still adds value). What gets in the way, as the video argues, is excessive explicit typing. But languages can get around this with type inference.
Strong/weak types and dynamic/static types are really two different spectrums. People conflate strong types with static types and weak types with dynamic types, but they aren't really the same thing.
Static/dynamic just has to do with whether the types are checked at compile time or run time. Examples: Static: C, Haskell. Dynamic: Javascript, Python.
Weak/strong has to do with what kinds of checks the type system does. A strong type system is capable of checking a lot of different things for you. Static types are often stronger, but not always: for example, C is statically typed but its type system checks hardly anything: int* + int is perfectly valid. A list of programming languages from weakest-typed to strongest-typed might look something like: JavaScript, C, C++, Common Lisp, Perl, Scheme, Ruby, Python, Java, C#, OCaml, Haskell.
Static types are nice for projects which will grow large and where bugs are a big problem, but I think for the average HN person, static types aren't really necessary.
Strong types, on the other hand, are extremely useful. Even in a dynamically typed language, they aid in debugging a lot, because type errors occur much closer to where they're caused. In Python, for example, `"foo" + 42` immediately fails. But in JavaScript, you don't get an error until much later, perhaps when your webpage is mysteriously displaying "foo42".
Of course, there's a small cost to strong types: in the case where I actually do want to append a number to a string, I have to do `"foo" + str(42)`. But I think people tend to overstate this cost because it's visible. But if you look at the big picture, typing five extra characters takes a lot less time than debugging almost anything.