8 ms·
Great post - the one word missing, "maintenance." Most programming work is done maintaining/enhancing existing code. The greenfield work is a piece of cake by c
by SKILNER 4y ago
Great post - the one word missing, "maintenance." Most programming work is done maintaining/enhancing existing code. The greenfield work is a piece of cake by comparison.
You want to do the hard stuff? Maintain existing code you're not familiar with.
The problems around maintaining unfamiliar code are huge, largely unsolved, expensive and risky. There's a little branch of computer science called Program Comprehension and no one pays any attention. Though most programming money is spent on maintenance.
- danielvaughn 4y agoI always tell my clients - the difference between writing code and maintaining it, is the difference between raising your hands and keeping them raised indefinitely.
- baq 4y agogreat analogy. totally stealing this.
- iovrthoughtthis 4y agopowerful image!
- deepakkarki 4y agoOr the difference between conceiving a child and raising one :)
- metaltyphoon 4y agoI always smile when a green field project starts and then they claim its “Clean Code”. No, you won’t known if it was clean code until years down and the system will need updates. Then and only then you can reflect and see how hard it was to changes things in it.
- tasuki 4y agoFully agreed. No matter how "clean code", the next person or team is immediately going to label it "legacy" and complain endlessly about all the choices made by the original author(s).
- Jensson 4y agoMany dependencies? Updating them is hell, remove dependencies and just write the utilities we need so we can update to latest easily! Few dependencies? Too much reinventing the wheel, delete all that code and add dependencies! There is no perfect code, can always make different trade-offs and move things around.
- deleted 4y ago[deleted]
- tacitusarc 4y agoMy metric for clean code is how quickly a developer unfamiliar with it can understand it
- agumonkey 4y agoIt seems that anything successful, for any given era, is the one thing that minimize time to understanding better than others.
- simonblack 4y agoMuch as we denigrate COBOL, that is still its greatest advantage. Yes, it's wordy, yes it's old. Yes, it needs to be really updated. But it's still easier for a new hire to understand the COBOL old code than any other old code.
- Ygg2 4y agoI've never had any problem digging into any Python codebase. Even magic stuff like `@attributes` is easily searchable.
- danielvaughn 4y agoHa, love this one.
- agumonkey 4y agoraising someone else's that is already 4yo and emotionally harmed
- pojzon 4y agoThis hits home. You win. Maintaining and cleaning up a mess someone left behind are two different things.
- sdashner 4y agoWhenever I do a big refactor it’s so that it will be messed up my way instead of being messed up their way.
- deleted 4y ago[deleted]
- bsedlm 4y agoyes. I wish I could somehow get to work on a blend between: a decompiler, debugger, emulator, static analyzer, memory profiler, and so on. The idea being some kind of a runtime for assembly code which does not actually execute the program but allows one to understand it in different sematinc levels, or dunno.. this is a very raw idea. needs a lot of work (and a lot more knowldedge) to set down. too bad none of the professors that I was able to meet were really interested in this kind of thing
- Banana699 4y agoI think dynamic analysis is incredibly powerful and criminally underused in IDEs and other dev tools. I have thought of an idea about 6 months ago that has been fermenting in my mind since then : what if (e.g.) a Python VM had a mode where it records all type info of all identifiers as it executed the code and persisted this info into a standard format, later when you open a .py file in an IDE, all type info of the objects defined or named in the file are pulled from the persistent record and crunched by the IDE and used to present a top-notch dev experience? The traditional achilles's heel of static analysis and type systems is Turing Completeness, traditional answers range from trying and giving up (Java's Object or Kotlin's Any?), not bothering to try in the first place (Ruby, Python, etc...), very cleverly restricting what you can say so that you never or rarely run into the embarrassing problems (Haskell, Rust,...), and whatever the fuck C++'s type system is. The type-profiling approach suggests another answer entirely : what if we just execute the damn thing without regard for types, like we already do now for Python and the like, but record everything that happens so that later static analysis can do a whole ton of things it can't do from program text alone. You can have Turing-Complete types that way, you just can't have them immediately (as soon as you write the code) or completely (as there are always execution paths that aren't visited, which can change types of things you think you know, e.g. x = 1 ; if VERY_SPECIFIC_RARE_CONDITION : x = "Hello" ). You can have incredibly specific and fine-grained types, like "Dict[String->int] WHERE 'foo' in Dict and Dict['bar'] == 42", which is peculiar subset of all string-int dictionaries that satisfy the WHERE clause. All of this would be "profiled" automatically from the runtime, you're already executing the code for free anyway. Essentially, type- checking and inference becomes a never-halting computation amortized over all executions of a program, producing incremental results along the way. I have ahead of me some opportunity to at least have a go at this idea, but I'm not completely free to pursue it (others can veto the whole thing) and I'm not sure I have all the angles or the prerequisite knowledge necessary to dive in and make something that matters. If anyone of the good folks at JetBrains or VisualStudio or similar orgs are reading this : please steal this idea and make it far better than I can, or at least pass it to others if you don't have the time.
- di4na 4y agoThere have been interesting progress in this space from a different angle of attack. o11y (Akita, honeycomb, ebpf, prodfiler, ...) and "Learning from incidents" are two of these angle that have really built on this idea that "understanding what the system does in prod" matters far more than "writing it right the first time". It is also the thinking we can see supporting a lot of the early devops movement.
- tppiotrowski 4y agoWorking on old but popular software is where legends are made. You need to be methodical about changes. How do you make changes in a million line+ codebase without breaking anything for millions of existing users? This challenge is reserved for the finest engineers on the planet. These are the people you want your desk near when you start your professional career as a programmer.
- baq 4y agothis is simpler than it sounds - the process trumps any engineering stardom. the process is king. the process is love, the process is life, quite literally. getting any change in there isn't so much fine engineering as it is wrestling with layers and layers of process, where every layer has been added due to a monumental f-up in the past. it's an environment where getting any change committed into a repository usually takes weeks, unless one of processes for sidestepping the process is invoked.
- dlojudice 4y agothe problem is that a large amount of code produced is to support the accidental complexity of the software (let's call it infrastructure code) while the value generated by it comes from its essential complexity, that is, the application domain, as cited by the article . while Domain Driven Design and Clean Architecture are a first step in the right direction, languages and frameworks are still limited in supporting these ideas. It's almost insane to think that once you have a modeled domain you need to replicate them in resolvers, types, queries, etc (for graphql), resources, responses, endpoints (for rest), etc, etc. to reinforce the point of the article and the one brought by @SKILNER, I believe that the great transformation that is to come is in maintainability through a focus on the domain
- picsao 4y ago
- galdosdi 4y agoI think, as OP alludes, ultimately explorability is the heart of the problem that stops people from writing code this way. If you don't care about other people being able to read and explore your code without a lot of preperation, you can go full hog creating layers of DSLs and metaprogramming, and with enough dedication you can end up with all your real domain level business rules in one place separate from the "infrastructure" But if you do this, you end up with a codebase that is hard for a newcomer to ask simple maintenance questions about like "What are all the places XYZ is called from?" or "What are all the places to write to ABC" etc So an experienced developer learns to limit their metaprogramming so their code retains easy explorability at the expense of long term sustainability. Golang is kind of an epitome of this kind of thinking. Lisps are kind of the epitome of the opposite I guess. This is what's behind the paradox where a good dev working alone or maybe with one very like minded person can produce a level of productivity you can't match again as you add developers, till you have way more developers. The dip represents the loss due to having to communicate a common understanding of the codebase, that doesn't get adequately compensated for till you've added a lot more people.
- fleddr 4y ago
- deleted 4y ago[deleted]
- commandlinefan 4y ago> The problems around maintaining unfamiliar code are huge, largely unsolved, expensive and risky Not to mention massively underestimated and unappreciated by non-programmers.
- samsquire 4y agoA software engineer, coder and developer's responsibility is to manage technical complexity and solve technical, data or business problems. I'm not sure if we are respected for this capability. Do people want to pay for what they do not understand why it is so hard?
- kanzenryu2 4y agoAlso possibly including: install very old OS version, get libs and dependencies to some old version, and maybe update to a slightly newer compatible version, but not the latest. Create mock services of complex back end systems for test cases. Convert https connections to http for testing, or use unsupported TLS versions and protocols for some connections. Then you can get started!
- agumonkey 4y agoI sincerely don't know why uni don't make more classes on that only. - pick any software - try to change something - give a precise impact analysis - generate a few potential implementation paths - measure how fast you did all that and what failed / worked
- AndyMcConachie 4y agoI agree. A fundamental problem with how we teach programming is that we focus on writing, instead of reading, software. To borrow terminology from the language arts; we don't focus enough on reading comprehension.
- salawat 4y agoThis. So much this. I have devs I oversee vomiting forth code with nary a thought of how it integrates with anything else.
- schaefer 4y agoexactly, Just like getting assigned book reports, but for software nerds!
- johncessna 4y agoAt the University I'm associated with, there was a discussion about why more 'practical' classes weren't taught. The answer was 'We're not a trade school.'
- vlunkr 4y agoI've also wondered if it's time to back off on agile a bit. Or at least "agile" as it is implemented generally, which means we get to make up new requirements every two weeks. In my experience, the hardest maintenance problems occur because we're trying to re-shape code into something that the developers never knew would be coming down the line. Spending lots more time up-front deciding requirements would go a long ways towards more maintainable code.
- BurningFrog 4y agoThe part of Agile a lot of people ignore is the phase when, after your code works, you spend as much time as it takes to make it well structured and readable to others.
- BurningFrog 4y agoBTW, this is the Design Phase in XP! You first write the code, then you design it. Genius!
- andsoitis 4y agoIf you think of code writing as a process of organizing your thoughts, exploring/understanding a domain, and articulating it iteratively (for code/run/debug loop), then your pithy comment seems perfectly rational.
- bmitc 4y agoIt's interesting to me that people are so into Agile when it simply doesn't work all by itself. How many books, conferences, certifications, practitioners, evangelists, etc. does it take to make a paradigm, supposedly the paradigm, of working actually work? Every company I have worked for that used Agile basically had broken processes and were not productive. The one job where we did not explicitly use Agile was actually a place where I produced the most useful work. If the number one answer to we're using Agile but it's not working is "you're doing Agile wrong", then maybe Agile isn't the solution? The way I worked at the place that did not have an explicit process was one of switching between agile and waterfall methods. Early on in the projects, the process was primarily waterfall, defining things up front, building prototypes, laying out the project, etc. Then once passed that stage, projects would enter into a more agile or iterative process. Then as new big features came in, back to waterfall and then switching to agile once that stabilized. This worked quite well.
- synergy20 4y agoA huge opportunity here: ways to assist developers to figure out how existing code base works by generating code flow, class hierarchy, etc. yes there are a few tools on the market, nothing really standout though, maybe it's for AI/ML to innovate in this field. Linux kernel is well designed, in that I can add code relatively easy into its subsystems, it's those Object oriented or FP code base that bothers me the most, especially when they're large, often times they just made me feel hopeless, good tools desperately needed.
- bmitc 4y agoI would argue that a huge or maybe even the primary reason why maintenance is so hard, though, is because a lot of software was originally not written "correctly", that is without maintenance and longevity in mind. The hardest part of maintenance, in my experience, is that programs were developed under needless or incorrect constraints and then expected to be magically maintained. There is a huge downstream effect of decisions made early on in a software system's life. The story of "just get it working" that evolves into "now that's it's working, don't change it but add these new features" repeats itself over, and over, and over. It's not surprising why maintenance in systems developed like that is hard.
- gitgud 4y agoA similar concept is the maintenance of physical world machinery, it's also often overlooked, but a huge industry even compared to manufacturing the machinery it self
- the_duke 4y agoI see this largely as a language failure. Alot of popular languages make it really easy to write code, but hard to maintain it . It's one of the reasons I like Rust so much,even for relatively high level code. It has one of the srictest type systems and std/library ecosystems of any language in existence, which tends to make code very robust and easy to refactor. I often wish for a language that has a similarly strict type type/ecosystem but is higher level. Swift is quite close, but very Mac OS centric. Haskell has exceptions, which are often used for error handling, making code less robust (plus the ecosystem is small). Other languages like Ada/Spark or Idris are way too fringe...
- kinjba11 4y agoWhat about F#? Often seems underappreciated
- thrown_22 4y ago>Alot of popular languages make it really easy to write code, but hard to maintain it . The language you're writing in has next to no meaningful impact on long term maintenance. When you're trying to do software archeology on why a function even exists the types it has will not help you figure out it's there because between 1996 and 2002 there was a tax rebate on capex for rocket development. You need human understandable documentation, not fancy language features. This is no where near as sexy so no one does documentation and we're in the middle of a digital dark age.
- kinjba11 4y agoI disagree. Language does matter for long term maintenance. For instance with a tax rebate. Static typing - a fancy language feature - can immediately tell you the function deals with money. +1 for maintenance. Static typing with a solid IDE will immediately reveal everywhere the function is used. +1. Languages shepherd you into certain designs or mistakes by making some things easier than others, such as when class inheritance can be easily abused in OO languages, cryptic one liners are easy in Perl, point-free cleverness in Haskell, monkey patching in dynamic languages, etc. +/-1 depending. Per documentation, languages come with tools and best practices: Javadoc, Godoc, Rustdoc; C# even has a dedicated comment syntax for documentation - a fancy language feature. +1. No one does documentation, until the language tooling forces them to. That said, BG (Before Git) and widespread use of source control, as in '96 to '02, was a dark age. We know more now.