> I don’t know about the rest of the world, but I’ve never once been slowed down by a compiler saying “It won’t work like that. Don’t waste your time”.
I'm right there with you, I really don't understand this train of thought that catching errors faster somehow makes you slower. I like having the compiler there to catch my errors when I make them rather than some number of minutes/hours/days/months later when everything is on fire and I've forgotten the context of what I was doing.
Maybe learning a statically typed language (nearly) first damages your brain irreparably, and there's no longer any hope for me.
Under dynamic typing, you just do a small part of the job, yet the program builds; you can get in there and try things. Decisions about how to proceed can be guided by errors you run into when you step on the things broken by the partial refactoring. Seeing things working right away can be a motivator to get the whole thing done. Or it can help you see that, oops, the change is not worth doing or bad for whatever reason: you dodged a bullet with a small amount of sunk cost (the few changes you made that you can throw away without a whole lot of regret).
Static typing helps with small refactoring where the ripple effect is small. The compiler pinpoins things that have to change; they happen to be few in number, and don't have too many ripple effects of their own. If your change breaks everything, then it's moot; the compiler tells you there are breaking changes everywhere.
There is another angle: under dynamic typing, changes can be done in ways that things continue to work. You can write modules that have "absolute genericity": they work with objects of any type without being recompiled. Such things are bullet-proof against all conceivable refactoring.
I’m reading this and I have just no idea what to say.
With static typing you don’t have to be very considerate in this work, because you will have a compiler telling you if anything is broken, not to mention refactoring-tools which can help you reliably and automatically make those changes across your entire code base in a verified 100% correct way.
With dynamic typing however, you just have to guess and pray.
Clearly static typing is the superior option in this specific scenario where you are calling out static typing to be a disadvantage.
So what am I missing?
A good language has a run-time type in every object, regardless of the type checking system, and allows programs to be run safely even if they are incompletely checked or if inconsistencies have been positively identified.
[0]: https://en.wikipedia.org/wiki/False_memory#Commonly_held_fal...
I have exactly the opposite experience here. If you're making a sweeping change to a core data structure, I would feel much more comfortable making a large change in a statically typed system. It would take much longer for me to feel comfortable releasing a change like that in a dynamically typed system.
> Under dynamic typing, you just do a small part of the job, yet the program builds; you can get in there and try things. Decisions about how to proceed can be guided by errors you run into when you step on the things broken by the partial refactoring. Seeing things working right away can be a motivator to get the whole thing done. Or it can help you see that, oops, the change is not worth doing or bad for whatever reason: you dodged a bullet with a small amount of sunk cost (the few changes you made that you can throw away without a whole lot of regret).
Is this how you work? That's terrifying. How much time do you have to spend poking and prodding after you make a change like that in order to be sure you've fixed everything? How much time do you spend tracking down the source of bugs caused by this weeks or months later?
> Static typing helps with small refactoring where the ripple effect is small. The compiler pinpoins things that have to change; they happen to be few in number, and don't have too many ripple effects of their own. If your change breaks everything, then it's moot; the compiler tells you there are breaking changes everywhere.
If your change breaks everything, it's too much to change at one time. Period. Smaller refactors that deliver some amount of value are so much faster than cleaning up for months after throwing caution to the wind.
To use the example of a change to a core data structure: If you want to make a breaking change to a given struct, the first place I'd look is to see if you can convert between the old style and the new style seamlessly.
If that's possible, then you copy the data structure, make your changes, and add a method on each to convert to the other. Then you can slowly roll out that new data structure to the rest of the application until the compiler allows you to delete the original. Speaking from experience this route is so much faster than swapping it out at the source, fixing it up everywhere, and hoping things continue to work as they should.
If it's not possible, not all is lost, but I'd need to see the specific example to give advice on what to do.
> There is another angle: under dynamic typing, changes can be done in ways that things continue to work. You can write modules that have "absolute genericity": they work with objects of any type without being recompiled.
If your code can work on literally any group of assorted types, but still do something of value, then I'm interested to see what it's doing. Sounds like it doesn't do much of anything except pass pointers around. Great for a collection struct, but that's about it. As soon as you need to get things out of it and do something of value, you'll need to have some idea what type you're getting back.
> Such things are bullet-proof against all conceivable refactoring.
I am extremely cynical of any promise regarding code that is "bullet-proof against all conceivable refactoring". OOP famously promised that for many years, but my experience has been that it's the cause of far more refactoring pain than it saves.
Hold on. Are you conflating OO languages with static typing? If your experience with static typing is Java then I actually think I understand where you're coming from now.
I wish I could be convinced by the likes of Rich Hickey that types don't actually help, because he's so smart and charming and eloquent, but my experience screams the opposite.
The usual saying is that faster development is more important because your business probably won't get users anyways. As if Ruby is going to give you a two year head start before any chickens come home to roost.
I don't know about that. Maybe you will get a half-day head start on me if I'm using a statically-typed language I haven't used before and I'm digging through old projects to remember how to write my .gradle hello world.
I don't want to commit to refactoring a large amount of code for the sake of a small change, just so that some code-writing robot gives me permission to run the whole thing.
I don’t know about the rest of the world, but I’ve never once been slowed down by a compiler saying “It won’t work like that. Don’t waste your time”.