13 ms·
I remember when I first added ESLint to our large JavaScript codebase, and then again when I added Flow. I'm a perfectionist when I code, but it was shocking to
by _bxg1 8y ago
I remember when I first added ESLint to our large JavaScript codebase, and then again when I added Flow. I'm a perfectionist when I code, but it was shocking to see some of the things I'd written. Mistakes that I thought were so unlike me, but had been sitting there for months anyway, waiting to blow up.
The human brain wasn't designed to handle the complexity of large codebases. There are just too many compounding implications of everything for us to hold them all in mind at once. The very best coders miss things all the time.
Instead of seatbelts, I would compare tool assistance to aviation instruments. It's not primarily something that just catches you before a disaster; it's something that helps you make the most effective use of your mental resources. We don't ask pilots to fly commercial airliners without advanced software and dozens of readouts and displays to guide their attention and decision-making in an overwhelming sea of information. We shouldn't expect the same of programmers.
- moosey 8y agoThe contrarian argumentation that I see on HN is always something to behold (I view it as a positive!). An article comes out yesterday about programmers being a problem: comment section points in another direction. An article comes out today that says that programmers aren't the main problem: comment section points out how awful all of us were, if we just go back far enough in time. My main takeaway: Programming is hard.
- sgt101 8y agoAre you talking about monoliths vs microservices from yesterday? If so then I think that the points made are somewhat different; there is little reason to believe (that I have seen) that microservices are "better" than monoliths, but there is a lot of reason to believe that strong type systems (an other tools) provide long term benefits.
- noir_lord 8y agoI couldn't agree with your post more if I tried. The first time I ran a static analyser over an old codebase of mine it was deeply humbling. I'm a competent programmer who works deliberately and carefully and the tool still went "did you really mean to do this stupid thing?". Of course sometimes you do mean to do stupid thing because there is a good reason for it and as long as the tool gives you the ability to say // @allow-stupid-thing: punch-myself-in-face it's all good. Since then I throw as many linters, formatters and static analyses tools as I can reasonably get my hands on at every codebase.
- _bxg1 8y agoYeah. That's one thing I love about Flow/TypeScript as opposed to "real" compiled languages: you can actually leave type errors present if you don't know how to take care of them at the moment, and do a successful build. Or, if you know you're doing something safe and the analyzer just can't understand that, you can literally comment-out the error. And of course, Rust has "unsafe" mode. In my experience it's important to have tiered strictness; start out with the highest constraints, but provide mechanisms for stepping that down in special cases where you really have to, without giving up safety completely if possible.
- kzzzznot 8y agoI too like this about Typescript - allows for fast spiking too, where you don't actually yet know what you want
- nickpsecurity 8y agoCould you name them? Especially those that find more stuff than the others along with how you rate them on false positives? I try to collect data to pass on to folks interested in trying static analysis.
- Zarel 8y agohttps://lgtm.com/ https://lgtm.com/ LGTM recently came by my project offering to integrate with GitHub. It's found a decent number of bugs other linters and my test suite didn't find, and it didn't require any setup at all; you just open your project on their website. Their staff also reacted really quickly when I asked them questions or reported bugs. For the most part, their only false positives are things like unreachable code, which I sometimes used to leave in for future-proofing, but I eventually did things their way, because it does make sense that it could be confusing to a third party. The only alert I've ever suppressed was a string search for "example.com", which could have matched "example.com.untrusted-attacker.com". It was just code for displaying a reminder, not anything security-critical, so I didn't think it was worth fixing.
- 8y ago
- hinkley 8y agoIn race cars (though maybe not F1), I’m told that the inertia of the driver would throw them out of the car on those turns if not for the safety equipment. I think you can make the analogy work for professional drivers, but not for amateurs.
- pjc50 8y agoI'm not sure I follow this; are you referring to the great improvements in safety that F1 adopted relutantly, only after a long campaign by Jackie Stewart who'd seen too many friends die?
- swiley 8y agoTools are an absolute must for large codebasses. Humans struggle with large codebases but by restricting what's allowed to certain well understood and prearranged patterns and by forcing them to write specs and docs they are possible to handle.
- phaedrus 8y agoThe comparison with aviation instruments is apt: I remember seeing a TV special that talked about how in the early days of aviation (circa WWI) the pilots' culture of seat-of-the-pants flying and bravado was resistant to suggestions that human senses are just not equipped to differentiate between certain inertial reference frames, of which one leads to getting into a death-spiral. It was not until an early aviation safety pioneer came up with a demonstration on the ground (something like a spinning chair and blindfold - I forget the details) that pilots who went through the demonstration were shocked to discover they "fell for" the physical illusion they believed they were immune to. I feel like programming is in the same state today. Especially the more C/C++ code I see in my career: I'm absolutely convinced humans should just not expected to manually manage some of the things they try to do now.
- _bxg1 8y agoC/C++, and in many cases Lisp, seem to be the most entrenched communities when it comes to the "culture of seat-of-the-pants flying and bravado". For contrast, JavaScript has as much flexibility and nearly as many foot-guns as those languages, but its community has been much more receptive to safety rails and static analysis. (Hopefully this doesn't start a flame-war; that isn't my intention)
- AdeptusAquinas 8y agoHow. Dare. You. More seriously, JS has had its own resistance movements. TypeScript was actively disdained until, as far as I can tell, Angular switched to it. Probably partially because it was MS, but also because there was a lot of resistance to static typing despite the demonstrated safety benefits.
- cm2187 8y agoDoesn’t static analysis requires static typing? There certainly has been a strong resistance to the introduction of static typing in the js community.
- 8y ago
- specialist 8y ago"The human brain wasn't designed to handle the complexity of large codebases." Because I'm a very simple bear, I always try to find the most simple thing that works. Because I'm certain that the next programmer that comes along, which is most likely future me, will see my efforts and think "WTF?!" Another facet is our human mind's propensity to make errors. Instead of blaming stupid users, just deal with it. Design artifacts and systems which prohibit errors. FWIW, Donald Norman's book Design of Everyday Things completed my transformation from technophile to humanist. (I don't know how well it's held up since. Or what knowledge now supersedes it.) "I would compare tool assistance to aviation instruments." Great analogy. Many, many designers (of APIs, frameworks, UIs, simulations) conflate abstractions with mental models. Our tools should make the underlying systems obvious, vs trying to hide the complexity. And if something remains too complex to explain, try again, until a mental model that is simple and obvious is found.
- chousuke 8y agoI think that distinction between mental model and abstraction is something I've tried to put into words for a long time with little luck. Thanks for that. I think that any person working with a system must be able to form a "morally correct" mental model of the entire system from top to bottom (as deep as it practically matters) or the abstractions of that system have failed. When I read highly abstracted code, the times it gets frustrating is when I can't form a coherent mental model based on the abstraction so that I could understand how the system behaves. Usually that's because the abstraction is too generic or interwoven with a non-local mechanism that I can't predict.
- _hardwaregeek 8y agoIt's amazing how little we talk about tooling, both in work and in education. I had an internship where I kept on trying to work on better tooling for the developers, only to be told that I should be working on the actual product because that's more important. Except, if I make the other developer's lives even 5-10 percent easier, then that will have a much longer effect than whatever work I can get done in 3 months. The most useful contribution I made in that internship was a document explaining all the features of the product with images, short videos and both the internal names and the client facing names. And in school? Forget about it. Nobody shows kids how to use IDEs or editors properly. Nobody teaches git properly or command line tools. Nobody learns how to set up linters or heck, how to turn on -Wall -pedantic. Imo, every systems class should have a first lecture that explains Valgrind, proper compiler flags and Makefiles, and a last lecture that explains Rust. Realistically most students are not going to use Rust, but just understanding that it exists as a possibility can be useful.
- m4lvin 8y agoHey stranger, thanks for telling me that the lecture I gave last week was the right thing to do, even though I will be told that "those things do not belong to 'Data Structures and Algorithms'" :-)
- Izkata 8y ago> and Algorithms If the complaints are annoying enough, I propose cheating - for example, working makefiles into the graph algorithms part of the course.
- mamcx 8y agoNot only with dynamic types, where more bugs are of the "very stupid" kind. I run against my rust code, and damm. However, this also prove how MUCH better is static typing. The rust linter provide hints about more serious stuff, not things that the type system already avoid!
- adrianhel 8y agoI did a review of the entire backend of a pretty big project just now. Very very worth it. I'm going to plan for that every 6 months or so from now.