Yeah but it is more on the scale of if the entire company sat at that one desk daily. And even better the desk isn't broken the people that are sitting at it complain about the chair you didn't design or are sitting on the end of it and saying they can't see the screen well because it is 6 feet away.
software is nothing like a desk, you can't clone desks (but it takes less than a day to build one from boards). perfect cloning at near-zero cost is not something you can just wave away. it affects literally everything in the product lifecycle. in a way, it contradicts capitalism, which is built around scarcity of commodities.
@@ZombieJigbeing a natural language with lots of exceptions and a huge vocabulary and a lot of ambiguity sure makes you harder than a programming language with defined syntax and 50 keywords at most :p
As a junior I read an article about "all code is garbage". At the time I didn't pay it much attention. I went through my programmer puberty with design patterns. Clean malleable code that somehow was future proof. Now. I'm past programmer puberty. Every abstraction I have ever written has fallen short in some way or another. There is no such thing as future proof code. The best code is the one you can quickly delete and rewrite.
Hmm maybe, but I swear there are certain abstractions that can increase your chance of future proofing your code... Pure functions, inversion of dependencies, loose coupling, embedded DSLs, passing through keyword arguments, decorators, maybe even monads O_o.
@@aoeu256 Yeah, I definitely find you can write software in good ways and bad ways and some design patterns are much easier to upgrade. A big key I find is having code that will hopefully create errors at compile time. Things like Rust enums which force exhaustive patterns, typescript "satisfies never" in the default parts of a switch statement and similar tricks have saved me a lot of time. So that way if you ever add in a new type at some point, your compiler tells you you've missed out on handling the specific case for it. And the more your compiler can tell you and detect, the better, because you will make stupid mistakes so setting it up where the machine double checks for you is key.
Good abstractions are replaceable, which means good abstractions meet your criteria for good code. I mean I have software examples that have held up to the years and stayed maintainable, it's more so a question of whether or not people put in the effort to do the upkeep, and the more complicated the code base the more upkeep there is, but the less upkeep you do the more the complexity drains productivity. The more tech debt you create the more likely you are to just throw the baby out with the bathwater and recreate something with a better idea of what is currently needed in mind. Requirements change, and therefore so does software, you can't see the future, and eventually things might change so much that the current solution is just not going to work either. So there's still reason for good code, and there's still reason for putting the the work to keep the code base manageable, because on the flip side there's been times when we've moved quick to create software, changed it a bunch, and are stuck trying to dig ourselves out of the hole we were essentially forced to create. So yeah, everything is a balance.
There are serious issues in this industry that is at the core of modern economy. First of all you can’t write lightweight code with all the frameworks and everybody but the coders seem to have an opinion these days. Coders can take so much learning in just a few years and stay productive. There are also massive management issues with allot of people not related to coding fighting for position, even HR has been on top of coders in the past years. And there are actual business issues because nobody listens to coders, I am getting close to 20 years now and have an economics degree, I see these things and know how managers are trained. I was working for two years with an agency on a big Website (10+ countries) with all that it means (sales, CMS etc.). We never had time for scaling, they were like “this guy will have a pause in two weeks, let’s add another feature”. What do you know, sales go up in UK and wanna start selling in France. A dip in performance obviously. Before I was done explaining they should upgrade the hosting and we should start getting prepared for cloning to individual serves for each country (I had that prepared since day 1 and it was the cheapest way to scale for them) they changed management and started over with a basic Website and an external sales platform that, obviously, started two products for the two countries. This was an agency I was working with at least two managers mostly on vacation, I was not that well paid and God knows what they were charging this client. So yea, you have allot of bad things working against you on top of actual coding. Good thing is I see a shift back to vanilla at least for the Web.
Lol, you really hit that nail on the head @24:15. I came into where I work and the repo was 10gb+ in size because devs before me were keeping data with the code.. I rebuilt everything from the ground up over years.. took care of the code base and developed a proper pipeline.. the repo is now
Just because a famous framework has non-readable code, doesn’t mean readable code is bad. On a big, long term project where new people will keep coming in, it’s far more important to make code easily readable. If each function states clearly what it’s doing, reading code is similar to reading a story about what that code is doing.
I’ve been an engineer, product manager, solutions consultant and sales manager. As soon as I stepped out of the engineering bubble I immediately got the “good enough” mindset. Once you realize that perfect code doesn’t pay the bills, and that code is only a means to an end, you get it.
The worst part is suffering the agony of peer review with fresh graduates who's heads are filled with "clean code" practices that don't work in production.
I don't think we're taking about perfect code here. I think the major issue is when the product has massive architectural issues and no one except engineering cares. If you've made bad decisions about code structure or how the product is deployed and product and management don't let you go back and fix it because we always need new features, then the product could enter a death spiral. Additionally, paying down tech debt allows you to build features more quickly. I think I'm some ways, product and management can definitely be short-sighted when they adopt this good enough mentality. It's think about the next quarter rather than the quarter five years from now.
People say this and then pack a bunch of complex logic behind some weird type or function and suddenly you have no control and are locked in some pattern that cannot possibly be best for all the cases its marketed for
@@yuriy5376 make it as simple as possible. As the software requirements become more complex, then build on these simple constructs into more manageable solutions. That’s how software must be designed. That’s where I think things like DDD _could_ be useful.
Our job is not just to make it simple. Our job is to take incredibly hard problems and make them look effortless. “Effortless” software is so slick and easy to use that it seems from the user’s perspective that it must have been easy to make. …which sadly then leads to bad management killing off top performing teams because they just spent the last year “rescuing” a shitty team and believe that their “newly improved” team can clearly do such a simple thing better than the pathetic team that’s currently managing it. 🤦♂️
I doubt very much that the person who wrote the Rollercoaster in Excel thought that they were using the right tool for the job. Its more like doing it because you can, not because you should.
He never claimed the person thought it was the right tool, he used it simply to prove the point that you can use many tools to do a thing and if you're good with the tool, it would appear it was the right tool for the job but really it was all the developer, not the tool
I do think in the world of enterprise LOB applications that readbility is almost more important than anything. When the technical complexity is low but the domain complexity is high, code readability is important since the code is your source of truth for how a business process ACTUALLY works.
What's lost in Prime's take is that he is hyper-focused on 1 long function. When you talk readability, you are talking about the entire repository, a feature, a module, a function in that order in terms of importance. You can look at a long function and say "look how unreadable that is, it's so long!" as a kind of gotchya for people who say that readability doesn't exist. What is missing is the context of that long function. He skimmed right past a small function that leverages a long function and guess what, it's crystal clear what that small function does because of the lifting done by that large function.
Real. I work on automations for business processes and the function is how money literally moves between subsidiaries, for example. And coming from the web to this job 4 years ago made me really appreciate simplicity. When implementing a single process without the need for too much reutilizarían or branching, I just write a single big function that does the thing, with maybe a couple of properly named utils functions. Having to jump through 4/5 functions with vague names between files is a nightmare when 2 years later the client wants to add a new use case. Nobody remembers what the thing actually does. Not even good documentation helps sometimes to understand code from “clean coders” (not derogatory lol)
This this and this. There’s a reason we haven’t migrated off of mainframes with 30+ year old code that still hold up the stock market, flight systems, and other industries. Rewriting/rebuilding would mean you would have to trust you’re not breaking 30+ years of business logic that nobody really understands
What my previous team did is exactly the reason why they're now in a very bad position, they settled for "good enough, it works" and now they have a huge but fragile infrastructure they can't maintain nor change without a massive refactor
I'm a HW guy. Have taken on a Java project that ultimately ends up as a piece of hardware from the code output. To learn Java, I bought Java beginners by Oracle two years ago. Yesterday was the first ever JUnit for the project in its 8yr life! I've had to do this because each new HW product starts as a new J package, with existing code copied / pasted / tweaked by overrides. It's an enormous intertwined f'in mess that now does not work unless one knows all the gotchas. When I mentioned this to one of the original coders, his reply was "it was good enough to get the job done". That guy has a PHD and insists on being called Dr. I call him Mr to bring him down to earth.
@@BobBeatski71 I worked at a hardware company myself, manufacturing always takes priority over code, and requirements are never clear, it's just not a good experience. Hell, the IT infrastructure sucks in these companies in general, you can't always develop software under normal conditions. So I see why people settle down in a sense, these companies never prioritize good software. But nonetheless, it should be a priority
Exactly this. Whenever people say “just get it working”, all i hear are people playing not to lose, instead of playing to win. “By the time you need to refactor the code, youve already won because your product took off.” Yeah, until it dies a month later, ie the current state of the gaming industry and nearly every website. The fact of the matter is: you need to “just get it working”, in the present sense, and the future sense. Otherwise, youre not playing to win.
my last company did this. "let's use stored procedures because they're easy". literally thousands of stored procs later, upper management says let's move away from oracle due to cost. cool, who wants to rewrite thousands of procedures from oracle flavor to another? nobody? not to mention the troubleshooting hell when you're using debugger and then reach a stored procedure call. everyone dances with joy at this point yes? no? 😂
This is the state of the software I work on. I tried multiple times to get them to halt and rethink, but nope. They just pressed on, running on that feature treadmill. And now it’s all unmaintainable garbage that I honestly can’t stand to look at.
I agree that experience in many ways makes software dev more difficult. I was at peak productivity/effectiveness when I was still naïve of all the best practices. It is commonly understood that 'cowboy' coding is a bad thing but in over 30 years of doing software dev and programming, it is usually the optimal strategy. Fancy tools, methodologies and paradigms are massive technical debt. Good devs know how to KISS. The vast majority of the time, good code does not mean making bulletproof code, it means making it as simple as possible without painting yourself into a corner.
its a good approach to anything in general. You just learn over time, that people just don't give a sh*t and everybody has agenda, so why bother go extra miles anyway. Just survive and do the minimum and you're good.
What I find hard is getting the rest of the devs on board though. So many devs practice dogmatic clean architecture for instance thinking it's the way. Takes alot of time and energy to change that around.
@@paper_cut9457 Obviously no offence taken. I'm an analyst as well and I've seen the disaster code firsthand. I like to call it Buca di Beppo code because that spaghetti code is family style.
The NP + NL situation, to me, is actually what ChatGPT is PERFECT for. It allows you to explore a new problem, and relate that problem to a language to already know. ChatGPT is not good for 90% of the things people think it is, but as an interactive learning tool, it does GREAT! It can't teach you fundamentals, but it helps you more broadly apply the fundamentals you already know.
Someone in chat said "Clean code is opinionated" I'd say "Opinionated code is good code" PARTICULARLY because it's "led" by a person, rather than an amorphous blob of principles, patterns and expectations that aren't very cohesive.
I have a simple rule. code complexity should match the bussines requirement complexity. I naively started a side project that I thought was simple three years later no matter how much I refactored my code it's just complex. I learned from this that there is no such thing as a simple "real world" software. if you software is simple it has "no value" and no different from the many software projects I completed as a cs student.
If you haven’t read The Mythical Man Month, you might enjoy it. Brooks spent a good chunk of the book talking about inherent complexity (the complexity needed by the problem) versus accidental complexity (the complexity caused by the methods used to solve the problem).
I love what youre speaking about in the beginning, I am currently developing a feature at work and everything is new, I am a graduate dev trying to implement a masstransit feature and its honestly fun tbh, but productivity is slow because I am a) googling everything, b) trying to write good unit tests c) message queues are hard to debug haha. But tbh I think I am nearing the end and its awesome, feel like I have personally learned a lot, but I feel slow, too.
Good to see different takes that still align overall. From somewhere else I'd taken "Write code that someone else can understand 6 months from now". That someone usually being yourself.
Well, the 3 months figure is worrying. Personally, I always throw-up seeing the code I've written in the past. But in most cases, I only have to rediscover it every 2 to 3 years generally.
Yes, sometimes it's a pleasant surprise. I find that mapping coding abstraction to business abstraction increases the likelihood of this happening as the business requirement changes in ways that the code base already anticipated.
We use around 20-40 msg functions to read from a mbs server. I rebuilt it to read the entire database with one msg using sequencing. It does the same thing, but WAY more advance and FASTER than I'd ever thought in my previous years.
19:10 I agree with your friend, and I've been saying this for years. We've known for years that readability matters. If functions are too short, readability suffers. But when a logical block takes 2 page scrolls, that's also unreadable. Trade-offs, people.
"the person who works on it can continue to work on it." What if a different person has to start working on it? What if they quit? What if the project needs more developers to scale it up? What if they demand double the salary and a stake in the company for half the hours or they'll leave? What if they take months off for maternity leave? Is it gonna be a black box until they come back? When they do, are they even going to remember how their own code works? Part of the problem with bad code is that when anyone else needs to work on it, it becomes an intractable problem. This isn't to say you need to turn everything into maximally encapsulated OO, or 10-line highly nested do nothing manager functions, or increasingly nonsensical inheritance trees, or for that matter stateless functional code. What it does mean though is that someone else should be able to read your code and be able to figure out how to change it without understanding how every line of the codebase is coupled to every other.
I've been a dev for 30 years, it's one of my hobbies as well. I've been trying to get better every day but I still feel average. Why? Because of the complexity of multiple conflicting goals. I very, very rarely get to feel like "this is the best solution" because everything is a compromise. I think there are better and worse compromises but most of the time what I feel is a slight disappointment. Also, it doesn't help that every OS, every programming language and every API is also a bunch of more of less annoying compromises. I wish computer science was more of a science but also that the industry cared a bit more about what the studies indicate. One corner of the industry is busy reinventing the broken javascript wheel every couple of weeks and the other corner is bolting more crap on Java.. but we're not ready for any kind of paradigm shift because most people don't want to learn new things and like Prime said the "best tool for the job" is just the language&framework one is the most comfortable with.
19:10 This is something I believe is a good way to fight bad abstraction. For me, I've been phrasing it as "The correctness of the code should be locally obvious." This is something I started thinking about when I had to dig down many branching levels to see what a function did, then I had to do a scan of the project to see how an object was initialized, so that I can know which class to further dig down to see what function was actually being called on the object, which again required tracking down the various ways object's members were set. There are 2 paths that I know of to fulfilling this guideline: make the code local or make the abstractions robust. Good libraries are an example of robust abstractions, where you can reason about your program without having to read the library's source code. Though even if your abstraction is robust, someone who reads the code will probably need to learn your abstraction to verify correctness, so making the code local is generally a strong choice. (Re-listening to the clip, "you don't have to learn new abstractions" is mentioned, so I like double agree with this guy.)
Atomic pieces: Regex to scan important instructions/data from robot code. Small features: Robot motion point joint knuckle flipper, code formatting, comment injection, various data extractor from running robot programs, setup validation tool, etc. Everything together: General robot commissioning tool.
Thanks Prime for your incessant hammering on not abstracting. I'm currently writing new docker containers and systems for our cloud at work and started to abstract. Then remembered your yelling about it. I killed the whole project and restarted from scratch, no abstraction, just simple neat sequential code. And am thankful I did :). You are right, experienced programmers really got an abstraction problem (me included, been writing code around 15 years now). Good fortunes to you good sir o7
Really agree with you on the function length. I once worked on a code base with hundreds of one-time functions, many just calling other functions, and often badly named. It was so hard to track the control flow without a debugger and even with it required infinite working memory in your head. I definitely do prefer well-structured long functions over a multitude of small functions.
At 16:20 tiny pieces are brilliant. Like Lego pieces vs puzzle pieces. Puzzle piece can fit only in one place, Lego pieces can be rearranged and reused. If I am not mistaken that's a part of Composition over inheritance
I'm so glad my manager owns the tiny company he does. I never have to worry about being told what to do by 10 steps up the corporate ladder. And it's such a small team that my voice is important. I'm able to code my best, be comfortable, and have positive motivation. The reality of most people's software engineering jobs is terrifying to me. And hopefully I never have to understand that experience myself.
Small Focused Functions is bliss. But I might be biased as I prefer functional programming, and thus it makes perfect sense. But then what the point of that is that the functions does one think, and it should be quite obvious what when you just read its name.
We need to escape from our code fetishism and see things from the other side of the business to realize that if you don't know the in-depth and minute nuances of the domain you are trying to model with your software, your software will result in accumulating overengineered, convoluted designs and features that don't bring any value, advantage, or profitable innovation. That is what the people who are paying/investing need. So, we have to be good at two things: coding as a means but attached to business-relevant goals. DON'T CONFUSE business goals with features. This is the fatal error that most of us in hardware and software engineering have committed in the past.
We rather need to escape from our commodity fetishism. - Do you like coding? - Oh yes, so many business opportunities. - What do you mean? - I created my company last year. - Ok, but what about coding? What type of software do you make? - I make software with tremendous profitability. I'm sure my company will double its revenue this year. - What's your favorite language? - $$$$$$$$$$$$$$$$$$$$$$$$$$$$ - Do you have some advice for a beginner developer like me? - Yes, you really need to see things from the other side of the business. Think marketing, human resources, market research, balance sheet, assets, merchandise, shareholder, industry, sales, innovation, efficiency, productivity, business model, management, cash flow, market segmentation, customer loyalty, distribution, logistics, expansion, competition, branding. - ???
Back in my algorithms class in college I learned about overdoing the concept of very small functions / large abstraction chains in an unexpected way, and the lesson keeps revealing itself in new ways. Mergesort... You simply break the array into two parts, merge sort each of them, then merge them together. This is great when the array is 1000000 elements, and 500000, and 250000, and so on. It's not so good when the array length is 16 due to the overhead of the recursive calls and that dividing something by two gets you fewer and fewer shaved off elements each time. Indeed, once you get below a magic threshold of about 16 or 32, it becomes more efficient to simply insertion sort instead of continuing to subdivide... To "just do the thing" instead of offloading it to more and more subdivisions. Though this is performance vs code style, I think it provides some intuition that some abstraction is good and necessary... Merge sort is more efficient than insertion sort. But you can overdo it. A 1000 line function is probably bad, but a 100 line function might be as small as it makes sense to be. Breaking it up further would just waste not only the developers time, but the readers time jumping from useless function to useless function. I think this goes for many concepts not only in computer science but in life. TLDR; Diminishing returns, use common sense over dogma.
if you don't feel doubts while writing, it's probably going to be bad. Whatever your current level, you should be aiming at least slightly higher. It's not about how many design pattern you can cram into your code but the overall coding efficiency, code simplicity and performance. It's about looking for new angles. Let's take the example of the APIs of the modules (JS) you can refactor them for an eternity and still find better ways. How to be concise, performant, readable, how quick people will use what you created and how good the result will be for them.
24:35 living right now, and is so true. When I started 16 years ago, I was taught that the most important duty in programming was keeping a good eye on the code you needed to maintain, consistent tabbing, etc, and nobody on my career was careful enough to keep the codebase nice and clean.
25 years in the industry and the main thing that goes through my mind when writing software is "will someone else be able to maintain this without wanting to end their career as a software developer". If you write code that no one else can maintain, expect to maintain that code for a long time :) I agree with the "readability" points though, in fact, I agree with the majority of what you said around the state of code and I have added to the mess LOL I also maintain that the more generic something becomes, the less useful it is. Some real gems in here
19:01 this is exact reson of this recommendation. Because you divide your 200 line function in 5 smoller ones, with names that explain what this part does, and if you have static types it even better, because you can see what set of data you need to pass there and what it returns
Completely disagree with his take one clean code. I’m not referring to Uncle Bob either. Clean, readable code is a thing and should be something that’s desirable. There are few instances imo where ugly illegible code is acceptable due to quirks and performance. Rarely are devs programming at such a level. Widely used libraries or not. Ugly code in most instances is lazy code.
Please try to understand what he said! Readable code is desirable and you should try to write the best you can, but you should not use the phrase 'clean code' for that. Even if you don't mean it, people will think of Uncle Bob's clean code. Imo, even if somebody likes Uncle Bob's clean code style, it is not an universal 'you should write like this' clean code
You should just design ur system like how it should be and not have clean code in ur mind as you are coding. The problem is people who advocate for clean code or readable code will often write code a certain way and preach that it is better because its is more readable/cleaner. Clean code should not be part of your design decision.
I am a huge proponent of what you called "eyeshot development" here. I've been using the word "locality" for the idea, but "within eyeshot" is really nice in how plain and not-abstract it is. Opposite of "spooky action at a distance". If I change code waaaayyy over there somewhere, and it breaks this code over here, that's a non-local change/effect. If some function in that other source file mutates this data that's being used by code I'm looking at here, ditto. Low/poor locality of stuff that's related and coupled. Ideally we'd make proximity/locality correlate to relevance/coupling. If I need to read/see both anyway, maximize locality, get them close to each other. It's obviously not supposed to be an "infinitely strong" rule - it doesn't always outweigh everything else. All best practices are weights that pull one way or another, better code is better balance of those pulls. And locality/eyeshot is definitely one of the pulls. Our life is better when all *relevant* information is as close by as possible. Same file, same screen. Do we need to know *that* code to understand/verify/change *this* code? Then it should be nearby.
You're not supposed to be changing the kind of code that would have that sort of effect, though. Such changes should be breaking the contract, and you shouldn't be breaking contracts that are already in place.
RUclips has recommended this person to me before, and I didn’t realize he was a software engineer. He has a very interesting video about why insects are drawn to light and why they circle it.
4:46 How about working on the logistics of a product ( SRE before SRE: plumbing, instrumentation, tooling, etc) only to have the product launch cancelled two weeks before public beta. Even better, ( which most people can't believe ) agreeing 100% with management that although the product would be successful, it would distract from a sudden and rapid change in the competitive landscape. "Hey Ted, just an FYI and you didn't hear this from me.... Jeff Co. are signing revenue share agreements with the big 6 for variois thin round pieces of plastic. " Option A: spend marketing $$$ launching a UK service ( first intl expansion ) as planned for the past 18 months. Option B: Cancel above project and pour $$$ into price cuts, domestic improvements to keep Jeff Co. from entering into an easily profitable enterprise given their existing large primo user base. Obtion A would have been validating for all the blood sweat and tears... but selfish upon reflection. Option B helped keep Jeff Co. at bay.
As a junior I was eager to start coding and solve problems because that is what we are taught to do. Through experience you become a senior and then you become afraid to start coding because you know you will fuck-up eventually. 🙂
the no googlin thing is so tru. i switched to linux cuz of prime and broke my pc 4 times with internet, 5th time i didnt. not being able to Bing Copilot and copypaste made everything fun i miss windows
im deff not missing it. so far every game i wanted to work, works (league/dota/battlebit/wowclassic) and vscode and even GIMP open just... instantly. idk how this is even possible. this whole symlink thing is pretty daggon neat too. and search is instant, cloudflare warp just works... second time ive tried linux and first time able to stick with it, all thanks to bing copilot being so good at answering everything. only thing i hate so far is the default nautilus skin but i havent tried changing yet.
Don't abstract until you need to abstract. It's that easy. If it's not an api, it doesn't matter. Abstracting it later is easy. On the other hand, don't abstract minutia. If there are three similar processes, but they're too different for a general abstraction, just don't. Copy and paste is fine here. Don't over confuse.
5:03 My way around this is to just lean into it. When something is bullcrap, I agree that it's bullcrap and want it to change. It frustrates me, too, and I should express that. It not only helps user morale, but sharing in the frustration of people working under me also helps with morale, because they also don't want to be unheard.
I am a fan of the smaller functions, and then creating new classes if you have a giant class with a bunch of little functions. It makes it so much easier to change/fix an issue in just one place. I am not a fan of the term “self-documenting code” for the same reason that Prime isn’t a fan of the term “clean code”. This is also why I don’t dislike comments as much as other people; they help me more often than they confuse me.
Never forget : Support wants to know where they can poke to know why things aren't working right. Meaningful errors, tools to fix things without dev involvement, understanding what aspect relies on what system at a high level. How can we show where something isn't working so you can go straight to the issue.
Need to add another comment. The solution to future-proofing your code isn't abstraction, it's literally the opposite, simplification. If you code is easy to read and understand, you can change it much more easily. If it's heavily abstracted as a means to avoid having to change it, you probably made bad assumptions and it will be harder to change--plus if those predictions never came to pass, which they usually don't, you're paying the cost of the penalty all the time no matter what. That's a bad insurance policy.
I remember finding your channel a few years ago when I started learning vim and wanted to write my own vimrc and also to get better at it. At some point I just stopped watching your videos. I don't really have a reason for that, I just think that I wasn't interest in rust or other things you were doing, or the memes, don't really know. But I really like these videos like this one. It is a talk about software, it makes sense independently of the language you use the most, it is just honest takes on development process. I love it. Contratulations on the content 👏
I agree with your friend. I've wasted too much of my professional career going through 20 something functions deep on code that should have been at most three levels of abstractions away. Way too many developers think about principles for the sake of principles, and don't think about things practically.
I could talk forever on this topic, but the short version is I firmly believe the only candidate for an objective measure of "good" code beyond it simply working is properly tested code.
I don't understand your logic there. I mean one has no idea if ones software actually works unless one has tested it, at least to some degree. The degree to which one tests it shows how much you care are about it actually working. Unless you are happy to let your users test your creations.
Even the best programmers will occasionally write some pretty hard-to-read code. There is often a sliding scale/trade off between efficiency and code readability. Also other constraints may come into play. I do believe most code can probably be improved by an order of magnitude in terms of readability, but this is due to a lack of training and industry standardization in this area.
4:15 Whenever I learn a new language or tool inside a language (like ECS or a game engine), I usually try to replicate something I've done many times before, like reprogramming ball physics and connections like in World of Goo, or trying to implement compile time dimension generic geometric algebra.
HR has its uses but it's important to keep in mind their job is to protect the company, even if that means screwing over employees. That doesn't mean they won't help employees because often that is mutually beneficial to the company but make no mistake they are NOT your friend.
I feel the videos are entertaining, but for the learners--- To summarize: understand reqs, domain, standards => start small by building core pieces => THEN abstract and refactor (as needed)
A shopping list is handy. Disposable. Concrete. If you can generate it quickly, and the cost of rewrite can be kept low, why write a perfect abstract shopping list you have to adaptively decrypt every trip? - adapt to every possible period? - category of item? The epiphany waiting for most new developers is your code is a shopping list. It's rare you will get to a stage where a generative recomposition from smaller components can't be faster than perfect up-front design and abstraction. And so often then you're immortal code will still only be harder to replaced, it may not even need to have lasted the duration of creation.
At the end of the day just enjoy what you are doing. If you can find a way to not look at a problem as inconvenient but as an oppurtunity to learn and get better your life will significantly be better despite not actually being better in any objective way. It will be the same thing but you will get much more joy from doing it just because you believe it to be fun/interesting learning project.
Small functions make the individual functions easier to understand but you kick the can down the road because it can easily make the larger function using all the small ones harder to understand. I think the priority is if a functionality can or needs to be reused many times, then it should be its own function. If you split your large function into smaller ones that are only used within that one function then it was useless to split it from the start.
Bro, why surprised about HR? Michael Scott hated HR before it was a thing... That said, Primeagen, thanks for your vids. I have been doing tech/telecom engineering for almost 20 years but never learned code. Now i am, and wisdom has shown me there is an 'art' to software dev as much as 'science.' Thanks for sharing your wisdom on where/how to focus. I appreciate it.
About "readable" - the problem is that readability has subjective and objective components, and many of the objective components are relativistic rather than absolute. So yes, there are objective readability factors: human vision has mechanical and computational constraints which can be studied, understood, and optimized for (this is why newspapers and textbooks use thin columns - it optimizes for less eye saccades, and this is one of the reasons why line width in code is partly an objective readability matter). Of course, there can be physical and mental variations between people that make us more sensitive to these objective factors, so it's partly absolute and partly relativistic. There's also stuff that seems "subjective" only because it's heavily relativistic. For example, whether you find camelCase more readable than snake_case is heavily influenced by what you're used to looking at, so that can feel like purely a matter of taste when part of it is *habitualization* - and we can measure this in our own lives if we ever spend enough time away from one style of naming, and then see how we feel when we come back to it. (For example, I used to think camelCase was equally readable to snake_case, but then I noticed that even though I was instantly comfortable reading snake_case after years of programming professionally in camelCase, after a mere two-three months doing snake_case full-time I found camelCase harder to read.)
Maybe aversion to small functions and hopping is line between VIM and IDE? Becuase most of IDEs greatly improve this hoping experience. Also meaningful names limit necessary hopping too. Anway i saw once owner of the firm who have and trains x20 programmers and he opted even for two line functions but he also admitted that they select specific type of people to his teams
the web is boring, how many times are you just gonna do CRUD before you get bored? it's ok if that's your job, but there's much more to programming then just storing and presenting data on a web page (which is hands down one of the most needlessly overengineered areas of IT if not tech as a whole
@@anoh2689 not "better" as making websites is obviously useful, without the web access to information would still be limited and there's great value in it. but limiting urself to just web development to me seems like deciding to be a carpenter that exclusively only makes chairs and refuses to make anything else, it doesn't make sense. I'd say just explore what programming has to offer, do ur job as a backend/frontend/whatever u need to do to get paid, but it never hurts to do more. as for other areas u might explore: low level programming, emulation, CLI, encryption, graphics, databases, ML, GUI, embedded, compilers, simulation, data science, etc. I mean, the great thing about programming is how versatile it is, u can provide (real) value by doing a lot of things with it and adjacent knowledge in other things that might also interest u
I love writing code and creating a product. I don't care if it's bad or good. That are worries for later. I refactor as I go. But I guess it's different when you work in a team.
I believe in a clean code - as long as project is completely isolated low level code without dependencies or small application. Let's say up to 20 files and higher tens of kilobytes. Once it has like 3 layers of abstrations (and it's hard to even find all methods that class actually has), many classes that are glueing together simpler classes add logic of their interaction, interractions with gui, error reporting, it get's complicated. And then add serialization and undo stack.
HOT TAKE: I rather create code that I feel proud about, enjoy every minute of programming, and MAKE LESS MONEY, than being more efficient but having no pride on my work and only find joy on my leisure time.
Well structured, documented and properly tested code is pretty much possible and totally justifies the effort put into it, no for prototyping of course. Encapsulation is necessary for handling complex programs and teamwork. And yes refactoring is needed to adjust the code for further development. Clean code also exists! just because it's relative doesn't mean that it doesn't exist!
7:03 unfortunately “good enough” has to be the way because there’s always “just one more thing” that could improve things. I’ve lost count of how many devs I’ve seen go down rabbit holes gold plating a solution blowing out budgets beyond belief which only reinforces the “good enough” approach
The key to number 5 is to know when repeated code is repeated because of an underlying abstraction, or just by sheer coincidence. Consider refactoring the former, and think carefully before refactoring the latter
When starting a project, I usually start with a single file, implement everything in the main, until I start to notice patterns or it gets complicated, and abstract from it. That way, I progressively abstract and when it's done, I have a exactly as many abstractions I need.
Im happy after the 3rd rewrite normally. Building good software is very hard. Its not the code I struggle with but holding off until i really understand the domain im working in before diving in with both feet.
2:55. Lua! Everything else for me is a purpose language. Lua is like my hobbyist language (But I LOVE [2D] it the most). Everything else is: Python, C++ and Assembly.
My first boss (30 years ago), said that for ever 1000 lines of code there's a bug, and for every bug you fix you create another. 30 years later, I still agree!!
"the good enough approach....I hate it SO MUCH.........Because 20%-30%-40% of the time it's the right decision but it's made every time" Exactly ! I hade it SO MUCH too , for the same reason :)
To add to the 'good enough' approach. That's fine for innovation, MVP for PoC, and for fairly low risk and reasonably low visibility processes that won't charlie foxtrot other things important to an org. But for everything else, a mantra I adopted long ago "You can do things right. Or you can do them again."
25 years in coding and it work . Some things i build in the past ran with 4 code changes in 10 years. Old cobol and pl1 code worked and was good. Modern stuff gets changes all the time. People dont write code for the business anymore they are experimenting for their own skillset. Code quality does not matter because code only lives for 2 years max and the readability is not in de code logic but in the full chain of all the services involved imho
I try to only abstract when it comes to external dsls. I would for external libraries, but I find it works better to just limit its use to a specific internal library and just rewrite it rather than abstract it. It’s not as fast as abstraction but better than having to refactor my code in all million different services.
Hey! That's my video! Thank you for the shoutout!
I love your videos
are you also behind deno's channel?
@@alexandrecosta2567 Yes - I'm helping produce some of their videos as well.
You have some great takes, awesome-coding.
@@futuza thanks! :)
Do you care how many hours someone slaved to build the desk you are using? No, and if it breaks you hate them. Its not exclusive to code.
Yeah but it is more on the scale of if the entire company sat at that one desk daily.
And even better the desk isn't broken the people that are sitting at it complain about the chair you didn't design or are sitting on the end of it and saying they can't see the screen well because it is 6 feet away.
I built my desk in like 2 hours 😎
Just build it your self
@@MrDasfried that makes a lot of sense. Then when I hate myself, it'll be no different.
software is nothing like a desk, you can't clone desks (but it takes less than a day to build one from boards).
perfect cloning at near-zero cost is not something you can just wave away. it affects literally everything in the product lifecycle. in a way, it contradicts capitalism, which is built around scarcity of commodities.
My go to language is TypeScript on a good day and Polish on average.
😂
Ironically Polish is at least 100x harder to learn than TS
@@ZombieJigbeing a natural language with lots of exceptions and a huge vocabulary and a lot of ambiguity sure makes you harder than a programming language with defined syntax and 50 keywords at most :p
LOL that caught me by surprise, good one 🤣😂
I need to meet some Poles. It may just be me but the outside impression of you lot is "lovably quirky". This comment only strengthens my impression.
As a junior I read an article about "all code is garbage". At the time I didn't pay it much attention. I went through my programmer puberty with design patterns. Clean malleable code that somehow was future proof.
Now. I'm past programmer puberty. Every abstraction I have ever written has fallen short in some way or another. There is no such thing as future proof code. The best code is the one you can quickly delete and rewrite.
Hmm maybe, but I swear there are certain abstractions that can increase your chance of future proofing your code... Pure functions, inversion of dependencies, loose coupling, embedded DSLs, passing through keyword arguments, decorators, maybe even monads O_o.
@@aoeu256 Yeah, I definitely find you can write software in good ways and bad ways and some design patterns are much easier to upgrade. A big key I find is having code that will hopefully create errors at compile time. Things like Rust enums which force exhaustive patterns, typescript "satisfies never" in the default parts of a switch statement and similar tricks have saved me a lot of time. So that way if you ever add in a new type at some point, your compiler tells you you've missed out on handling the specific case for it. And the more your compiler can tell you and detect, the better, because you will make stupid mistakes so setting it up where the machine double checks for you is key.
Read and understand it enough to dump it and rewrite it
Good abstractions are replaceable, which means good abstractions meet your criteria for good code. I mean I have software examples that have held up to the years and stayed maintainable, it's more so a question of whether or not people put in the effort to do the upkeep, and the more complicated the code base the more upkeep there is, but the less upkeep you do the more the complexity drains productivity. The more tech debt you create the more likely you are to just throw the baby out with the bathwater and recreate something with a better idea of what is currently needed in mind. Requirements change, and therefore so does software, you can't see the future, and eventually things might change so much that the current solution is just not going to work either. So there's still reason for good code, and there's still reason for putting the the work to keep the code base manageable, because on the flip side there's been times when we've moved quick to create software, changed it a bunch, and are stuck trying to dig ourselves out of the hole we were essentially forced to create. So yeah, everything is a balance.
There are serious issues in this industry that is at the core of modern economy. First of all you can’t write lightweight code with all the frameworks and everybody but the coders seem to have an opinion these days. Coders can take so much learning in just a few years and stay productive.
There are also massive management issues with allot of people not related to coding fighting for position, even HR has been on top of coders in the past years.
And there are actual business issues because nobody listens to coders, I am getting close to 20 years now and have an economics degree, I see these things and know how managers are trained. I was working for two years with an agency on a big Website (10+ countries) with all that it means (sales, CMS etc.). We never had time for scaling, they were like “this guy will have a pause in two weeks, let’s add another feature”. What do you know, sales go up in UK and wanna start selling in France. A dip in performance obviously. Before I was done explaining they should upgrade the hosting and we should start getting prepared for cloning to individual serves for each country (I had that prepared since day 1 and it was the cheapest way to scale for them) they changed management and started over with a basic Website and an external sales platform that, obviously, started two products for the two countries. This was an agency I was working with at least two managers mostly on vacation, I was not that well paid and God knows what they were charging this client.
So yea, you have allot of bad things working against you on top of actual coding. Good thing is I see a shift back to vanilla at least for the Web.
Lol, you really hit that nail on the head @24:15. I came into where I work and the repo was 10gb+ in size because devs before me were keeping data with the code.. I rebuilt everything from the ground up over years.. took care of the code base and developed a proper pipeline.. the repo is now
Thats great!
Just because a famous framework has non-readable code, doesn’t mean readable code is bad.
On a big, long term project where new people will keep coming in, it’s far more important to make code easily readable.
If each function states clearly what it’s doing, reading code is similar to reading a story about what that code is doing.
exactly! i LOVED to go through some python scripts. they feel like a long ride.
My goto languages are BASIC and C/C++. There are not many other languages having GOTO nowadays.
Lua :)
SQL
Bruh 😂
Good joke saving this one also Batch scripts have goto iirc
I’ve been an engineer, product manager, solutions consultant and sales manager. As soon as I stepped out of the engineering bubble I immediately got the “good enough” mindset.
Once you realize that perfect code doesn’t pay the bills, and that code is only a means to an end, you get it.
The worst part is suffering the agony of peer review with fresh graduates who's heads are filled with "clean code" practices that don't work in production.
The problem I have is that if it doesn't look perfect, it looks like utter trash to me and how could anyone use the tool. I'm building otherwise.
I don't think we're taking about perfect code here.
I think the major issue is when the product has massive architectural issues and no one except engineering cares. If you've made bad decisions about code structure or how the product is deployed and product and management don't let you go back and fix it because we always need new features, then the product could enter a death spiral.
Additionally, paying down tech debt allows you to build features more quickly.
I think I'm some ways, product and management can definitely be short-sighted when they adopt this good enough mentality. It's think about the next quarter rather than the quarter five years from now.
Hot take: software is hard and complex. Your job is to make it simple and build on the simplicity.
Is that even possible? How can you build simple software for complex business requirements?
People say this and then pack a bunch of complex logic behind some weird type or function and suddenly you have no control and are locked in some pattern that cannot possibly be best for all the cases its marketed for
@@yuriy5376 By using the right complexity management technique for the job. Something learnt through experience & research.
@@yuriy5376 make it as simple as possible. As the software requirements become more complex, then build on these simple constructs into more manageable solutions. That’s how software must be designed. That’s where I think things like DDD _could_ be useful.
Our job is not just to make it simple. Our job is to take incredibly hard problems and make them look effortless. “Effortless” software is so slick and easy to use that it seems from the user’s perspective that it must have been easy to make.
…which sadly then leads to bad management killing off top performing teams because they just spent the last year “rescuing” a shitty team and believe that their “newly improved” team can clearly do such a simple thing better than the pathetic team that’s currently managing it. 🤦♂️
I doubt very much that the person who wrote the Rollercoaster in Excel thought that they were using the right tool for the job. Its more like doing it because you can, not because you should.
The "job" was "build a rollercoster in excel", not "build a rollercoaster".
It was the right tool because the tool was part of the design constraints.
He never claimed the person thought it was the right tool, he used it simply to prove the point that you can use many tools to do a thing and if you're good with the tool, it would appear it was the right tool for the job but really it was all the developer, not the tool
It's*
@@Dogo.Rmaybe the person who made it only knows how to build it in the excel
@@MerkieAE if the task wasn’t constrained to only use Excel, then Excel is always the wrong tool for that job. It’s a useful exercise, nonetheless.
the manager is also the HR of my company. I can't complain about him to him. :(
Somehow way worse than not having HR at all.
HR works for the company not for the employees
You can do it, but only once
@@conorx3 sometimes your incentives are aligned, which is when it works out.
Bit like the Police...
I do think in the world of enterprise LOB applications that readbility is almost more important than anything. When the technical complexity is low but the domain complexity is high, code readability is important since the code is your source of truth for how a business process ACTUALLY works.
What's lost in Prime's take is that he is hyper-focused on 1 long function. When you talk readability, you are talking about the entire repository, a feature, a module, a function in that order in terms of importance. You can look at a long function and say "look how unreadable that is, it's so long!" as a kind of gotchya for people who say that readability doesn't exist. What is missing is the context of that long function. He skimmed right past a small function that leverages a long function and guess what, it's crystal clear what that small function does because of the lifting done by that large function.
Real. I work on automations for business processes and the function is how money literally moves between subsidiaries, for example. And coming from the web to this job 4 years ago made me really appreciate simplicity. When implementing a single process without the need for too much reutilizarían or branching, I just write a single big function that does the thing, with maybe a couple of properly named utils functions.
Having to jump through 4/5 functions with vague names between files is a nightmare when 2 years later the client wants to add a new use case. Nobody remembers what the thing actually does. Not even good documentation helps sometimes to understand code from “clean coders” (not derogatory lol)
This this and this. There’s a reason we haven’t migrated off of mainframes with 30+ year old code that still hold up the stock market, flight systems, and other industries. Rewriting/rebuilding would mean you would have to trust you’re not breaking 30+ years of business logic that nobody really understands
Comments that explain why something is being done. Those are a godsend a year later when you need to make a change.
The best written code is the code that is easy to replace ... almost every good pattern or practice stems from that.
What my previous team did is exactly the reason why they're now in a very bad position, they settled for "good enough, it works" and now they have a huge but fragile infrastructure they can't maintain nor change without a massive refactor
I'm a HW guy. Have taken on a Java project that ultimately ends up as a piece of hardware from the code output. To learn Java, I bought Java beginners by Oracle two years ago. Yesterday was the first ever JUnit for the project in its 8yr life! I've had to do this because each new HW product starts as a new J package, with existing code copied / pasted / tweaked by overrides. It's an enormous intertwined f'in mess that now does not work unless one knows all the gotchas. When I mentioned this to one of the original coders, his reply was "it was good enough to get the job done". That guy has a PHD and insists on being called Dr. I call him Mr to bring him down to earth.
@@BobBeatski71 I worked at a hardware company myself, manufacturing always takes priority over code, and requirements are never clear, it's just not a good experience. Hell, the IT infrastructure sucks in these companies in general, you can't always develop software under normal conditions.
So I see why people settle down in a sense, these companies never prioritize good software. But nonetheless, it should be a priority
Exactly this. Whenever people say “just get it working”, all i hear are people playing not to lose, instead of playing to win.
“By the time you need to refactor the code, youve already won because your product took off.” Yeah, until it dies a month later, ie the current state of the gaming industry and nearly every website. The fact of the matter is: you need to “just get it working”, in the present sense, and the future sense. Otherwise, youre not playing to win.
my last company did this. "let's use stored procedures because they're easy". literally thousands of stored procs later, upper management says let's move away from oracle due to cost. cool, who wants to rewrite thousands of procedures from oracle flavor to another? nobody? not to mention the troubleshooting hell when you're using debugger and then reach a stored procedure call. everyone dances with joy at this point yes? no? 😂
This is the state of the software I work on. I tried multiple times to get them to halt and rethink, but nope. They just pressed on, running on that feature treadmill. And now it’s all unmaintainable garbage that I honestly can’t stand to look at.
I agree that experience in many ways makes software dev more difficult. I was at peak productivity/effectiveness when I was still naïve of all the best practices. It is commonly understood that 'cowboy' coding is a bad thing but in over 30 years of doing software dev and programming, it is usually the optimal strategy. Fancy tools, methodologies and paradigms are massive technical debt.
Good devs know how to KISS. The vast majority of the time, good code does not mean making bulletproof code, it means making it as simple as possible without painting yourself into a corner.
I've been thinking about this recently quite a lot.
It’s all going to be technical debt anyway.
its a good approach to anything in general. You just learn over time, that people just don't give a sh*t and everybody has agenda, so why bother go extra miles anyway. Just survive and do the minimum and you're good.
Sinplicity is key but never easy. Saddest part is that not-so-good devs write complicated code thinking what they did is "simple" or "clean"
What I find hard is getting the rest of the devs on board though. So many devs practice dogmatic clean architecture for instance thinking it's the way. Takes alot of time and energy to change that around.
there's shitty code and then there's the data analyst code. that's one of the most amazing mess
Very hurtful, 100% true but still hurtful.
did not mean to hurt anyone. apologies. I'm an analyst myself and I'm just amazed at how things keep working in offices like mine.
Instructions unclear. Put all my production code in a Jupýter Notebook.
@@paper_cut9457 Obviously no offence taken. I'm an analyst as well and I've seen the disaster code firsthand. I like to call it Buca di Beppo code because that spaghetti code is family style.
damn
The NP + NL situation, to me, is actually what ChatGPT is PERFECT for.
It allows you to explore a new problem, and relate that problem to a language to already know.
ChatGPT is not good for 90% of the things people think it is, but as an interactive learning tool, it does GREAT!
It can't teach you fundamentals, but it helps you more broadly apply the fundamentals you already know.
Someone in chat said "Clean code is opinionated"
I'd say "Opinionated code is good code" PARTICULARLY because it's "led" by a person, rather than an amorphous blob of principles, patterns and expectations that aren't very cohesive.
I have a simple rule. code complexity should match the bussines requirement complexity. I naively started a side project that I thought was simple three years later no matter how much I refactored my code it's just complex. I learned from this that there is no such thing as a simple "real world" software. if you software is simple it has "no value" and no different from the many software projects I completed as a cs student.
If you haven’t read The Mythical Man Month, you might enjoy it. Brooks spent a good chunk of the book talking about inherent complexity (the complexity needed by the problem) versus accidental complexity (the complexity caused by the methods used to solve the problem).
Try creating accounting software. It's a simple +- right 🤔
I love what youre speaking about in the beginning, I am currently developing a feature at work and everything is new, I am a graduate dev trying to implement a masstransit feature and its honestly fun tbh, but productivity is slow because I am a) googling everything, b) trying to write good unit tests c) message queues are hard to debug haha. But tbh I think I am nearing the end and its awesome, feel like I have personally learned a lot, but I feel slow, too.
Good to see different takes that still align overall. From somewhere else I'd taken "Write code that someone else can understand 6 months from now". That someone usually being yourself.
Am I the only one that rediscovers my own code every 3 months and after I read how it works, I'm amazed how flexible and maintainable it is?
Well, the 3 months figure is worrying. Personally, I always throw-up seeing the code I've written in the past. But in most cases, I only have to rediscover it every 2 to 3 years generally.
Why worrying? If you're not touching your code for 2-3 years are you iterating?
Yes, sometimes it's a pleasant surprise. I find that mapping coding abstraction to business abstraction increases the likelihood of this happening as the business requirement changes in ways that the code base already anticipated.
We use around 20-40 msg functions to read from a mbs server.
I rebuilt it to read the entire database with one msg using sequencing.
It does the same thing, but WAY more advance and FASTER than I'd ever thought in my previous years.
19:10 I agree with your friend, and I've been saying this for years. We've known for years that readability matters. If functions are too short, readability suffers. But when a logical block takes 2 page scrolls, that's also unreadable. Trade-offs, people.
"the person who works on it can continue to work on it."
What if a different person has to start working on it? What if they quit? What if the project needs more developers to scale it up? What if they demand double the salary and a stake in the company for half the hours or they'll leave? What if they take months off for maternity leave? Is it gonna be a black box until they come back? When they do, are they even going to remember how their own code works?
Part of the problem with bad code is that when anyone else needs to work on it, it becomes an intractable problem.
This isn't to say you need to turn everything into maximally encapsulated OO, or 10-line highly nested do nothing manager functions, or increasingly nonsensical inheritance trees, or for that matter stateless functional code. What it does mean though is that someone else should be able to read your code and be able to figure out how to change it without understanding how every line of the codebase is coupled to every other.
I've been a dev for 30 years, it's one of my hobbies as well. I've been trying to get better every day but I still feel average. Why? Because of the complexity of multiple conflicting goals. I very, very rarely get to feel like "this is the best solution" because everything is a compromise. I think there are better and worse compromises but most of the time what I feel is a slight disappointment. Also, it doesn't help that every OS, every programming language and every API is also a bunch of more of less annoying compromises.
I wish computer science was more of a science but also that the industry cared a bit more about what the studies indicate. One corner of the industry is busy reinventing the broken javascript wheel every couple of weeks and the other corner is bolting more crap on Java.. but we're not ready for any kind of paradigm shift because most people don't want to learn new things and like Prime said the "best tool for the job" is just the language&framework one is the most comfortable with.
I think coding in industry is far more of an art than a science, which is why no one can say what is 'good'
19:10 This is something I believe is a good way to fight bad abstraction. For me, I've been phrasing it as "The correctness of the code should be locally obvious." This is something I started thinking about when I had to dig down many branching levels to see what a function did, then I had to do a scan of the project to see how an object was initialized, so that I can know which class to further dig down to see what function was actually being called on the object, which again required tracking down the various ways object's members were set.
There are 2 paths that I know of to fulfilling this guideline: make the code local or make the abstractions robust.
Good libraries are an example of robust abstractions, where you can reason about your program without having to read the library's source code. Though even if your abstraction is robust, someone who reads the code will probably need to learn your abstraction to verify correctness, so making the code local is generally a strong choice. (Re-listening to the clip, "you don't have to learn new abstractions" is mentioned, so I like double agree with this guy.)
Atomic pieces: Regex to scan important instructions/data from robot code.
Small features: Robot motion point joint knuckle flipper, code formatting, comment injection, various data extractor from running robot programs, setup validation tool, etc.
Everything together: General robot commissioning tool.
Thanks Prime for your incessant hammering on not abstracting. I'm currently writing new docker containers and systems for our cloud at work and started to abstract. Then remembered your yelling about it. I killed the whole project and restarted from scratch, no abstraction, just simple neat sequential code. And am thankful I did :). You are right, experienced programmers really got an abstraction problem (me included, been writing code around 15 years now).
Good fortunes to you good sir o7
Really agree with you on the function length. I once worked on a code base with hundreds of one-time functions, many just calling other functions, and often badly named. It was so hard to track the control flow without a debugger and even with it required infinite working memory in your head. I definitely do prefer well-structured long functions over a multitude of small functions.
At 16:20 tiny pieces are brilliant. Like Lego pieces vs puzzle pieces. Puzzle piece can fit only in one place, Lego pieces can be rearranged and reused. If I am not mistaken that's a part of Composition over inheritance
I'm so glad my manager owns the tiny company he does. I never have to worry about being told what to do by 10 steps up the corporate ladder. And it's such a small team that my voice is important. I'm able to code my best, be comfortable, and have positive motivation.
The reality of most people's software engineering jobs is terrifying to me. And hopefully I never have to understand that experience myself.
Preemptively adding abstraction is usually a bad idea. Add it when you need it!
Classes are abstraction.
Java forces classes on you even just for Hello World.
No wonder so many hate Java.
@@DarrenJohn10XDon't blame OOP for Java's failures. C# is amazing.
Small Focused Functions is bliss. But I might be biased as I prefer functional programming, and thus it makes perfect sense. But then what the point of that is that the functions does one think, and it should be quite obvious what when you just read its name.
"You should have 3 goto languages". I've got HTML, CSS and JavaScript. Glad I made the cut, thanks 🙏🏻
We need to escape from our code fetishism and see things from the other side of the business to realize that if you don't know the in-depth and minute nuances of the domain you are trying to model with your software, your software will result in accumulating overengineered, convoluted designs and features that don't bring any value, advantage, or profitable innovation.
That is what the people who are paying/investing need. So, we have to be good at two things: coding as a means but attached to business-relevant goals. DON'T CONFUSE business goals with features. This is the fatal error that most of us in hardware and software engineering have committed in the past.
We rather need to escape from our commodity fetishism.
- Do you like coding?
- Oh yes, so many business opportunities.
- What do you mean?
- I created my company last year.
- Ok, but what about coding? What type of software do you make?
- I make software with tremendous profitability. I'm sure my company will double its revenue this year.
- What's your favorite language?
- $$$$$$$$$$$$$$$$$$$$$$$$$$$$
- Do you have some advice for a beginner developer like me?
- Yes, you really need to see things from the other side of the business. Think marketing, human resources, market research, balance sheet, assets, merchandise, shareholder, industry, sales, innovation, efficiency, productivity, business model, management, cash flow, market segmentation, customer loyalty, distribution, logistics, expansion, competition, branding.
- ???
Back in my algorithms class in college I learned about overdoing the concept of very small functions / large abstraction chains in an unexpected way, and the lesson keeps revealing itself in new ways. Mergesort... You simply break the array into two parts, merge sort each of them, then merge them together. This is great when the array is 1000000 elements, and 500000, and 250000, and so on. It's not so good when the array length is 16 due to the overhead of the recursive calls and that dividing something by two gets you fewer and fewer shaved off elements each time. Indeed, once you get below a magic threshold of about 16 or 32, it becomes more efficient to simply insertion sort instead of continuing to subdivide... To "just do the thing" instead of offloading it to more and more subdivisions. Though this is performance vs code style, I think it provides some intuition that some abstraction is good and necessary... Merge sort is more efficient than insertion sort. But you can overdo it. A 1000 line function is probably bad, but a 100 line function might be as small as it makes sense to be. Breaking it up further would just waste not only the developers time, but the readers time jumping from useless function to useless function. I think this goes for many concepts not only in computer science but in life. TLDR; Diminishing returns, use common sense over dogma.
250,000 or 32 just use the same logic. thre's no way 32 will take more time then something with ~7,500x elements/iterations
Bro cooked but no one was hungry
if you don't feel doubts while writing, it's probably going to be bad. Whatever your current level, you should be aiming at least slightly higher. It's not about how many design pattern you can cram into your code but the overall coding efficiency, code simplicity and performance. It's about looking for new angles. Let's take the example of the APIs of the modules (JS) you can refactor them for an eternity and still find better ways. How to be concise, performant, readable, how quick people will use what you created and how good the result will be for them.
24:35 living right now, and is so true. When I started 16 years ago, I was taught that the most important duty in programming was keeping a good eye on the code you needed to maintain, consistent tabbing, etc, and nobody on my career was careful enough to keep the codebase nice and clean.
I couldn’t agree more with your assessment of how to stay happy with your development journey
25 years in the industry and the main thing that goes through my mind when writing software is "will someone else be able to maintain this without wanting to end their career as a software developer". If you write code that no one else can maintain, expect to maintain that code for a long time :) I agree with the "readability" points though, in fact, I agree with the majority of what you said around the state of code and I have added to the mess LOL I also maintain that the more generic something becomes, the less useful it is. Some real gems in here
19:01 this is exact reson of this recommendation. Because you divide your 200 line function in 5 smoller ones, with names that explain what this part does, and if you have static types it even better, because you can see what set of data you need to pass there and what it returns
Completely disagree with his take one clean code. I’m not referring to Uncle Bob either. Clean, readable code is a thing and should be something that’s desirable. There are few instances imo where ugly illegible code is acceptable due to quirks and performance. Rarely are devs programming at such a level. Widely used libraries or not. Ugly code in most instances is lazy code.
Please try to understand what he said! Readable code is desirable and you should try to write the best you can, but you should not use the phrase 'clean code' for that. Even if you don't mean it, people will think of Uncle Bob's clean code.
Imo, even if somebody likes Uncle Bob's clean code style, it is not an universal 'you should write like this' clean code
You should just design ur system like how it should be and not have clean code in ur mind as you are coding. The problem is people who advocate for clean code or readable code will often write code a certain way and preach that it is better because its is more readable/cleaner.
Clean code should not be part of your design decision.
I am a huge proponent of what you called "eyeshot development" here. I've been using the word "locality" for the idea, but "within eyeshot" is really nice in how plain and not-abstract it is.
Opposite of "spooky action at a distance". If I change code waaaayyy over there somewhere, and it breaks this code over here, that's a non-local change/effect. If some function in that other source file mutates this data that's being used by code I'm looking at here, ditto. Low/poor locality of stuff that's related and coupled. Ideally we'd make proximity/locality correlate to relevance/coupling. If I need to read/see both anyway, maximize locality, get them close to each other.
It's obviously not supposed to be an "infinitely strong" rule - it doesn't always outweigh everything else. All best practices are weights that pull one way or another, better code is better balance of those pulls. And locality/eyeshot is definitely one of the pulls. Our life is better when all *relevant* information is as close by as possible. Same file, same screen. Do we need to know *that* code to understand/verify/change *this* code? Then it should be nearby.
You're not supposed to be changing the kind of code that would have that sort of effect, though. Such changes should be breaking the contract, and you shouldn't be breaking contracts that are already in place.
15:38 I like how he sits so still while being almost swallowed
xD
RUclips has recommended this person to me before, and I didn’t realize he was a software engineer. He has a very interesting video about why insects are drawn to light and why they circle it.
4:46 How about working on the logistics of a product ( SRE before SRE: plumbing, instrumentation, tooling, etc) only to have the product launch cancelled two weeks before public beta.
Even better, ( which most people can't believe ) agreeing 100% with management that although the product would be successful, it would distract from a sudden and rapid change in the competitive landscape.
"Hey Ted, just an FYI and you didn't hear this from me.... Jeff Co. are signing revenue share agreements with the big 6 for variois thin round pieces of plastic. "
Option A: spend marketing $$$ launching a UK service ( first intl expansion ) as planned for the past 18 months.
Option B: Cancel above project and pour $$$ into price cuts, domestic improvements to keep Jeff Co. from entering into an easily profitable enterprise given their existing large primo user base.
Obtion A would have been validating for all the blood sweat and tears... but selfish upon reflection. Option B helped keep Jeff Co. at bay.
As a junior I was eager to start coding and solve problems because that is what we are taught to do. Through experience you become a senior and then you become afraid to start coding because you know you will fuck-up eventually. 🙂
the no googlin thing is so tru. i switched to linux cuz of prime and broke my pc 4 times with internet, 5th time i didnt. not being able to Bing Copilot and copypaste made everything fun
i miss windows
It is impossible to break NixOS tho.
I still remember when Windows was my caretaker whenever I would bork Linux and feel bad
I dont miss windows ads. Basically puts you center in time square while you just want to look at some funny cat jifs.
im deff not missing it. so far every game i wanted to work, works (league/dota/battlebit/wowclassic) and vscode and even GIMP open just... instantly. idk how this is even possible. this whole symlink thing is pretty daggon neat too. and search is instant, cloudflare warp just works... second time ive tried linux and first time able to stick with it, all thanks to bing copilot being so good at answering everything. only thing i hate so far is the default nautilus skin but i havent tried changing yet.
@@pluto8404you can easily disable all the bloat ware except the MS store
This content changed my vision of programming for sure !
Don't abstract until you need to abstract. It's that easy. If it's not an api, it doesn't matter. Abstracting it later is easy.
On the other hand, don't abstract minutia. If there are three similar processes, but they're too different for a general abstraction, just don't. Copy and paste is fine here. Don't over confuse.
5:03 My way around this is to just lean into it. When something is bullcrap, I agree that it's bullcrap and want it to change. It frustrates me, too, and I should express that. It not only helps user morale, but sharing in the frustration of people working under me also helps with morale, because they also don't want to be unheard.
Gosh! Dude are you on fire in this video. Wonderful! Clap, clap, clap
I am a fan of the smaller functions, and then creating new classes if you have a giant class with a bunch of little functions. It makes it so much easier to change/fix an issue in just one place.
I am not a fan of the term “self-documenting code” for the same reason that Prime isn’t a fan of the term “clean code”. This is also why I don’t dislike comments as much as other people; they help me more often than they confuse me.
19:50 Fair point. For most PR’s I have to use IntelliJ’s review feature and hop around in the code to really understand the logic
Never forget : Support wants to know where they can poke to know why things aren't working right. Meaningful errors, tools to fix things without dev involvement, understanding what aspect relies on what system at a high level. How can we show where something isn't working so you can go straight to the issue.
Need to add another comment. The solution to future-proofing your code isn't abstraction, it's literally the opposite, simplification. If you code is easy to read and understand, you can change it much more easily. If it's heavily abstracted as a means to avoid having to change it, you probably made bad assumptions and it will be harder to change--plus if those predictions never came to pass, which they usually don't, you're paying the cost of the penalty all the time no matter what. That's a bad insurance policy.
I remember finding your channel a few years ago when I started learning vim and wanted to write my own vimrc and also to get better at it. At some point I just stopped watching your videos. I don't really have a reason for that, I just think that I wasn't interest in rust or other things you were doing, or the memes, don't really know. But I really like these videos like this one. It is a talk about software, it makes sense independently of the language you use the most, it is just honest takes on development process. I love it. Contratulations on the content 👏
I agree with your friend. I've wasted too much of my professional career going through 20 something functions deep on code that should have been at most three levels of abstractions away. Way too many developers think about principles for the sake of principles, and don't think about things practically.
I could talk forever on this topic, but the short version is I firmly believe the only candidate for an objective measure of "good" code beyond it simply working is properly tested code.
I don't understand your logic there. I mean one has no idea if ones software actually works unless one has tested it, at least to some degree. The degree to which one tests it shows how much you care are about it actually working. Unless you are happy to let your users test your creations.
What's your objective measure of "properly" tested code?
100%. My teammates hate me when I say this but I only trust bits of code that executed recently.
Even the best programmers will occasionally write some pretty hard-to-read code. There is often a sliding scale/trade off between efficiency and code readability. Also other constraints may come into play. I do believe most code can probably be improved by an order of magnitude in terms of readability, but this is due to a lack of training and industry standardization in this area.
4:15 Whenever I learn a new language or tool inside a language (like ECS or a game engine), I usually try to replicate something I've done many times before, like reprogramming ball physics and connections like in World of Goo, or trying to implement compile time dimension generic geometric algebra.
HR has its uses but it's important to keep in mind their job is to protect the company, even if that means screwing over employees. That doesn't mean they won't help employees because often that is mutually beneficial to the company but make no mistake they are NOT your friend.
Congrats on 600 videos
I feel the videos are entertaining, but for the learners--- To summarize: understand reqs, domain, standards => start small by building core pieces => THEN abstract and refactor (as needed)
A shopping list is handy. Disposable. Concrete. If you can generate it quickly, and the cost of rewrite can be kept low, why write a perfect abstract shopping list you have to adaptively decrypt every trip? - adapt to every possible period? - category of item?
The epiphany waiting for most new developers is your code is a shopping list. It's rare you will get to a stage where a generative recomposition from smaller components can't be faster than perfect up-front design and abstraction. And so often then you're immortal code will still only be harder to replaced, it may not even need to have lasted the duration of creation.
At the end of the day just enjoy what you are doing. If you can find a way to not look at a problem as inconvenient but as an oppurtunity to learn and get better your life will significantly be better despite not actually being better in any objective way. It will be the same thing but you will get much more joy from doing it just because you believe it to be fun/interesting learning project.
Just discovered User Story Mapping and it is changing how I approach development.
really summing it up from 2:00 to 4:15. every new project has to have something I havn't done before
Small functions make the individual functions easier to understand but you kick the can down the road because it can easily make the larger function using all the small ones harder to understand.
I think the priority is if a functionality can or needs to be reused many times, then it should be its own function.
If you split your large function into smaller ones that are only used within that one function then it was useless to split it from the start.
Bro, why surprised about HR? Michael Scott hated HR before it was a thing...
That said, Primeagen, thanks for your vids. I have been doing tech/telecom engineering for almost 20 years but never learned code. Now i am, and wisdom has shown me there is an 'art' to software dev as much as 'science.'
Thanks for sharing your wisdom on where/how to focus. I appreciate it.
About "readable" - the problem is that readability has subjective and objective components, and many of the objective components are relativistic rather than absolute.
So yes, there are objective readability factors: human vision has mechanical and computational constraints which can be studied, understood, and optimized for (this is why newspapers and textbooks use thin columns - it optimizes for less eye saccades, and this is one of the reasons why line width in code is partly an objective readability matter). Of course, there can be physical and mental variations between people that make us more sensitive to these objective factors, so it's partly absolute and partly relativistic.
There's also stuff that seems "subjective" only because it's heavily relativistic. For example, whether you find camelCase more readable than snake_case is heavily influenced by what you're used to looking at, so that can feel like purely a matter of taste when part of it is *habitualization* - and we can measure this in our own lives if we ever spend enough time away from one style of naming, and then see how we feel when we come back to it. (For example, I used to think camelCase was equally readable to snake_case, but then I noticed that even though I was instantly comfortable reading snake_case after years of programming professionally in camelCase, after a mere two-three months doing snake_case full-time I found camelCase harder to read.)
Maybe aversion to small functions and hopping is line between VIM and IDE?
Becuase most of IDEs greatly improve this hoping experience.
Also meaningful names limit necessary hopping too.
Anway i saw once owner of the firm who have and trains x20 programmers and he opted even for two line functions but he also admitted that they select specific type of people to his teams
I mostly build for the web so I use TypeScript and Go for the most part and it lets me solve most web-related problems.
the web is boring, how many times are you just gonna do CRUD before you get bored? it's ok if that's your job, but there's much more to programming then just storing and presenting data on a web page (which is hands down one of the most needlessly overengineered areas of IT if not tech as a whole
@@FlanPoirotI am curious. what are the other programming domains that are better than the web in your opinion?
@@FlanPoirotnot all web is equal
@@anoh2689 not "better" as making websites is obviously useful, without the web access to information would still be limited and there's great value in it.
but limiting urself to just web development to me seems like deciding to be a carpenter that exclusively only makes chairs and refuses to make anything else, it doesn't make sense.
I'd say just explore what programming has to offer, do ur job as a backend/frontend/whatever u need to do to get paid, but it never hurts to do more.
as for other areas u might explore: low level programming, emulation, CLI, encryption, graphics, databases, ML, GUI, embedded, compilers, simulation, data science, etc.
I mean, the great thing about programming is how versatile it is, u can provide (real) value by doing a lot of things with it and adjacent knowledge in other things that might also interest u
Always remember HR is never on your side. They are always on the company's side.
Yes! They are not "resources for humans", they are "human-shaped resources" for the company to use.
Yeah I'm good at tcp programming and use the Indy framework in C++ Builder
I'm using Indy framework but in Delphi, hello :p
After using Delphi for 20+ years, I still enjoy it. I don't care if it's outdated, it works for me.
Thanks for all the commentaries!
I love writing code and creating a product. I don't care if it's bad or good. That are worries for later. I refactor as I go. But I guess it's different when you work in a team.
I believe in a clean code - as long as project is completely isolated low level code without dependencies or small application. Let's say up to 20 files and higher tens of kilobytes. Once it has like 3 layers of abstrations (and it's hard to even find all methods that class actually has), many classes that are glueing together simpler classes add logic of their interaction, interractions with gui, error reporting, it get's complicated. And then add serialization and undo stack.
HOT TAKE: I rather create code that I feel proud about, enjoy every minute of programming, and MAKE LESS MONEY, than being more efficient but having no pride on my work and only find joy on my leisure time.
words of comedicallyy-gold wisdom and equally wise responses to those harsh truths. thanks for sharing, signed a jr dev 1.5 year post grad
Well structured, documented and properly tested code is pretty much possible and totally justifies the effort put into it, no for prototyping of course. Encapsulation is necessary for handling complex programs and teamwork. And yes refactoring is needed to adjust the code for further development. Clean code also exists! just because it's relative doesn't mean that it doesn't exist!
I generally break into function when I think a block of code is so complex that I may forget what it does in the future.
So long as the .exe is named well, I’m happy.
7:03 unfortunately “good enough” has to be the way because there’s always “just one more thing” that could improve things. I’ve lost count of how many devs I’ve seen go down rabbit holes gold plating a solution blowing out budgets beyond belief which only reinforces the “good enough” approach
One of my favourite features of Google's Gemini is summerizing his long ass videos.
The key to number 5 is to know when repeated code is repeated because of an underlying abstraction, or just by sheer coincidence. Consider refactoring the former, and think carefully before refactoring the latter
12:17 the look that he makes, staring at everybodys eyes, is really absourd.
When starting a project, I usually start with a single file, implement everything in the main, until I start to notice patterns or it gets complicated, and abstract from it. That way, I progressively abstract and when it's done, I have a exactly as many abstractions I need.
Im happy after the 3rd rewrite normally. Building good software is very hard. Its not the code I struggle with but holding off until i really understand the domain im working in before diving in with both feet.
2:55. Lua! Everything else for me is a purpose language. Lua is like my hobbyist language (But I LOVE [2D] it the most). Everything else is: Python, C++ and Assembly.
I agree on the "having several 'Go to' languages" (And you should always be on the lookout for a new one to add. Looking at you Rust. And you, Mojo.)
My first boss (30 years ago), said that for ever 1000 lines of code there's a bug, and for every bug you fix you create another. 30 years later, I still agree!!
Primeagen: Don't be the rollercoaster guy.
Also Primeagen: Sometimes you have to be the rollercoaster guy.
"the good enough approach....I hate it SO MUCH.........Because 20%-30%-40% of the time it's the right decision but it's made every time"
Exactly !
I hade it SO MUCH too , for the same reason :)
Saw this vid. And yeah, this channel does say some powerful things.
Agree with the size of functions, my bedrock is around 1 page on your monitor like you said, keep it all within eye-shot.
To add to the 'good enough' approach. That's fine for innovation, MVP for PoC, and for fairly low risk and reasonably low visibility processes that won't charlie foxtrot other things important to an org. But for everything else, a mantra I adopted long ago "You can do things right. Or you can do them again."
25 years in coding and it work . Some things i build in the past ran with 4 code changes in 10 years. Old cobol and pl1 code worked and was good. Modern stuff gets changes all the time. People dont write code for the business anymore they are experimenting for their own skillset. Code quality does not matter because code only lives for 2 years max and the readability is not in de code logic but in the full chain of all the services involved imho
The Excel Rollercoaster... I am equally impressed and terrified by that.
19:23 THIS! THIS! THIS! A million times. LET'S GO!
All problems can be solved by adding another layer of abstraction, except for having too many layers of abstraction.
I try to only abstract when it comes to external dsls. I would for external libraries, but I find it works better to just limit its use to a specific internal library and just rewrite it rather than abstract it. It’s not as fast as abstraction but better than having to refactor my code in all million different services.