8 ms·
Clever code considered harmful
- revskill 3y ago"To maintain or not to maintain, that's the question" - Shakeshands.
- labster 3y agoDebugging is twice as hard as writing new code. So if you write code as cleverly as you can, you are by definition not smart enough to debug it.
- amelius 3y agoTrue, but you can keep writing fresh clever code until you wrote something that doesn't need debugging.
- belter 3y agoAs of May 2023, we do not have the technology to produce bug free software. We have the technology to specify requirements, we have the technology to produce formal proofs, do verification of specifications ( ex. TLA+ ), and prove a software implements the specification. But what is this "something" that would not need debugging? "Beware of bugs in the above code; I have only proved it correct, not tried it." - Donald Knuth
- JauntyHatAngle 3y agoIt's an interesting experience reviewing a "smart" solution you wrote years ago, and happening upon it again. It's like opening a time capsule to yourself and getting nothing but a punch in the face.
- bluetomcat 3y ago“Smart” can also mean less code, more modularity, efficient algorithms. Obfuscated code is also “smart”, but in a different way.
- drewcoo 3y agoMy smart code plans for me to be sort of stupid and slow in the future, lacking the context I had when I was writing it. And I'm delighted when some seemingly hard problem has a simple, straightforward solution. I often wonder what happened to me. There's a preponderance of evidence that I was smart in the past but very little that I'm smart today.
- tmtvl 3y agoKernighan's Law, exactly.
- deleted 3y ago[deleted]
- blippitybleep 3y agoI found the first solution easier to understand, but I have this infuriating (even to myself) obsession with ternary operators that could introducing some bias.
- jay_kyburz 3y agoI like them when the actually fit one one line. If I have to scroll horizontally I will roll my eyes. And I really hate nested ternaries. One of my pet hates is when the c# style is for opening braces on a new line, making if/then/else statements much longer than they need to be, so people try to cram as much into a single ternary as possible.
- blippitybleep 3y agoyeah, they need to be tidy. You can shoot an unsuspecting programmer through the soul with some evil ternary abuse.
- pwdisswordfishc 3y agoMy biggest beef with the former solution is that resultsEntries is unnecessarily stored in a variable, and between its declaration and use there is an interspersed declaration of a general utility function. I might have inlined that one as well. This is what harms readability the most. Code should be arranged general-to-specific, and this example violates that. Although given that there are only two properties to process, the gopher-style assignment code preferred by the author would suffice anyway.
- samsquire 3y agoI enjoy writing my own code more than I enjoy reading other people's code which is probably not right. To understand other people's code, I have to put away my own thoughts of how things work and try understand the thinking model and mental model of the person solving the problem. And if they're smarter than me, then I have an uphill battle. I think experts get too deep into values that aren't practically valuable to businesses or me and as a result go into the deep end creating a manifestation of something they think is beautiful or elegant but for me is a mess I am now forced to understand, with reluctance. They say that one person's trash is another person's treasure and I think it applies to code too. One person's elegance at runtime is another person's unextendable mess that leads to slow velocity and developer morale. They say code IS the documentation but I don't agree. I don't want to bounce between 50 tiny files to understand where the core part of your algorithm is and what I need to do to get the behaviour I need. I think if you're reaching for advanced language features to solve the problem before better data modelling, that's a warning sign.
- gniv 3y ago> I enjoy writing my own code more than I enjoy reading other people's code which is probably not right. Right or wrong, I think this is true for most programmers. Would be interesting to understand why this is so. Probably related to the problem in the article: we're writing code that is too clever, so reading it takes too long or is too mentally taxing. If we could read code as fast as we read text, it would be less annoying.
- samsquire 3y agoThank you for your reply. I prefer reading documentation or technical deep dives - such as this one https://mattwarren.org/2017/02/07/The-68-things-the-CLR-does-before-executing-a-single-line-of-your-code/ https://mattwarren.org/2017/02/07/The-68-things-the-CLR-does... Is code more dense than English? Why do I understand more overall from this blog post than I would if I studied the codebase of the CLR for hours and hours. I think it's to do with mental models. If developers were on all the same page of understanding the underlying mental models, we could all understand eachother's code because we all understood the same underlying things.
- marginalia_nu 3y agoArguably the pendulum has swung too far in the opposite direction. There's a time and a place for clever code. Clever code can save you thousands of dollars in hardware spending and permits you to do more with less. That's great, even if it comes at the expense of costlier maintenance. That said, most code probably shouldn't be clever. Clever isn't a benefit in itself.
- RedNifre 3y agoOkay, but please use `let output = {}` instead. Yeah, I know, const/let is about the mutability of the variable, not its content, but if you use const I'll assume you write in an immutable style, which you don't when you do `output.Component = Component`. Using `let` is a better warning like "Watch out, mutation ahead!".
- tkzed49 3y agothis just isn't the usage I observe; const/let is typically checked by the linter and auto-fixed. It's just another idiosyncracy of JavaScript.
- wk_end 3y ago> if you use const I'll assume you write in an immutable style Why make assumptions that don’t make sense in the language you’re using?
- msravi 3y agoI don't know. It's true that simpler code is more maintainable and all that. But what happens to the fun and joy of coding? You remove the fun part, and you're left with dry processes and mind-numbing toil that suck the joy out of a passionate endeavor. I get it that many see programming as a means to an end, and that's totally fine, but why take away from those that derive an intellectual high from it?
- mcluck 3y agoBecause I don't want to debug your clever code when we have an outage and you're on vacation
- acheron 3y agoFortunately my code is perfect so it never needs debugging.
- ralphstodomingo 3y agoThe fun, intellectually stimulating part definitely takes a back seat in priority over keeping the lights on for customers/colleagues most of the time, except in personal/weekend projects.
- magicalhippo 3y agoI leave the fun to my side projects. There I write overly clever code and play with the language. Some of these ideas end up in production if I can find a way to make them less clever-looking and more approachable. When I was younger I wrote fun code in production. Then I had to extend it or debug it some years later and struggled to figure out what was going on. Invariably ended up rewriting it to plain code, often many lines more but with clear intent and little ambiguity.
- theshrike79 3y agoYou can be fun and clever on your own time. When you're doing code in a team, prefer readability over clever terseness and premature optimisation. Doubly so if (when) you're not the one who has to come look at the code in 5 years and spend days deciphering the clever bits.
- pwdisswordfishc 3y agoThis is one of those advice that sound reasonable when explained in the abstract, and yet when you hear it invoked in actual code reviews by other people, you wish it had never existed. Especially when the following kind of constructs get decried as "clever": - writing "return condition" instead of "if condition then return true else return false end" - using the conditional-value ("ternary") operator in any capacity - early returns/goto cleanup instead of nested if conditions - using basic higher-order functions like map or reduce in any capacity - any kind of metaprogramming whatsoever One person's "clever" is another's "elementary". If you want to point out that some code is hard to understand, that's fine. But don't call it "clever". Using "clever" as a criticism is implicitly an ad personam argument, passing value judgement on the person who wrote it ("Oh, they must have written it to show off") instead of an argument about the code itself. Also, this: > Hi friend! Hope I didn't startle you. Can I let you know about my newsletter? is missing a "fuck off to hell, don't you dare disrespect my attention like that ever" button.
- denton-scratch 3y ago> fuck off to hell Yeah, that's the button I was looking for.
- nousermane 3y ago> writing "return condition" instead of "if condition then return true else return false end" > using the conditional-value ("ternary") operator in any capacity Looks like author of some code I had to comb through recently, maybe had that among guidelines. Said code was replete with: if(function_that_returns_boolean()){ return true; }else{ return false; } ...and... if(foo()){ return true; }else{ if(bar()){ return true; }else{ return false; } }
- ggambetta 3y agoThis to me screams "I don't understand boolean variables". Why stop there? switch (byte_value) { case 0: return 0; case 1: return 1; ... case 255: return 255; }
- jasmer 3y agoI spend much of my time looking at dusty old code, arguing with my former self, undoing tangled knots of hitherto maligned bits of supposed genius.
- jay_kyburz 3y ago>tip: Euler is pronounced “Oiler”. Impress your math friends with this knowledge. This is what I learned today!
- quickthrower2 3y agoNow do Fermat and Erdos!
- Verdex 3y agoPhilosophical question. I learned the pronunciation of Euler long ago, but I still sometimes use the incorrect pronunciation because I want to make sure people who don't know the correct pronunciation understand what I'm about to say. Is the correct pronunciation of Euler equivalent to clever code?
- scbrg 3y agoHonest question, how else would you pronounce it?
- jay_kyburz 3y agoe-you-ler
- papito 3y agoThink of it as writing in a natural language. You are writing a story that someone else has to read and follow. The compiler will know what you mean if you use the the right words, but you are really not writing the code for the compiler - you are writing it for other people. Clarity is more important than performance, and in many cases the performance gain is imaginary in the first place. Every time I write code and tell myself "I will just keep in the back of my mind why I did that", I know I am writing bad code. There should be no open loops, you should not have hidden knowledge in your brain about how the code works.
- andrewstuart 3y agoI wish “considered harmful” was banned by the HN rules.
- hardware2win 3y agoHow about banning that boring meme too? You know "considered harmful considered harmful" and complaining about "considered harmful" whenever "considered harmful" post appears?
- yawboakye 3y ago> when it comes to day-to-day production code, here's the barometer I like to use: will a junior developer, someone at the very start of their career, struggle to understand this code? this is one of the stupidest things ever said about any piece of code. how about you give that feedback to beethoven (and other great composers)? hey beeth, can you please make your music piece so simple that a junior pianist can play it? this thing over here requires too much study and virtuoso to play, and that's not something we want to aspire to. or to euclid: hey can you remove this _pons asinorum_ here? i have a beginner whose struggling to understand the isosceles triangle. clever code is art to be studied and enjoyed. they are the vehicles of growth, of new and important ideas. holding them off for the sake of a proverbial junior is stupid.
- wk_end 3y ago> clever code is art to be studied and enjoyed. Cool, great, save it for the Obfuscated C contest. The less time I spend “studying” someone else’s idea of cleverness while trying to fix ticket #51483 or implement some weird business logic corner case the happier I am.
- cookieperson 3y agoPretty sure 99% of the world agrees with you here. If someone wants to write twenty nested closures that compose some category theoretic construct in some ancient academic paper instead of two function calls using an already imported library they can go to their museum or whatever to be studied. The rest of us have shit to do...
- endisneigh 3y agoYou say it’s stupid but don’t really elaborate on why. You imply there’s some excellence cliff that presumably cannot be reached if you cater to beginners but that’s hardly the case. Simplicity and complexity, beginner and expert are not inclusive things.
- yawboakye 3y agoapologies. please refer to https://news.ycombinator.com/item?id=36117455 https://news.ycombinator.com/item?id=36117455.
- xupybd 3y agoI once got in trouble for using a switch statement to build a finite state machine. It turned out that language had only recently supported the switch statement and using experimental features in production was a no no. I still hate perl so much for crap like that.
- hkt 3y ago100% with the author here: the number of times I've worked with clever, talented people who make things as complicated as possible is too damn high. The usual result is that they leave, somebody thinks "jesus I don't want to maintain this" and their code is either ignored forever or rewritten with the complexity removed. Maybe this is done in a more verbose or ugly way, but it is also more approachable. As a profession, we really don't give one another enough help. Coding is not about reaching some platonic form of terse expressiveness, it is a social activity, and the sooner this is commonly understood, the better.
- sanitycheck 3y agoCompletely agree with this. It took me 7-8 years of professional development before I fully realised that I needed to stop being clever without a really good reason. A really good reason would be to significantly improve performance or reduce a maintainence burden (e.g. loads of duplication). A good reason would not be "elegance" or an abstraction which might be useful one day. One of things I loathe about code review is fighting for simplicity against people who haven't figured it out yet.
- cookieperson 3y agoIf you look at golang... It's entire purpose for existing(in my opinion) was google realized it had too many people who couldn't be trusted to write maintainable code with all of the flexibility of most programming languages. And yes, google hires many of the best and brightest, and yep go lang is still flourishing despite being an objectively rough language. I'm with you though. I don't like reviewing a lot of code because it sucks calling out a simpler approach to someone who is clearly trying to showcase their greatness. Can put mid level engineers who know better in a crappy spot.
- asah 3y agos/harmful/irrelevant/ By the line, most code and tests will be written by AI in the next few years, with humans specifying it, checking it and checking the overall results. The next generation will look back and ask, "you wrote code BY HAND ?" the same way 99% of us look back and ask "you wrote assembly code BY HAND ?" (and by the numbers, 99% of us don't manage memory by hand, either)
- denton-scratch 3y ago> "you wrote assembly code BY HAND ?" The first computer I was exposed to was an IBM Schools Computer. It had no assembler. It booted into what in retrospect I suppose was a primitive memory debugger; you toggled machine code into the box as hex bytes.
- marcodiego 3y agoMy view: good code is necessarily boring code.
- palata 3y agoWhen did "clever" become synonymous with "overcomplicated"? To me, clever code is maintainable code. If you can't understand code, either it is not maintainable, or you don't master the language at the required level. The thing is that it depends. "Ternary operators are too hard" is not an absolute truth. I would argue that sometimes they are more readable, sometimes not. Same for recursion and everything. The art is to find the balance, and even there, there is not one universal truth. If my interns need to learn things, that's not a problem for me. The goal is not for the interns or my grandmother to maintain my code. The idea is that the maintainers maintain it. If they find it maintainable, then it's hard to argue that it is not.
- adhesive_wombat 3y agoIt's one of those tongue-in-cheek mis-statements that make it into common usage, lose their scare-quotes or italicisation and become a different definition of the same word. Other examples: * "Literally" used in a way to refer to something that's clearly figurative * "Non-trivial" used in a way to refer to something that is clearly extremely complicated Much as I like to decry abuse of language¹, at some point one has just accept that a headword has gained a new bullet-point in the dictionary and move on. 1: and speaking, or, rather, attempting to speak, the Queen's^W King's English, the modern American-centric world certainly delivers opportunities for that!
- teddyh 3y ago“Articulate”.
- peteradio 3y agoIt's like when the electrician comments on some of my own electric handiwork. I believe he called it "nifty".
- palata 3y agoSure, I'm fine with that. I guess my point is that those posts, to me, just try to convey that one should write good code, and that good code is not necessarily using all the tricks in the book (rather not). But then they tend to go as far as to say "never use this concept, because it's too complex", or even go towards wishing that the language did not offer any "clever" features, which I disagree with. Yes, write good code, as in "maintainable". But don't say that a concept is always bad (be it tertiary operators, recursion or templates). It depends on the language, project and situation.
- doe88 3y agoI don't know if it's intrinsically qualify as clever but point free programming in haskell can get really hard to understand really fast.
- okl 3y ago"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult."
- denton-scratch 3y ago> The hard thing is solving complex problems with simple code. If you agree that code is a way of communicating with people (not machines), then this is a corrolary of my rule: that if you truly understand a complex matter, then you can explain it in simple language to a reasonably intelligent non-expert.
- yanis_t 3y agoIf only there were a single standard of what is considered "clever" and what is considered "simple" to which we all could agree regardless of seniority level, experience, etc.
- Syzygies 3y agoI stopped reading after the Haskell example, which looked idiomatic and reasonable to me. Yes it's short; that's a reason to learn Haskell. I'd much rather code in the shower than handcuffed to a keyboard.
- jillesvangurp 3y agoFor me the benchmark is how much time it takes me to figure out my own code when I come back to it six months later. If I can glance at it and still know what I was thinking, I did an OK job. If you stick around long enough on a software system, you will come across code that you wrote that you struggle to understand. Failing this test can be an educational moment. It's your code after all. So, obviously you messed up. But how? How could you improve things? These are important questions because failing to address the issue just sets you up for more problems later. The worst you can do is walking away and then having to figure it out all over again a few months later. Cognitive load of understanding code is expensive. I tend to leave notes for myself. Document the not so obvious things with little one liner comments. Rename variables to clarify what they are for. Extracting code to get rid of the distracting clutter. Etc. I sometimes get comments from others that they find this helpful. That's nice. But I do it for myself as well. Simple code is obvious in what it does. There's a certain elegance to simple code solving big problems. It takes effort to make things simple. Making things as complicated as needed but not more complicated. Being overly clever means you end up with a Rube Goldberg machine of unnecessary complexity and clever mechanics that is hard to understand and maintain. You get a certain satisfaction out of making that kind of stuff work but in the end it's a mistake.
- PrimeMcFly 3y ago[flagged]
- quickthrower2 3y agoThe problem with the intern test is some problem spaces are just complex! But for most crud stuff, yes.
- realjhol 3y agoThis rule is simply wrong. Sure there is code that is needlessly labyrinthine or confusing, but otherwise the far more important rules are - Be concise - Do not repeat yourself - Never be scared of the language. Every feature is a tool that has a right time to use. Code should be simple in these terms, and it takes a fair degree of cleverness to make code simple in these terms
- mianos 3y agoThose initial two examples look like kdb. Particularly the second one. That's production code in many places where I have worked. I would send it to hell if I could. edit: oh, J lang is a later K. That explains it. Similarly it should be sent to hell. It calculates an average in the most obtuse manner. So clever. I hope I never have to work with that one.
- rak1507 3y agoIt's not obtuse, it's an extremely obvious way to calculate a moving average. What would you do instead?
- mianos 3y agoI would not do it all in one long line. I would not do it in an exotic language. I would not do it in a language that it is impossible to find skilled experts at a reasonable price. KDB people cost 2X anyone else with the same skills. Any normal developer can't just pick it up based on some other conventional language in a few weeks. This is the point of the OP and I agree. So many reasons.
- rak1507 3y agoThe original article wasn't about the economics of different languages. It was about not using "clever" code. That J code isn't "clever", it's a very straightforward implementation of the problem, just in a language that is unfamiliar to most people. If someone wants to write an article saying no one should ever use J, fine, but that's a pretty separate article. You said the moving average in particular was "obtuse". How? It's more verbose than it could be, to make it more readable/obvious. Like I asked, what would you do? Whenever people say something is bad, if they can't provide either a good reason or an alternative, it makes me inclined to think that it is simply a kneejerk reaction to unfamiliarity.
- mianos 3y agoIf you code that same thing in js, java, c++, python or rust they all look similar. If you can achieve the same performance in a language understandable by more people you will be better off. Another example is, Russian is much more expressive than English due to the more advanced grammar. That said if you want to express yourself to your American peers and they don't speak Russian you don't write in Russian. If you are all Russian sure. We use kdb/q in our firm but I would rather not and will be trying to migrate away from it in the future. It is good but bigger picture more trouble than it is worth. At least our code is formatted and not all one liners like Morgan Stanley.
- rak1507 3y ago> Clearly, it takes a tremendous amount of skill to solve such a hard problem with such a small amount of code. Wrong. It is extremely easy. The code isn't golfed. It is regular J code that could be written by anyone who's looked at J for more than 5 minutes. They've not even copied it right! I was confused for a second at what gt was, but it's just a mistake from copying >. The other paragraph is also nonsense. It's just in a different language. Don't hand it off to python (or whatever mainstream lang) programmers, hand it to array programmers and they'll do just fine. If I were to be provocative I'd say that the J is vastly easier to read write and understand than the equivalent in any other (non array) language.
- erik_seaberg 3y ago> will a junior developer, someone at the very start of their career, struggle to understand this code That guy’s entire job is to become the expert you need. It’s a bad tradeoff to permanently handicap your experts from communicating clearly and concisely to each other, just to accommodate the start of his learning curve. It’s also not doing his career any favors, having to work with worse code for the rest of his tenure.
- gcmeplz 3y agoI think sometimes "clever" is just a term for bad code that you don't like. The clever-code react example doesn't seem like a good example of clever code to me—it just seems awful! If you were do something clever for that function, it could look like this: function extractDataFromResponse ([Component, props]) { return _.pickBy({Component, props}, Boolean); } I'm cheating by using lodash, but I think this code is a fairer comparison to the unclever example that's given in the article.
- roryokane 3y agoNice simplification of the “clever” code. Lodash docs for anyone curious: https://lodash.com/docs/4.17.15#pickBy https://lodash.com/docs/4.17.15#pickBy Here’s my version of the “clever” example that doesn’t depend on Lodash. It’s longer than your version but still simpler than the article’s: const extractDataFromResponse = (response) => { const [Component, props] = response; const dataIncludingUndefinedValues = { Component, props }; return Object.fromEntries( Object.entries(dataIncludingUndefinedValues).filter(([_key, val]) => val) ); };
- thesnide 3y agoThe biggest issue it will solve is not even technical, it is management https://blog.pwkf.org/2022/09/18/always-optimize-for-dummies.html https://blog.pwkf.org/2022/09/18/always-optimize-for-dummies...