The Pragmatic Programmer says to throw away prototypes, but in practice it always seems easier to click the merge button than to rewrite working code.
You aren't seeing the non-existence all the well engineered stuff you never had time to build "properly".
If only 1 in 10 throwaway scripts survives, that can easily cost more in the long run than writing all 10 scripts in a sustainable way.
The open secret is that you almost always have time to do it properly. Doing it properly doesn't take that much more time, and most deadlines are self-imposed and artificial.
EDIT: Time isn't actually the most important cost. Not my code, but a coworker's throwaway script where he thought, "We'll just log this to a file for now" filled up a production DB server with log entries and took down a high-traffic e-commerce site for 6 hours. That easily cost more money than an entire career's worth of "doing it properly". There were obviously multiple mistakes that allowed that to happen, but removing the "we'll do this properly later" mistake would have prevented it.
> Doing it properly doesn't take that much more time
If you don't have a cutting board for a small thing, surely you wouldn't put your cooking on hold to drive out to the kitchen supply shop to buy a cutting board. You'd just use a stack of cardboard or something. (And make a note to buy a proper cutting board later, of course.)
Technical debt is inevitable, and it will never be adequately documented. That's not really the situation we're talking about here.
This is more about stuff that was written with the mindset of "this will go into prod" versus "this will never go into prod". If your code is never going into prod, it's often acceptable to have huge, critical bugs--that's a very different thing from technical debt.
> If you don't have a cutting board for a small thing, surely you wouldn't put your cooking on hold to drive out to the kitchen supply shop to buy a cutting board. You'd just use a stack of cardboard or something. (And make a note to buy a proper cutting board later, of course.)
Well, sure, but this is a great example of why analogies aren't a good way to make arguments.
You're talking about using the right tools, not doing things properly. Sure, if I don't have the right tools, I'd do the best I can with the tools I have. But you'd better bet that a professional chef shouldn't just skip chopping the carrots because "it's just a throwaway dish, no need to do this properly" when there's a chance that it's going to be served to a food critic.
At first, I thought it was crazy. It kinda makes sense though, JS seems to be growing extremely fast.
Readable languages are the kinds where not only do you understand what they're trying to do at a quick glance, but also what they actually do.
Just because more people are doing it, doesn't mean it's improving.
I'll believe things are going in a good direction when `{}.foo` throws an exception in all major JS implementations. But I'm not optimistic about that ever happening.
My only hope for JavaScript right now is that it might die because WebAssembly lets a reasonable language achieve dominance.
It does. That's a SyntaxError.
Try one of the following:
> ({}).foo
undefined
> var a = {};
undefined
> a.foo
undefined
Now imagine hundreds of lines of code and a bunch of asynchronous callbacks occur between the last two lines, and imagine what that does for your debugging experience. Or watch Wat[1] and see if any of that is what you want your language to do when it happens.The fact that JavaScript throws an exception on `{ foo: 'bar' }.foo` and not `({}).foo` isn't exactly a defense of the language.
> Now imagine hundreds of lines of code and a bunch of asynchronous callbacks occur between the last two lines, and imagine what that does for your debugging experience
That's what using typed signatures for your objects is for. It's not even substantially different from having, say, Java with an object with properties that can be nullable or Optional.empty().
This is an excellent and succinct explanation of why JavaScript is a badly-designed language, and why I use better designed languages when possible.
If the basic properties "work" when it makes no sense for them to work, your language is broken.
> That's what using typed signatures for your objects is for.
Explain more?
With Typescript or even just JSdoc and a good IDE, you can do:
const a: {propertyA?: true; propertyB?: 'cats';} = {};
// or
/**
* @type {object}
* @property {true=} propertyA
* @property {'cats'=} propertyB
*/
const a = {};
...and get warnings later when you attempt to access anything that's not propertyA, propertyB, or a JS builtin, as well as warnings if you attempt to use either without verifying whether it's undefined or not, as well as warnings if you then try to use them in places restricted to non-matching types.With Typescript, you can turn on full strictness and make these build-rejecting compile-time errors, too.
There gotta be a better way to design syntax for an async language.. right?