8 ms·
My thoughts on “bad code”
- p-o 4y agoI'm not sure if it's a trend but I am sure that I like to see people being vocal about highly readable codebase. I have yet to see this mindset in workplaces I've been at. I would love to see a future where folks write code without thinking about how "scalable" or "performant" their code is and instead focus on how easy it would be to change the behaviour of existing code.
- llanowarelves 4y agoProblem is even if your manager's manager understands the value of it, his manager's manager doesn't, so time spent on it is seen as wasteful or "doing nothing" versus duct-taping things together for some poor sap to have to refactor ("for free") under pressure while implementing more features non-technical PMs or managers want ASAP. You have to be skilled at office politics or make sacrifices to keep code quality high. Usually not worth it. You get yelled at less if you externalize all the costs to future suckers, instead of trying to reduce those costs upfront.
- jiggawatts 4y ago> externalize all the costs to future suckers I literally just had this exact meeting yesterday. So much basic maintenance had been skipped that a suite of apps was costing too much money to migrate to a new platform. Instead of asking for more budget for that app, the dev manager suggested using the money from an upcoming project for an unrelated app to finish off this one! It's a literal Ponzi scheme, using funds from newcomers to pay off the technical debts of previous projects. Which of course never ends. Now the next project will go over budget, leading to rushed work, corner cutting, and drawing down on the project after that, which in turn will be a mess, etc... It's fascinating to watch this kind of stuff unfold as an outsider.
- epgui 4y agoI realize that my comment doesn’t scale and only works for a minority of people but… Just try really hard to not work for shortsighted people or bad companies. There are tons of great workplaces out there that will treat you like a king and pay you very well. Keep looking, these “almost too good to be true” companies exist. Vote with your feet at every opportunity.
- namaria 4y agoPaying attention to tooling helps. Python shops are hit and miss, but golang and c# centered outfits have been better in my experience.
- epgui 4y agoFWIW, my experience has been that companies using less popular languages with a good reputation (Haskell, Clojure, lisp, OCaml...) are really, really awesome places to work and learn.
- namaria 4y agoCertainly something I imagine to be true, I just haven't been fortunate enough to get deeper in that direction. My first contact with programming logic was The Little Schemer though, and I'm incredibly glad for that.
- jzombie 4y agoCurious about the coorelation between scalability and performant vs over time and over budget. Of course scalable and performant is nice. I have also been on teams that delivered absolutely nothing because the KPIs were more important than the product.
- ahi 4y agoThis one drives me nuts. We aren't running this web app on a pentium 2. Code complexity is vastly more important than the complexity of running this algo when the N is 12.
- favaq 4y agoBecause it starts with "it doesn't matter because N is 12" and it ends up with websites such as reddit which are extremely slow and go offline every single day. You may not be running your site on a pentium 2 but shitty performance adds up quickly and computing power is not infinite.
- pdimitar 4y agoIt's not an either/or, in my career at least it was very often the case that I could produce code that's both easy to extend and is very performant. At one point experience and intelligence converge and things get better.
- Rayhem 4y ago> instead focus on how easy it would be to change the behaviour of existing code. This has been my principal design consideration for a while now. Not "the code should be short!" or "the code should be elegant!" but "it should be easy to change" because your requirements are always going to change. It just so happens that the latter usually means things like single responsibility and loose coupling that bring about the former as a matter of course.
- flippinburgers 4y agoThis is why devs should chose a language like golang. It is readable because, generics aside, you don't get to do much with the language and it also runs very fast.
- 000ooo000 4y agoMaybe a livestream is not the best place to articulate well ones thoughts on software design philosophy, and to give the most charitable interpretation: bad code can be distinguished from terrible code if one can easily see how to improve it. I think it would be unwise to suggest bad code is good without qualifying that 'good' here just means 'better than terrible', which is my more literal interpretation of the tweet. I'm also not fond of the idea that bad code is not necessarily bad because of xyz circumstance that lead to the bad code. Can't we just call a spade a spade? We all have or will continue to write code which is less than ideal; seems like too much ego is attached to the code and we're gonna start down the All Code Is Beautiful path. Sometimes you just gotta write garbage, but garbage is garbage at the end of the day.
- dannyobrien 4y agoTsoding is a really impressive (though cranky in an almost stereotypically Russian way ) coding livestreamer. I've really enjoyed his voyages around Haskell, Rust, and other esoteric pursuits over the years: https://tsoding.github.io/ https://tsoding.github.io/
- defrost 4y agoThere was an "OMG Bad Code!!" scene toward the end of the Silicon Valley series that I caught. Many people ragging on the founder|coder for writting a clean snippet of linear search function when he obviously should have done better and used a binary search (or some other algo) .. ergo "Bad Code!!". What was missing from that was any context about the volume of expected data per "need to seach this" call etc. It's entirely possible that every instance was to quickly search an already primed cache of data and that the optimal performance on the target hardware was to minimise branching and linearly rip through a small chunk of data in a load page. Or, maybe not. Point being, context and bigger picture plays a part here also.
- asdguinui 4y agoIn fairness to the scene, this was the code in question: https://stackoverflow.com/questions/65753731/why-searching-a-sorted-list-using-brute-forcing-is-funny-to-silicon-valley-show https://stackoverflow.com/questions/65753731/why-searching-a... Hardly clean, I think you'd agree. In any case, you shouldn't use explicit iteration to solve this problem without a good reason. Every language should have both linear and binary search as part of its standard library.
- epgui 4y agoUhhh not sure why you were downvoted to oblivion. I can easily see other people disagreeing with you, and I’m not saying I agree, but what you said was not unreasonable. Vouched.
- Jtsummers 4y agoNew accounts whose first comment includes a link tend to get filtered and marked dead without user interaction, it's part of the automated mod system. They basically get caught up in the spam filter, I vouch for them a lot when (like the one you vouched) they are actually contributing.
- epgui 4y ago
- trentgreene 4y agoSome of the most impactful code I've written has been absolutely trash. Like, really, really bad. By almost all objective measures, terrible. Except for the results it helped bring about. By that one measure, it was excellent, damn near perfect code
- joombaga 4y agoOh man I have some bash case statements that fit this description. Could be improved, but it's tested with every commit on every PR and by George it really holds the room together.
- jiggawatts 4y agoI've seen snippets of the back-end code of a public cloud, and it is full of multi-page "switch" statements where they have hard-coded lookup tables for what SKUs support what features. It's ugly, it's a maintenance headache, but it does function, and very robustly too. There are no API calls, no microservices, no performance issues, etc...
- arethuza 4y agoI wrote some really trashy code in what was supposed to be a "proof of concept" where I had about 7 days to write something that would be shown to the executive committee of the very large company I was working for at the time. Then I was told the CEO and CFO wanted a preview in 3 days.... That was 12 years ago, still in production as far as I know! [The functionality was supposed to be replaced with something built in or integrated with the new ERP system.... but that project crashed and burned].
- now__what 4y agoLikely because if the effect of "bad" code is positive enough, you have incentive to just let it keep on being "bad" and not touching it, so you can keep reaping the benefits. Also, if you're on a tight timeline for a critical function, you may want to push ugly/inelegant/dense/"bad" code just to get the function in prod a day sooner. This doesn't mean the code isn't "bad," it just means that the business needs outweigh the ugliness.
- jfengel 4y agoGood and bad code only matters if someone is looking. If you assume nobody is looking, you will often write bad code. If you assume that someone is looking, possibly including Future You, you will aim to write good code.
- epgui 4y agoThis is very true. IME it’s really an empathy problem. - “It passes the linter so don’t give me any advice on how it can be improved” - “YAGNI” While both of the above could be good counter-arguments in some contexts, I’ve seen them used disproportionately often by set-in-their-ways senior engineers who don’t care anymore or who forget that we write code for other humans, not for machines.
- nighthawk454 4y agoThis is a pretty good take imo. His argument, summarized, is that ostensibly "bad" code is not as bad as it could be, because that implies you can readily tell what it does, immediately see issues with it, and know how to improve it. Possibly, this code might not fully deserve the label "bad". It's _far_ better than code that's completely impenetrable. Reminds me of the Bjarne Stroustrup quote: "There are only two kinds of languages: the ones people complain about and the ones nobody uses".
- 000ooo000 4y agoI'm not so convinced that "bad code is better than awful code" is a very useful observation. Kind of strikes me like "well I have stage 3 cancer, but at least it's not stage 4"; you wouldn't be wrong, but you still have cancer..
- nighthawk454 4y agoI think maybe "treatable" vs "untreatable/terminal" could be a better metaphor. Both obviously still suck and are expensive and painful and time consuming, but the difference seems signficant
- 000ooo000 4y agoAgreed, I like that. Seems more useful/actionable than 'good' or 'bad'. So can we then say the difference between a rookie and a seasoned developer is just whether they say code is 'unsalvageable' or whether it's 'bad'? We solved it - coming soon to a interview process near you.
- hardwaregeek 4y agoI've noticed what I'd term a "post-modern" sensibility towards code quality, where some of the often cited tenets of good code are being critiqued or questioned. Stuff like yes, you can have super large functions or super large files. Or yes, you can have repetitive code. Turns out a lot of this stuff doesn't impact readability or in fact is more readable than the alternative. I'd much rather read one function top to bottom than have to jump into 7 nested function calls that are only called once. And I certainly don't need the levels of abstraction that design patterns or Haskell typeclasses demand. There's a real danger in a well-intentioned clean code advocate. First, because there are no universal code principles. Maybe "have it work", but even then, a lot of value has been gotten out of code that doesn't work. And second, because it's very easy to go from a good guideline to a dogma. All you need is a few people to misinterpret your guidelines. Heck, a lot of people haven't even read the guidelines. They just parrot what someone else paraphrased on Twitter.
- agentultra 4y ago> I'd much rather read one function top to bottom than have to jump into 7 nested function calls that are only called once. And I certainly don't need the levels of abstraction that design patterns or Haskell typeclasses demand. I’d say it’s pretty subjective. I’m the opposite. I can’t read functions that are a hundred lines long with a dozen bound variables and half a dozen branches and early exits. That’s not easy to read and it requires keeping a notepad with you to figure out the control flow. I much prefer short definitions with clear logic. Leave the semantics to the edges of the program where it matters. It’s easier to reason about using substitution and algebraic manipulation. Don’t get me wrong though, I write my fair share of C code and low level drivers. For that though I tend to use a higher level language to work out the logic. My business isn’t writing code. That’s the boring part. It’s solving the problems that is interesting. But that’s the funny thing. Regardless we could both solve the same problems in our own ways and more often than not it will be good enough. After twenty years and hoping for another twenty… I guess I’ve learned that what matters is that you can get along with your team and read each other’s code. Styles come and go and don’t matter that much.
- 000ooo000 4y ago
- epgui 4y agoIn my experience, there are no absolute rules for “good code”. There is a lot of good advice out there, but ultimately the best predictors of good code are 1) experience, and; 2) caring. I’ve been in extremely frustrating situations where horrible horrible code gets steamrolled into production systems because of <arguments>. However, in nearly every single case that wasn’t a well-intentioned junior, the bad code was almost never the result of following bad advice: it was the result of the engineer not caring. Start with caring and empathy, and always worry about how “nice” your code is. That’s how it’ll get better.
- chrsig 4y agoGood and bad are such boring descriptions for code. It tells me nothing about it. Readability is incredibly subjective and it needs a point of comparison. What properties of the code need improvement or demonstrate what other should aspire to? -- Getting someone to really articulate that is quite difficult.
- cratermoon 4y ago> Readability is incredibly subjective and it needs a point of comparison Readability definitely has objective measures. One that I find especially interesting goes by the term "cognitive complexity" and measures, in part, comprehensibility. A 2003 article in the Canadian Journal of Electrical and Computer Engineering titled, "A new measure of software complexity based on cognitive weights", defines it as "the degree of difficulty or relative time and effort required for comprehending a given piece of software modelled by a number of BCS [basic control structures]" In 2018, "Cognitive complexity: an overview and evaluation" in Proceedings of the 2018 International Conference on Technical Debt gave a 3-part criteria for evaluating complexity. Not that this is not the same as cyclomatic complexity, a measure best suited to gauge the effort needed to adequately test a system.
- Vanit 4y agoMore of a legacy code thing, but in my experience a lot of devs will race towards labelling legacy code as "bad" code because it doesn't meet some superficial standard. If I had a dollar for everytime I heard this from a dev as they start discovery on some new feature or necessary refactor, only for them to come back and say they realised there's a good reason the legacy code is the way it is. I was certainly guilty of this too when I was a junior/mid.
- epgui 4y agoI think people also have a hard time telling the difference between “bad code” and “unfamiliar code/patterns/abstractions/etc”. Familiar thing often “feel better” to us even when they’re quite bad. I’ve seen that bias at play when new people join a team.
- flippinburgers 4y agoBut has anyone ever looked at a program that was structured after "clean architecture" principles as outlined by good-ol' uncle bob and thought "yeah this was a great idea!". The answer is no.
- josephg 4y agoOh goodness, I've been programming for 30 years and I'm still in this picture and I hate it. I have to fight the temptation to judgement all the time when I read other people's code. Their code uses too many classes? Bad code! Its overly factorized? Under factorized? Too many dependencies? Too much reinvention of the wheel? All these things are obviously evidence that whoever wrote this code is inexperienced (and they probably have deep character flaws). I'm sure other people feel exactly the same way about my code, too. Its frustrating and dumb.
- vsareto 4y agoGood/bad code has changed radically over time, and there’s still a bunch of diverse opinions on it. It also means different things in different ecosystems. At the end of the day, the easiest way to deal with it is to find a social circle that shares your opinions. That’s the only situation where you get enough direct, useful feedback over time on whether something is good or not. This is actually better because you’re bringing the person back to the forefront instead of trying to judge code as objectively good or not
- omginternets 4y agoThese are just different degrees of “bad”: 1. “I see something that makes it hard to work on this code” 2. “I don’t understand what the code is doing and touching anything breaks everything.”
- layer8 4y ago3. “I don’t understand what the code is doing, and have no practical way to tell if a change would break something, because the application integrates with bespoke distributed systems that only run at the customer site, and also there are N customers with N different environments having different integrations, and what’s worse their respective test environments, for those that have one, don’t match their prod environments.”
- brigadier132 4y agoThis is extremely stupid. And programming "influencers" are also stupid. Code can be bad on many levels. It can be bad on the level of some one liner where someone appends to a list in javascript by using the length as an index. It can also be bad on the level of being an impenetrable wall of shit that is impossible to understand. And just because I don't understand how something works doesn't mean I don't know why it's bad. I know why it's bad because I know it can be done simply but the person that implemented decided to write their own terrible and over engineered design.
- jeffrallen 4y agoYeah but sometimes bad code is just bad code. Sometimes what it is doing is not obviously wrong, but ends up being wrong, but it's so bad that it's not even doing the wrong thing right, so when you "fix" it you discover it should never have been written in the first place.
- j0hnyl 4y agoIn my opinion code that gets the job done is good.
- cratermoon 4y agoWhich job is that? A job it was written for months or years ago, or one it needs to do today? Or some other job?
- j0hnyl 4y agoAll of the above? Which ever one is needed.
- cratermoon 4y agoFor code to do "all of the above", it has to change. In which case, bad code does not get the job done because it's highly resistant to change and gets more resistant as time goes on.
- ladyattis 4y agoI agree with the comments in the video since often I find myself dealing with opaque code. Having code that's opaque makes it hard to make sense of what it does, when it does what it does, and what happens when it fails. Having code that's obviously less than optimal but still understandable is far better as the OP mentions in the video. At least with bad code that's understandable you can improve it sometimes if the underlying requirements and dependencies aren't too deep (otherwise, you're gonna break something and it's better to just leave it be bad or ugly code).
- tpoacher 4y agoIn other words: My definition of X which I interpret as Y, and is not what is usually grnerslly understood by X, is bad. Therefore, I propose alternative practice Z which is better than my Y (and also happens to be what people generally understand to be defined as X in the first place).
- end_my_own_ 4y agoSome patterns arise from language design * You can't express `T` where `null` is forbidden in the type system so you get NullPointerException everywhere and defensive null checks. * You express a sum type as a product type because your language does not have sum types . * Your language doesn't have first class multiple return values (or tuples) so you return extra parameters via out parameters or thread local variables such as `errno`. * Your language doesn't have exceptions (or algebraic effects) and can't do IO so you have monad transformers. * Your language doesn't have set-theoretic types so you need hacks like `thiserror` . * Your language doesn't have stackful coroutines or can't infer async IO for you so you have `async/await` spam or callback hell or "mono's". * Your language doesn't have exhaustive checks (or pattern matching) so you need a fallthrough case check on switch statements . * Your language doesn't have algebraic effects, so you need to pass context everywhere. I know someone will reply about Java's null annotation checking options, so here is one of them: https://github.com/uber/NullAway https://github.com/uber/NullAway .