> Have you ever tried static typing though? I suspect you don't know what you're missing. Static types make Python way easier to understand.
I'd probably call myself within the "dynamic typing crowd" and I've tried plenty of static typing. It mostly just slows down iterating on something, prevents issues that I/my projects don't really suffer from in the first place, and gets in the way more than it helps.
The statically typed languages I've tried are: C#, Crystal, Elm, Go, Haskell, Haxe, Java, Kotlin, Nim, Rust, TypeScript and probably more I'm forgetting about. Out of those, I've probably written most Rust code. I wouldn't say I despise static typing, but I'm not getting the same value from it that others seem to get.
I still come back to Clojure, ClojureScript or just straight up vanilla JavaScript, as they're much more effective at actually helping me solve the problem I have in my practical day-to-day.
> I'm not getting the same value from it that others seem to get.
Another reason I've seen people not realise how good static types are is if they aren't using a proper IDE with code intelligence.
The benefits of static typing are:
1. Fewer bugs.
2. Makes code easier to understand, because you know what types things are. That gives you a lot of information (even "business domain" things) that usually aren't documented in dynamically typed code.
3. Navigating code in an IDE that understands the language is a lot faster. E.g. you can just ctrl-click something to go to its definition, auto-complete works reliably, you can find all the uses of an item reliably, etc.
4. Refactoring code becomes tractable and easy. You can rename an item and it will automatically update all the usages. Anything you miss will get caught by the type checker.
If you don't use a proper IDE you're missing out on half of that.
Even so, I don't really see how you can say it gets in the way more than it helps. Unless you're working on really small & one-off projects, the amount of time you'll save by not having to deal with type errors or spend ages deciphering code just to figure out what type something has easily offsets any time adding the types.
> If you don't use a proper IDE you're missing out on half of that.
Ok, does Visual Studio Code and/or Visual Studio and/or the various JetBrains IDEs count as "proper IDE"? If so, those are the editors I tried, and while they're nice and all, none of those things you listed got better compared to my non-static typed languages usage. In fact, I'd argue that some of those things get worse when using statically typed languages, especially #2 and #4.
> Even so, I don't really see how you can say it gets in the way more than it helps. Unless you're working on really small & one-off projects, the amount of time you'll save by not having to deal with type errors or spend ages deciphering code just to figure out what type something has easily offsets any time adding the types.
I don't have to spend any time figuring out what type something has because that's not a typical problem I have when reading and writing code in for example Clojure. And if I do wonder about the shape of the data or whatever, I evaluate that snippet of code in my editor and it shows me what data is inside of whatever I had selected.
It's OK that we have different ways of working and our brains work differently. Static typing is not objectively better, some things just work better in one way for some people. I really love the feedback cycle of "Read code, evaluate it, change it, evaluate it, write a test, evaluate it, save file" for producing/modifying code, and others want a cycle of "Read a lot, type a bit, run type checker, run unit tests" or whatever, and that's perfectly fine.
> I don't have to spend any time figuring out what type something has because that's not a typical problem I have when reading and writing code in for example Clojure. And if I do wonder about the shape of the data or whatever, I evaluate that snippet of code in my editor and it shows me what data is inside of whatever I had selected.
Of course you have to know the type of an object to manipulate it. How can you not?
Running code to see the type is pretty much the only option for dynamically typed code but it's clearly vastly inferior:
1. It takes way longer.
2. It only shows you one possibility for the type. Falls apart as soon as you have a union or optional.
> In fact, I'd argue that some of those things get worse when using statically typed languages, especially #2 and #4.
How? Static types add extra information that makes code easier to understand. In dynamically typed code it's the stuff that ends up in comments anyway, except now it's complete and correct.
Similarly they make automatic variable renaming actually work (IDEs don't have enough information to do it properly otherwise), and they detect errors when you screw up a refactor.
What's your argument for them making things worse?
> Of course you have to know the type of an object to manipulate it. How can you not?
Not every language requires you to know the strict type of the data to manipulate it. Take `conj` from Clojure as an example. The function adds an entry to a `collection`, so you know it's a collection, but that's all you need to know in most cases. A collection can be a map, vector, list or your own thing, but it "adds a new entry" regardless, which exact behavior depends on what you use with it.
Definitely not for everyone, but personally I like the abstracted thinking this leads to.
Besides, what I meant with my comment wasn't "I don't need to know anything" but that confusing what types I'm dealing with isn't a typical problem I have when reading/writing code. I thought I made it clear, but I suppose I could have made it clearer. That's on me.
> Running code to see the type is pretty much the only option for dynamically typed code but it's clearly vastly inferior:
Disagree, it's vastly inferior to rely on types to understand what the data actually is, and evaluating the selected form takes one keyboard shortcut and your editor shows you the actual data + type. Only being able to see the type is clearly vastly inferior to me. I like to be able to see exactly what's going on, not just being able to see kind of what's going on.
You never wanted to be able to select a function call inside of another function and be able to see exactly what that returns, without having to do anything else than selecting that piece of code and hitting a keyboard shortcut in your editor? I wouldn't want to trade being able to do that with having static types any day.
> Similarly they make automatic variable renaming actually work (IDEs don't have enough information to do it properly otherwise), and they detect errors when you screw up a refactor.
I don't know where you get the idea that automatic variable renaming doesn't work outside of statically typed languages. Just because a language isn't statically typed, doesn't mean you can't statically analyze it, see https://clojure-lsp.io/features/ for one example.
Worth repeating: It's great that you seem to be getting good value out of statically typed languages, really. But that doesn't mean it's "objectively the best" or whatever, it just means it works great for you with the tradeoffs you're willing to make. Personally, I make other tradeoffs, so other languages are better for me and what I work on. You seem to argue from the standpoint of "Obviously static typing is the best for everything, no doubt" (like many of the statically typing practitioners) but reality is almost never that black and white.
I love Lua but I spend way more time than is fair hunting through my codebase to find the name of that one thing I was trying to access but that doesn’t seem to be present any more and where and when it was created. (Inb4 “better unit tests!” — typesystems do that bit of thinking for you…)
I feel the same way about Lisps, but more strongly. It’s really fast and fun to sketch stuff up until you’re about 3 or 4 functions deep trying to figure out the shape of that one inner associative array and what made you think this little adventure was a good idea in the first place.
> It’s really fast and fun to sketch stuff up until you’re about 3 or 4 functions deep trying to figure out the shape of that one inner associative array and what made you think this little adventure was a good idea in the first place.
But that's exactly the situations where lisps shines! Select the form in your editor, evaluate it and your editor tells you exactly what it is, both runtime and compile-time data, pure magic :)
I'd probably call myself within the "dynamic typing crowd" and I've tried plenty of static typing. It mostly just slows down iterating on something, prevents issues that I/my projects don't really suffer from in the first place, and gets in the way more than it helps.
The statically typed languages I've tried are: C#, Crystal, Elm, Go, Haskell, Haxe, Java, Kotlin, Nim, Rust, TypeScript and probably more I'm forgetting about. Out of those, I've probably written most Rust code. I wouldn't say I despise static typing, but I'm not getting the same value from it that others seem to get.
I still come back to Clojure, ClojureScript or just straight up vanilla JavaScript, as they're much more effective at actually helping me solve the problem I have in my practical day-to-day.