For a dynamically typed language, a REPL ends up being essential. In a lot of ways, REPLs can be a superior form of programming. Those are often much harder to get to work with static type languages (often too much ceremony around the types).
The other thing that comes up is sometimes those compile time errors are somewhat pointless. For example, in many cases the difference between an int and a long are completely inconsequential. But further, whether or not your type is a Foo with a name field or a Bar with a name field or an Named interface simply does not matter, you just want something with a name field. While static typing would catch the case of passing in something without the name field, it unnecessarily complicates things when you want to talk about "all things with a name field" (Think, in the case of wanting to move Foo, rename Bar, etc).
Then there is the new concepts you need to learn. With dynamic typing, you can write "add(a, b) { return a + b; }". But how do you do that with Static typing? Well, now you need to talk about generics. But what if you want to catch instances where things are strictly "addable?" now you are looking at constrained generics. But what if you want a specialized implementation? Now you are potentially talking about doing method overloading. What if you want a different style of adding? Now you might be talking about plugging in traits. Typing and type theory have a tendency to add a requirement that you learn a whole bunch of concepts, but also that you learn how to correctly use those concepts.
It is no wonder dynamic typing has it's appeal. Dynamic languages are generally low on ceremony and cognitive burden.
I say all this being someone that likes static typing. Just want to point out that dynamic typing has it's appeal. Obviously, the big drawback is when you come back to a dynamically typed language and you want to fix things. It can be insidiously hard to figure out how things are tied together and you get no aid from the language.
> For a dynamically typed language, a REPL ends up being essential. In a lot of ways, REPLs can be a superior form of programming. Those are often much harder to get to work with static type languages (often too much ceremony around the types).
Haskell has probably one of the best and most useful REPLs around.
> But further, whether or not your type is a Foo with a name field or a Bar with a name field or an Named interface simply does not matter, you just want something with a name field.
This is perhaps an argument for a structural type system, IMO. Though I completely disagree with it.
> Well, now you need to talk about generics. But what if you want to catch instances where things are strictly "addable?" now you are looking at constrained generics. But what if you want a specialized implementation? Now you are potentially talking about doing method overloading
Those same invariants are still in your dynamic code, it's just now they are invisible to everyone and will crash at runtime if broken.
> It is no wonder dynamic typing has it's appeal. Dynamic languages are generally low on ceremony and cognitive burden.
There is a low cognitive burden on the writer, but for every refactor afterwards, and anyone who wants to change your code later, the cognitive burden is higher.
Dynamic typing does have an appeal, but it seems to be shrinking these days while people wake up to the benefits of static types. And it's no wonder, they just make sense from a pragmatic perspective.
Thanks for your post. I mean, I disagree with almost everything you said, but it's interesting to hear the perspective.
> Then there is the new concepts you need to learn. With dynamic typing, you can write "add(a, b) { return a + b; }". But how do you do that with Static typing? Well, now you need to talk about generics. But what if you want to catch instances where things are strictly "addable?" now you are looking at constrained generics...
You lost me here. All of those "what if's" seem to apply equally to dynamically typed languages. If I want "a + b" to work with two Python classes that I just wrote, I'm probably going to have to implement __add__ methods on both classes, and possibly with non-trivial implementations. It's not like dynamic typing makes everything magically addable, with no burden on the developer. Wouldn't you agree?
Not to mention that languages such as Haskell and OCaml have REPLs too. They are not at robust as, say, Common Lisp's -- but REPL-driven development is hardly a stranger in the statically typed camp.
I agree that both camps have their appeal, though!
For a dynamically typed language, a REPL ends up being essential. In a lot of ways, REPLs can be a superior form of programming. Those are often much harder to get to work with static type languages (often too much ceremony around the types).
The other thing that comes up is sometimes those compile time errors are somewhat pointless. For example, in many cases the difference between an int and a long are completely inconsequential. But further, whether or not your type is a Foo with a name field or a Bar with a name field or an Named interface simply does not matter, you just want something with a name field. While static typing would catch the case of passing in something without the name field, it unnecessarily complicates things when you want to talk about "all things with a name field" (Think, in the case of wanting to move Foo, rename Bar, etc).
Then there is the new concepts you need to learn. With dynamic typing, you can write "add(a, b) { return a + b; }". But how do you do that with Static typing? Well, now you need to talk about generics. But what if you want to catch instances where things are strictly "addable?" now you are looking at constrained generics. But what if you want a specialized implementation? Now you are potentially talking about doing method overloading. What if you want a different style of adding? Now you might be talking about plugging in traits. Typing and type theory have a tendency to add a requirement that you learn a whole bunch of concepts, but also that you learn how to correctly use those concepts.
It is no wonder dynamic typing has it's appeal. Dynamic languages are generally low on ceremony and cognitive burden.
I say all this being someone that likes static typing. Just want to point out that dynamic typing has it's appeal. Obviously, the big drawback is when you come back to a dynamically typed language and you want to fix things. It can be insidiously hard to figure out how things are tied together and you get no aid from the language.