Are software engineering “best practices” just developer preferences?(floverfelt.org)
floverfelt.org
Are software engineering “best practices” just developer preferences?
https://floverfelt.org/posts/software-best-practices.html
370 comments
One thought to add here - when you appeal to an authority, which one is it?
In the OP example, it seems the senior dev is saying “on my authority”. And sometimes that is enough, especially if the senior dev can give examples of when not following this practice bit them.
But sometimes there is a higher authority, such as “it’s what is recommended in Google’s SRE book”, which is probably good advice if you are building a large SRE team. (Though as you say, not in all situations.)
I think in the worst case, “best practice” can indeed be used to shut down discussions of a leader’s preferences. But you can smell that out by asking for concrete examples, and asking how widely the practice is recommended.
A good “best practice” should be justifiable and explainable.
All that said, sometimes as the senior engineer you need to go with gut feel; “this design smells like it will give us trouble within a year” is the sort of thing I sometimes say. But I think it’s important to be honest that it’s a hunch, not a certainty in these cases, and discuss/weight accordingly.
In the OP example, it seems the senior dev is saying “on my authority”. And sometimes that is enough, especially if the senior dev can give examples of when not following this practice bit them.
But sometimes there is a higher authority, such as “it’s what is recommended in Google’s SRE book”, which is probably good advice if you are building a large SRE team. (Though as you say, not in all situations.)
I think in the worst case, “best practice” can indeed be used to shut down discussions of a leader’s preferences. But you can smell that out by asking for concrete examples, and asking how widely the practice is recommended.
A good “best practice” should be justifiable and explainable.
All that said, sometimes as the senior engineer you need to go with gut feel; “this design smells like it will give us trouble within a year” is the sort of thing I sometimes say. But I think it’s important to be honest that it’s a hunch, not a certainty in these cases, and discuss/weight accordingly.
> All that said, sometimes as the senior engineer you need to go with gut feel; “this design smells like it will give us trouble within a year” is the sort of thing I sometimes say.
That's a really great perspective. There are a bunch of times where I have a preference for or against something, but I can't point to a specific example of when that thing was good/bad, or any objective data about it. It's just that my experience suggests to me (via murky pattern matching in my brain) that particular thing will be good or bad.
It's certainly weaker evidence than data or concrete examples, but I think it's still valuable and worthy of consideration.
That's a really great perspective. There are a bunch of times where I have a preference for or against something, but I can't point to a specific example of when that thing was good/bad, or any objective data about it. It's just that my experience suggests to me (via murky pattern matching in my brain) that particular thing will be good or bad.
It's certainly weaker evidence than data or concrete examples, but I think it's still valuable and worthy of consideration.
Yep exactly! I think if you broaden the concept of "authority" beyond literal authoritative sources it gets even more murky.
Are you appealing to the authority of speed? Compilation time? Readability? Functionality?
I dunno, and it often (especially around readability) comes down to the developer's/senior engineers preference.
Are you appealing to the authority of speed? Compilation time? Readability? Functionality?
I dunno, and it often (especially around readability) comes down to the developer's/senior engineers preference.
“Best practices” smells like such a marketing term it should be tossed in the bin.
It’s poetic language that has nothing to do with specific problems.
What people usually mean when it comes to engineering is “be safe, reliable, and correct.”
Security best practices to be safe.
Developer best practices for reliability.
Etc etc
“Best practices” is hand wave-y fluff for “do a good job” and doesn’t need a technical definition.
Make sure you’re secure, reliable, and correct given the engineering context, and odds are you result in a system that also has a lot of specific best practices in place.
It’s poetic language that has nothing to do with specific problems.
What people usually mean when it comes to engineering is “be safe, reliable, and correct.”
Security best practices to be safe.
Developer best practices for reliability.
Etc etc
“Best practices” is hand wave-y fluff for “do a good job” and doesn’t need a technical definition.
Make sure you’re secure, reliable, and correct given the engineering context, and odds are you result in a system that also has a lot of specific best practices in place.
I think it's very telling just how little engineering there is in Software Engineering that people can call best practices "just preferences" or "marketing fluff" and not be immediately laughed out of the room.
Because that's what would happen if someone suggested "best practices smells like a marketing term" in an actual engineering discipline.
Because that's what would happen if someone suggested "best practices smells like a marketing term" in an actual engineering discipline.
Which brings to the realization that we have a lot of software development and much less software engineering.
Engineer to solve the problem. Not banter online.
My problem is people take a slogan like best practices and copy-paste in every new framework because it’s de facto best practice.
If the business is one of 1,000 todo apps, sure copy paste.
But it’s new hardware best practices are different and we ought to acknowledge that software use case isn’t as uniform as electronics, where Ohms law and material waste are coupled to waste.
Language choice and syntax choice depends on the problem as the team sees it. Avoid buffer overruns, sanitize inputs.
There you have it; software best practices.
My problem is people take a slogan like best practices and copy-paste in every new framework because it’s de facto best practice.
If the business is one of 1,000 todo apps, sure copy paste.
But it’s new hardware best practices are different and we ought to acknowledge that software use case isn’t as uniform as electronics, where Ohms law and material waste are coupled to waste.
Language choice and syntax choice depends on the problem as the team sees it. Avoid buffer overruns, sanitize inputs.
There you have it; software best practices.
Sometimes "best practice" is not because we need to worship a standard, but we need to have a standard. If everyone does everything in a different manner, you wind up with a tower of babel and support becomes impossible.
I'm of the mindset where an organization needs to agree to specific principles that everyone adheres. Not dogmatically but pragmatically.
Having that shared "best practice" makes is easier to support other people code/system, allows people to get up to speed faster and as a bonus, allows you to make a blog post on Medium where you can call yourself a thought leader.
I'm of the mindset where an organization needs to agree to specific principles that everyone adheres. Not dogmatically but pragmatically.
Having that shared "best practice" makes is easier to support other people code/system, allows people to get up to speed faster and as a bonus, allows you to make a blog post on Medium where you can call yourself a thought leader.
> I'm of the mindset where an organization needs to agree to specific principles that everyone adheres.
Agreed. But GP was talking about context dependency of those best practices. E.g. what might be a good best practice for a large organization inside a FAANG might be very bad for others. Some organization have very immediate feedback cycles. A significant problem in Amazon's online shop will probably show up immediately in sales numbers. A significant problem in the control software of a plane, might kill a few hundred people in a few years before people realize there is a problem. Therefore you cannot a/b test which auto pilot works better in a certain situation. (Although Tesla might disagree about that /s).
The point is every so called "best practice" should state under which precondition it is supposed to be applied. And most blog articles and books ignore that completely.
Agreed. But GP was talking about context dependency of those best practices. E.g. what might be a good best practice for a large organization inside a FAANG might be very bad for others. Some organization have very immediate feedback cycles. A significant problem in Amazon's online shop will probably show up immediately in sales numbers. A significant problem in the control software of a plane, might kill a few hundred people in a few years before people realize there is a problem. Therefore you cannot a/b test which auto pilot works better in a certain situation. (Although Tesla might disagree about that /s).
The point is every so called "best practice" should state under which precondition it is supposed to be applied. And most blog articles and books ignore that completely.
[deleted]
My experience is that enforcing standards for everybody is really bad. Different projects are truly different and require different trade offs. Enforcing one way to do things is anti-agile.
> somebody got flamed harshly when he mentioned using a global variable.
Harsh bashing on global variables is such a dumb thing.
Yes, they can be dangerous. Yes, many had problems due to using them. Yes, we should tell beginners to avoid globals.
But there is no reason to ban them altogether. Experienced programmers should utilize them whenever it makes sense (instead of passing down a value of a local one to almost every function [sic]).
Harsh bashing on global variables is such a dumb thing.
Yes, they can be dangerous. Yes, many had problems due to using them. Yes, we should tell beginners to avoid globals.
But there is no reason to ban them altogether. Experienced programmers should utilize them whenever it makes sense (instead of passing down a value of a local one to almost every function [sic]).
Global mutable variables are generally a bad idea because they have nonlocal side effects which are difficult to mitigate, like aliased mutable pointers but worse. Extra non-aliasing arguments and multiple return values are free of these issues, and a better tradeoff in almost all cases (unless you're sure you'll never run 2 instances of a system in the same address space, and you have specialized constraints possibly including embedded/safety-critical development and emulators).
When experienced programmers utilize global variables whenever it makes sense, it tends to bite future generations. Windows's GetLastError is a mess (some functions set it on error but don't clear it on success), I'm not sure about POSIX's errno, and when threads were introduced, these variables had to be changed to thread-local state.
When experienced programmers utilize global variables whenever it makes sense, it tends to bite future generations. Windows's GetLastError is a mess (some functions set it on error but don't clear it on success), I'm not sure about POSIX's errno, and when threads were introduced, these variables had to be changed to thread-local state.
That big backing relational database of yours contains tables of "global mutable variables". The non local side effects are part of the point.
For service directory lookup, global variable is fine. For global scope queue, global variable is fine. For global scope logging service, global variable is fine.
Each of these things prevents isolated testing of dependent components. For that reason alone they are nonstarters.
globalvar = new NopImpl()
works fine for testing. If you squint, you can even think of dependency injection frameworks like Dagger as a lot of boilerplate around a global database of instantiations.> When experienced programmers utilize global variables whenever it makes sense, it tends to bite future generations.
Usually.
There is one pattern I keep using in Rails to inject the current_user for the request into the model layer. At the beginning of a request, Thread.current[:current_user] gets set to the current_user. At the end of the request, it's cleared.
For those unfamiliar, each Thread has its own Hash object and [] and []= instance methods to access it. It's a way to create global variables scoped to the current thread. To hide this implementation detail, I wrap this functionality in ApplicationRecord.current_user and ApplicationRecord.current_user= methods so no one accidentally uses :curent_user.
The most common use case for this is to automatically set created_by and updated_by on a model, the same way created_at and updated_at are set.
Cron jobs can do something like ApplicationRecord.current_user = User.cron_user if needed. Ideally, I would set this in a CronTask parent class so current_user is always available in the model layer.
I always document these methods and explain exactly what is happening and why. Abstracting away from the implementation detail mitigates most of the problems with a global variable. Obviously, the Thread.current method does not work at all if you're using an event or actor driven architecture. Rails does a thread (or process) per request, so this works extremely well.
Usually.
There is one pattern I keep using in Rails to inject the current_user for the request into the model layer. At the beginning of a request, Thread.current[:current_user] gets set to the current_user. At the end of the request, it's cleared.
For those unfamiliar, each Thread has its own Hash object and [] and []= instance methods to access it. It's a way to create global variables scoped to the current thread. To hide this implementation detail, I wrap this functionality in ApplicationRecord.current_user and ApplicationRecord.current_user= methods so no one accidentally uses :curent_user.
The most common use case for this is to automatically set created_by and updated_by on a model, the same way created_at and updated_at are set.
Cron jobs can do something like ApplicationRecord.current_user = User.cron_user if needed. Ideally, I would set this in a CronTask parent class so current_user is always available in the model layer.
I always document these methods and explain exactly what is happening and why. Abstracting away from the implementation detail mitigates most of the problems with a global variable. Obviously, the Thread.current method does not work at all if you're using an event or actor driven architecture. Rails does a thread (or process) per request, so this works extremely well.
> It's a way to create global variables scoped to the current thread.
That's not a global variable; that's a thread-scoped variable.
(It's also not (really) mutable. It gets initialized at the start of the scope and gets removed at the end of scope.)
That's not a global variable; that's a thread-scoped variable.
(It's also not (really) mutable. It gets initialized at the start of the scope and gets removed at the end of scope.)
This is one of the reasons GNU Emacs will probably never be symmetrically multithreaded.
> Yes, we should tell beginners to avoid globals.
Welcome to Dependency Injection in .Net Core!
"Those who cannot remember the past are condemned to repeat it." -- George Santayana
Welcome to Dependency Injection in .Net Core!
"Those who cannot remember the past are condemned to repeat it." -- George Santayana
On the contrary, I think beginners should use them because it reduces cognitive load in tiny applications.
My standard rebuttal to anti-global dogmatism is "there's only one instance, and never needs to be more. If/when we do, we can consider doing something else."
My standard rebuttal to anti-global dogmatism is "there's only one instance, and never needs to be more. If/when we do, we can consider doing something else."
[deleted]
But here's the thing: aren't most alternatives to global, some other kind of global state anyway, but possibly better managed?
You can just... not. Give the thing an explicit scope and lifecycle. Maybe that's actually "program lifespan", but if you make that "execution of the main() function" rather than just "IDK, somewhere", you have more visibility and control.
Singletons come to mind as being a better alternative in languages that can do that sort of thing.
Singleton is just a fancy name for a global.
Ah, but they come with the benefit that you are forced to only ever make one. A global doesn't prevent you from doing that, so singletons are ever so slightly better.
Yes, but hence a global "but .. better managed" :-)
People also bash singletons, so you can't really win.
You can get issues with a singleton being accessed for the first time from multiple threads at once, for example, so you end up with more than one instance being created or a situation where one thread triggers the creation and another accesses before it has been fully initialized, depending on the code.
You can get issues with a singleton being accessed for the first time from multiple threads at once, for example, so you end up with more than one instance being created or a situation where one thread triggers the creation and another accesses before it has been fully initialized, depending on the code.
If you expect that sort of thing to occur, then your get method should be synchronized to prevent it.
These days in both Java and Swift you can just lazily reference a static class field/property set to an instance of the singleton (in java the field must be on a dedicated private class) and the Runtime will lazily initialize it exactly once in a thread-safe manner the first time it is referenced.
That's only the tip of the iceberg I'm afraid. If the singleton has methods that perform actual work asynchronously and different threads are hammering on it, all kinds of issues come up. Of course a seasoned developer is going to acticipate this and write the needed infrastructure, but a newbie is not. It can be better if different threads have their own worker objects with their own state for example.
[deleted]
Singletons are globals, aren't they?
Kinda depends. Single instance things are usually globally referenced, but as long as you're referencing an instance and not a static thing they're not hard to convert to an "injected" dependency if you need to provide a test impl to some thing being tested. The real problem is static things that can't be swapped out because you're actually calling static methods on some class rather than sharing an instance and calling instance methods.
I understand "singleton" as "only one exists" and "it exists in the global scope". That is, if I create one instance of something in my `int main()` that's not enough for it to be a singleton. That's important, because there's more than one way to enter your program. Notably, tests don't flow through your main entrypoint.
Almost assuredly better managed. There are no reasons to manage state on the global level apart from laziness.
Sweeping statements like that are the real laziness. All it proves is that you lack diverse experience in software development.
I'm a big advocate for functional programming but even I have to concede that in some domains, and particularly in some languages, when you're having to manage universal properties those properties are sometimes best placed at a global level.
I'm a big advocate for functional programming but even I have to concede that in some domains, and particularly in some languages, when you're having to manage universal properties those properties are sometimes best placed at a global level.
Funny you should mention that. I've used ocornut's ImGui library in the past, with a single, hierarchical object that managed the entire GUI state.
This approach caused whole classes of problems that affect regular GUIs to simply disappear, and it was the most performant, least buggy UI I've ever written by a country mile.
This approach caused whole classes of problems that affect regular GUIs to simply disappear, and it was the most performant, least buggy UI I've ever written by a country mile.
It's quite common in python to manage/encapsulate a global by wrapping it in a module, so arguably a singleton is the same thing, just encapsulating in a class/class-instance instead?
but even if the prog-lang had specific support for safe(r) globals, it would still just be a global at the lower (higher?) level.
but even if the prog-lang had specific support for safe(r) globals, it would still just be a global at the lower (higher?) level.
Isn't Redux doing this exact thing?
It is best practise to use RCCBs, because it turned out faulty wiring can kill people. But in Server rooms where you might not want to switch off the whole rack without warning when one device is faulty, you can use a device to monitor the residual current (RCM). Which issues a warning first, and only switches of when the residual current raises over the acceptable level. Different scenario, different best practise. (This is also the reason medical equipment is expensive).
I think a professional should be aware why a best practise exists and how to deal with a situation where for some reason it cannot be applied as you showed with the embedded example.
Don't forget however that many devs are against best practises out of lazyness or because they don't understand the reasons why they are best pracises.
I think a professional should be aware why a best practise exists and how to deal with a situation where for some reason it cannot be applied as you showed with the embedded example.
Don't forget however that many devs are against best practises out of lazyness or because they don't understand the reasons why they are best pracises.
Identifying a best practice is actually not as hard as people realize imo (although it may take some time), and only becomes hard when you let emotion and sources of emotion come into what should be a rational decision making process (such as preference for a certain tooling for reasons like familiarity or popularity in the field today rather than outright advantages vs other tooling).
To identify the best practice for anything, you start by doing a review of all the available practices in the field for a given problem you are working on. Then once you've reviewed the literature you can work out the pros, cons, caveats of each of these tools, and how these considerations affect your particular use case and your expected results. Then after doing that, the best practice out of available options will be readily apparent, or at the very least strongly justified, not by an appeal to authority or popularity or familiarity, but by looking at what the underlying technology actually does and how its relevant or not to your particular task at hand. In the end you will find the very best hammer available out of all the hammers people have made in this field for your particular unique nail.
To identify the best practice for anything, you start by doing a review of all the available practices in the field for a given problem you are working on. Then once you've reviewed the literature you can work out the pros, cons, caveats of each of these tools, and how these considerations affect your particular use case and your expected results. Then after doing that, the best practice out of available options will be readily apparent, or at the very least strongly justified, not by an appeal to authority or popularity or familiarity, but by looking at what the underlying technology actually does and how its relevant or not to your particular task at hand. In the end you will find the very best hammer available out of all the hammers people have made in this field for your particular unique nail.
That sounds like a beautiful example of letting perfect be the enemy of good.
Just like your design choices have trade-offs, is it important to realize that there's a trade-off between finishing sooner and making a better solution. Diminishing returns are usually very much in play with analysis.
(I would also challenge the notion that every situation has a different "best practice". That's just creating a solution. "Best practices" are usually general advise that is applicable in most situations.)
Just like your design choices have trade-offs, is it important to realize that there's a trade-off between finishing sooner and making a better solution. Diminishing returns are usually very much in play with analysis.
(I would also challenge the notion that every situation has a different "best practice". That's just creating a solution. "Best practices" are usually general advise that is applicable in most situations.)
You shouldn't take forever, but what I'm saying is a best practice emerges after doing however much due diligence. Maybe you spend an hour looking into it and that's it, but you should do your due diligence to vet what sort of approaches you can take to solve your particular problem as best you can, so you can make the best decision based on the evidence you've been able to find within however much time you are working with. A professor gave me a word of advice once, "a week in a library can save a month in the lab."
Most decisions don't require that much thought. They're low stakes and can easily be changed. To build on the professor's metaphor: don't spend a week in the library in it'll only save you a day.
If it's a bit more important, do a quick Google, but only break out Excel for the comparison tables if the decision is life-changing.
Honestly, the most important thing that professors don't teach and real life does is that sometimes the optimal thing to do is to not do the optimal thing.
If it's a bit more important, do a quick Google, but only break out Excel for the comparison tables if the decision is life-changing.
Honestly, the most important thing that professors don't teach and real life does is that sometimes the optimal thing to do is to not do the optimal thing.
Two different “experts” will do this and arrive at different conclusions. Now what.
> Calling something a "best practice" is basically an appeal to authority.
If presented on its own, but then, any conclusion presented on its own without supporting context and analysis is the same.
> But really, "best" and "right" are highly situational
A description of a best practice that doesn't provide a sufficiently precise description of the situation to which it applies as a best practice is generally inappropriate, unless it is the conclusion of an analysis of applicable best practices to a certain situation, in which case the scope is specified in framing the analysis.
It is true that lots of things described as best practices for particular situations with supporting rationale and up getting detached from their logic and context and becoming cargo cult best practices.
If presented on its own, but then, any conclusion presented on its own without supporting context and analysis is the same.
> But really, "best" and "right" are highly situational
A description of a best practice that doesn't provide a sufficiently precise description of the situation to which it applies as a best practice is generally inappropriate, unless it is the conclusion of an analysis of applicable best practices to a certain situation, in which case the scope is specified in framing the analysis.
It is true that lots of things described as best practices for particular situations with supporting rationale and up getting detached from their logic and context and becoming cargo cult best practices.
Even worse are people that talk of "code smells", applying their personal opinion of style in a judgmental and often unjustifed way.
Code smells aren’t conceptually about style but indicators of potential (possibly latent) bugs. A code smell is different than a style problem (though they overlap), its a thing that warrants attention because of risk of hiding errors.
Smart experienced software developers disagree on “best practices” all the time. What is “obviously” the best practice to you is “obviously” not the best practice for somebody else. Now what?
> He then explained that he was working on an embedded control system for cars and all the variables in that system were global.
Everyone should write Embedded at least once. It's a completely different world.
Everyone should write Embedded at least once. It's a completely different world.
and hard real-time.
It really inverts some priorities (I mean development priorities, not the priority inversion on mars pathfinder)
It really inverts some priorities (I mean development priorities, not the priority inversion on mars pathfinder)
The biggest issue I saw with "best practices" in my career is the failure to take into account who it claiming it to be a best practice, and in what context. I saw too many junior developers read a rando blog article, then get a non-technical / semi-technical manager excited about something that made their life easier, even though it was by no means a good practice for the context at hand. Or alternatively, believe some vendor carte blanche when they tell you their product somehow follows a best practice.
The overarching problem is that yes, there is software engineering going on in the world, but most organizations are not willing to do engineering. I don't blame the technical staff - they often have good intentions - but rather the typical business is not willing to pay the cost in time or money to do long-lasting engineering practices. This is one of the things not enough of us think about in our career choices - am I going to a place that practices fire drills or engineering?
The overarching problem is that yes, there is software engineering going on in the world, but most organizations are not willing to do engineering. I don't blame the technical staff - they often have good intentions - but rather the typical business is not willing to pay the cost in time or money to do long-lasting engineering practices. This is one of the things not enough of us think about in our career choices - am I going to a place that practices fire drills or engineering?
Spot on about reading a random blog or article. I think many engineers at work are under pressure to deliver, and are looking for quick solutions. They do a search and see a Medium post related to their problem written by someone who says they are an “<platform> developer at <company>”, and for some reason most readers see these authors as an authority in their domain (because why else would they be writing about it? /s), and just accept the blog post’s practices or conclusions. Once read an article a long time ago about Android’s async task , and some blog post claimed it should only be used for operations less than one second. I looked at the official documentation and while it did mention that it should be used for short operations, no where did it mention it should be less than one second specifically (unless I missed it). I saw the same advice mentioned by many other devs who referenced that same article.
To add on to this, the current most preached about "best practices" comes largely from a de-risking, never-ever fail point of view, ie. 'safety'. Unfortunately with such standards also comes a concept known as 'acccountability', ie. 'ass-covering' practices that provide little practical value.
This results in programmers no longer being able to iterate fast and having to rely on some third-party whose tradeoffs they don't understand, resulting in slow, bloated software and dissatisfied programmers.
This results in programmers no longer being able to iterate fast and having to rely on some third-party whose tradeoffs they don't understand, resulting in slow, bloated software and dissatisfied programmers.
I am not sure if I read you right here (correct me if I am wrong), but do you say that safety and stability concerns lead to bloated software because devs cannot blindly trust third party dependecies?
Because if so, yeah. You are responsible for the software you write and the dependecies you use. Software engineering is one of the least responsible engineering diciplines anyways. I am e.g. also a certified electrical engineer and of course I am responsible if my wrong decisions kill someone. If I would use a cheap chinese knockoff circuit breaker (because we can iterate faster if the stuff isn't expensive and certified) and someone gets killed, I go to jail. If someone gets killed and I can proof that I followed the currently agreed on state of technology my ass is covered. Of course you can get a lightbulb to light up without following any rule (and maybe this would be more efficient), but in EE the existing rules came as a consequence of deaths and rhe prevention of those is worth it.
In software engineering the worst that can usually happen (unless you work in IOT or industrial applications) is that you loose your user data. Many software devs don't care about whether they loose their users data and there are no tangible consequences. "Oh it was a software error" is still a good excuse, as if there was nothing which could have prevented that software error. I program software myself but I am al for stricter consequences in our profession because it would straighten out some heads who think this is all just fun and games for their personal joy.
Because if so, yeah. You are responsible for the software you write and the dependecies you use. Software engineering is one of the least responsible engineering diciplines anyways. I am e.g. also a certified electrical engineer and of course I am responsible if my wrong decisions kill someone. If I would use a cheap chinese knockoff circuit breaker (because we can iterate faster if the stuff isn't expensive and certified) and someone gets killed, I go to jail. If someone gets killed and I can proof that I followed the currently agreed on state of technology my ass is covered. Of course you can get a lightbulb to light up without following any rule (and maybe this would be more efficient), but in EE the existing rules came as a consequence of deaths and rhe prevention of those is worth it.
In software engineering the worst that can usually happen (unless you work in IOT or industrial applications) is that you loose your user data. Many software devs don't care about whether they loose their users data and there are no tangible consequences. "Oh it was a software error" is still a good excuse, as if there was nothing which could have prevented that software error. I program software myself but I am al for stricter consequences in our profession because it would straighten out some heads who think this is all just fun and games for their personal joy.
IMO, much of the low engineering standards in software is from a (potentially false) awareness in the industry that most products we work on simply aren't that valuable. If a bug deletes my Twitter account, that sucks to me be for a day but no real harm was done. The people who work in banking or healthcare IT tend to know better and have correspondingly higher (though still shockingly low) standards.
Haha. The banks ought to know better, but in fact due to software being hard to prove correct, we still get major disasters like the TSB migration failure. It caused real world problems like peoples house purchase deals falling through and money getting lost:
https://www.theguardian.com/business/2018/jun/06/timeline-of...
The thing, is there is seemingly no appetite to try to prove correctness of even single machines systems. Let alone distributed systems. I wonder if ever there will be a time where this kind of proof is cheap enough to be acceptable to business.
https://www.theguardian.com/business/2018/jun/06/timeline-of...
The thing, is there is seemingly no appetite to try to prove correctness of even single machines systems. Let alone distributed systems. I wonder if ever there will be a time where this kind of proof is cheap enough to be acceptable to business.
Do you have any concrete examples of that? I think I kind of see what you mean, and I have a feeling that this is mostly right, but I'm not sure.
Managers excited about a new tech idea are probably the most destructive thing in the industry.
As are managers that conform to archaic tech when better options exist.
Especially when maintaining and adding to a legacy system takes more effort and risks than simply rebuilding it.
Nah, just rewrite the code base.
> I saw too many junior developers read a rando blog article, then get a non-technical / semi-technical manager excited about something that made their life easier, even though it was by no means a good practice for the context at hand.
I’ve seen the other way around too - senior developers rejecting or pushing changes that they find convenient. IME it’s not to do with experience, rather stubbornness.
I’ve seen the other way around too - senior developers rejecting or pushing changes that they find convenient. IME it’s not to do with experience, rather stubbornness.
> How can Software Engineers call themselves engineers when there’s no rules, governing bodies, or anything to stipulate what true Software Engineering is?
We call ourselves software developers in Canada.
According to Canadian engineering[1]: The "practice of engineering" means any act of planning, designing, composing, evaluating, advising, reporting, directing or supervising, or managing any of the foregoing, that requires the application of engineering principles, and that concerns the safeguarding of life, health, property, economic interests, the public welfare, or the environment.
To be considered a work of engineering, then, that a piece of software (or a software-intensive system) must meet two conditions:
1. The development of the software has required “the application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software.”
2. There is a reasonable expectation that failure or inappropriate functioning of the system would result in harm to life, health, property, economic interests, the public welfare, or the environment
[1] - https://engineerscanada.ca/news-and-events/news/when-softwar...
We call ourselves software developers in Canada.
According to Canadian engineering[1]: The "practice of engineering" means any act of planning, designing, composing, evaluating, advising, reporting, directing or supervising, or managing any of the foregoing, that requires the application of engineering principles, and that concerns the safeguarding of life, health, property, economic interests, the public welfare, or the environment.
To be considered a work of engineering, then, that a piece of software (or a software-intensive system) must meet two conditions:
1. The development of the software has required “the application of a systematic, disciplined, quantifiable approach to the development, operation, and maintenance of software.”
2. There is a reasonable expectation that failure or inappropriate functioning of the system would result in harm to life, health, property, economic interests, the public welfare, or the environment
[1] - https://engineerscanada.ca/news-and-events/news/when-softwar...
> "The 'practice of engineering' means any act … that requires the application of engineering principles"
Error: cycle detected. ^__^
Software is by its very nature systematic and quantifiable. Is the quibble with whether programmers are disciplined?
All software companies would meet the "failure or inappropriate functioning of the system would result in harm to … economic interests" criterion.
Error: cycle detected. ^__^
Software is by its very nature systematic and quantifiable. Is the quibble with whether programmers are disciplined?
All software companies would meet the "failure or inappropriate functioning of the system would result in harm to … economic interests" criterion.
It's like everyone has forgotten third grade.
Define this word without using the word.
Lift: British English. A machine that lifts peo... damnit!
Define this word without using the word.
Lift: British English. A machine that lifts peo... damnit!
I aggressively refuse to call myself an engineer. Programmer is fine. Developer is better, because programming is only a piece of it. Y’all can call yourselves whatever you like, but inside I’m thinking you retconned an industry insider euphemism into a non-existent sub-type of engineering, by protesting all the ways you apply rigor to what we do.
What of those who graduated from engineering programs taught at engineer colleges?
Lots of people in other engineering disciplines build stuff with less rigor than is used to build software. Maybe load test it in Fusion 360 before sending the file to be milled. And lots of software companies test their stuff quite rigorously.
People who write software have imposter syndrome. Other disciplines are not building things better than we do. For every Google there's a Ford, and for every scrappy startup there's a scrappy machine shop.
Lots of people in other engineering disciplines build stuff with less rigor than is used to build software. Maybe load test it in Fusion 360 before sending the file to be milled. And lots of software companies test their stuff quite rigorously.
People who write software have imposter syndrome. Other disciplines are not building things better than we do. For every Google there's a Ford, and for every scrappy startup there's a scrappy machine shop.
> What of those who graduated from engineering programs taught at engineer colleges?
For new grads? In my experience, they're usually miles behind an 18 year old who has been messing around in their spare time for a few years. There are, of course, exceptions, but at this point seeing something they don't teach at the local universities is more eye-catching on a resume than most degrees.
It usually means they bothered to learn something on their own.
For new grads? In my experience, they're usually miles behind an 18 year old who has been messing around in their spare time for a few years. There are, of course, exceptions, but at this point seeing something they don't teach at the local universities is more eye-catching on a resume than most degrees.
It usually means they bothered to learn something on their own.
> What of those who graduated from engineering programs taught at engineer colleges?
We are the actual Engineers. For US-Based IT workers, that means a degree from an ABET [1] backed institution with a traditional undergrad and graduate programs.
Anyone else calling themselves an "engineer" while doing IT work are not.
In addition: Readers need to remember this isn't reddit and downvoting comments with facts you do not like is not appropriate for Hacker News. It's is depressing this reminder needs to be added here for facts as it appears a few readers here have forgotten already.
[1] https://www.abet.org/
We are the actual Engineers. For US-Based IT workers, that means a degree from an ABET [1] backed institution with a traditional undergrad and graduate programs.
Anyone else calling themselves an "engineer" while doing IT work are not.
In addition: Readers need to remember this isn't reddit and downvoting comments with facts you do not like is not appropriate for Hacker News. It's is depressing this reminder needs to be added here for facts as it appears a few readers here have forgotten already.
[1] https://www.abet.org/
That's all just protectionism. Or an attempt at it, because it's clearly not working in the software industry.
I am a graduate of such a school and it is a pain to even use that (earned and legally awarded) title in an international context because countries only recognise their own schools. Even in the EU, with its standardized EU-wide titles, you still can't use the "local" title of another country. Even if both titles are accredited to the same EU-title.
It's all status games and protectionism. And it's a silly war to fight, because no one thinks a "software engineer" is an accredited engineer anymore anyway.
I am a graduate of such a school and it is a pain to even use that (earned and legally awarded) title in an international context because countries only recognise their own schools. Even in the EU, with its standardized EU-wide titles, you still can't use the "local" title of another country. Even if both titles are accredited to the same EU-title.
It's all status games and protectionism. And it's a silly war to fight, because no one thinks a "software engineer" is an accredited engineer anymore anyway.
Just because a private organization says they have monopoly on the word “engineer” doesn’t mean they actually do.
Exactly this. Being told who the "real" engineers are is simply a good way of parting suckers with their money for "accreditation" or whatever such nonsense.
Completely depressing looking back at this thread and realizing that Hacker News has an issue with users holding advance degrees. I expect this jealousy and hatred from sites like reddit and Facebook, it should not be tolerated here on HN. This is NOT ok behavior especially from the amount of work these graduates and institutions have pushed into our fields. There is a complete lack of respect here and it shows.
You are not an engineer if you did not flow through an ABET institution. You're a developer, nothing wrong with that but you're not an Engineer. No, I do not care if your company has other certain titles, those are easily made up and have no academic backing.
This behavior we're seeing here is the same as if I pretended I was an MD after taking a first-aid-class. It's disrespectful to those that put in the effort to expand our academic understandings and our capabilities for others to turn around and then pretend that title is their own.
It is not.
You are not an engineer if you did not flow through an ABET institution. You're a developer, nothing wrong with that but you're not an Engineer. No, I do not care if your company has other certain titles, those are easily made up and have no academic backing.
This behavior we're seeing here is the same as if I pretended I was an MD after taking a first-aid-class. It's disrespectful to those that put in the effort to expand our academic understandings and our capabilities for others to turn around and then pretend that title is their own.
It is not.
I would trust someone graduating with CS degree from non-ABET accredited Stanford rather than someone from ABET-accredited CS program of Athens State University.
... Except Stanford is ABET accredited, and as are all the major Engineering institutions and leaders.
The fact that most users here are reaching to downvote literally the fact that leading Engineering institutions all fall in this bucket is absolutely depressing from this community. It's clear some feelings have been "hurt" here by other users having higher educations.
The fact that most users here are reaching to downvote literally the fact that leading Engineering institutions all fall in this bucket is absolutely depressing from this community. It's clear some feelings have been "hurt" here by other users having higher educations.
It's not all-or-nothing for the university -- some programs are not.
"Like the CS department, the EE department is no longer ABET accredited. While such accreditation is useful in certain disciplines such as civil engineering, it has no practical significance whatsoever in computer science."
https://cs.stanford.edu/degrees/undergrad/Considering.shtml
Similarly, UC Berkeley also declined to renew their ABET acreditation for their EECS department, and so they haven't been ABET-accredited for the past few years.
"Both of these programs are accredited by ABET through September 30, 2019, but because we have decided not to continue applying for ABET accreditation, we will be developing a single set of student learning outcomes for our department, rather than using the two sets of outcomes mandated by ABET for EECS departments. "
https://eecs.berkeley.edu/academics/undergraduate/eecs-bs/ob...
"Like the CS department, the EE department is no longer ABET accredited. While such accreditation is useful in certain disciplines such as civil engineering, it has no practical significance whatsoever in computer science."
https://cs.stanford.edu/degrees/undergrad/Considering.shtml
Similarly, UC Berkeley also declined to renew their ABET acreditation for their EECS department, and so they haven't been ABET-accredited for the past few years.
"Both of these programs are accredited by ABET through September 30, 2019, but because we have decided not to continue applying for ABET accreditation, we will be developing a single set of student learning outcomes for our department, rather than using the two sets of outcomes mandated by ABET for EECS departments. "
https://eecs.berkeley.edu/academics/undergraduate/eecs-bs/ob...
[deleted]
[deleted]
Isn’t it easier to just stick to the term and not fight with it? Everyone involved knows that “software engineering” is not like “civil engineering”, and those who don’t, usually don’t know either. It has no legal nor practical sense, so why bother?
>It has no legal nor practical sense, so why bother?
You might be surprised to know that it actually does matter, and it matters in a way that depresses American software engineer salaries: work visas.
The fact that the US government considers "software engineering" to be equal to "civil engineering" means that the TN visa (since we're talking about Canada) applies to people qualified to be employed as software engineers in the US.
As such, this visa allows tens of thousands of equally-qualified software engineers from Canada to compete for a good proportion of the same jobs thereby depressing American wages; why wouldn't an American software engineer (or a Canadian P.Eng who wants to make a business but can't afford the better engineers) be opposed to the weak American definition being the only one that really matters?
You might be surprised to know that it actually does matter, and it matters in a way that depresses American software engineer salaries: work visas.
The fact that the US government considers "software engineering" to be equal to "civil engineering" means that the TN visa (since we're talking about Canada) applies to people qualified to be employed as software engineers in the US.
As such, this visa allows tens of thousands of equally-qualified software engineers from Canada to compete for a good proportion of the same jobs thereby depressing American wages; why wouldn't an American software engineer (or a Canadian P.Eng who wants to make a business but can't afford the better engineers) be opposed to the weak American definition being the only one that really matters?
Note that Computer Systems Analyst is a profession listed in NAFTA; I was at a company where they used that. Also, the NAFTA definition of Engineer doesn't require a P. Eng title.
(https://www.nafsa.org/_/file/_/amresource/8cfr2146.htm was linked from state.gov)
(https://www.nafsa.org/_/file/_/amresource/8cfr2146.htm was linked from state.gov)
It didn’t used to bother me back when I could assume everyone else understood it was an industry specific title based on a metaphor! I even used to defend the title by saying, “Relax; it’s an industry-specific title, not a kind of engineer.” Like “Software Architect” is understood not to be a kind of architect. But over the last few years I’ve seen dozens of HNers lay out technical arguments for why they ARE engineers.
So, I never took a single engineering class, have no engineering cert, don’t know much about the ethos, and barely even know the definition without looking it up. But I’m supposed to not rock the boat, and claim to be one, like I accidentally became an engineer in the course of designing, planning, fortifying, testing, and measuring software? Like Daniel-san accidentally became a karate master by waxing cars?
Sorry, no. Our “engineering” is just another partially applicable metaphor for what software devs do. But software development is its own set of disciplines. It’s wonderful to pull helpful concepts from other disciplines, but I draw the line at coopting the whole designation.
So, I never took a single engineering class, have no engineering cert, don’t know much about the ethos, and barely even know the definition without looking it up. But I’m supposed to not rock the boat, and claim to be one, like I accidentally became an engineer in the course of designing, planning, fortifying, testing, and measuring software? Like Daniel-san accidentally became a karate master by waxing cars?
Sorry, no. Our “engineering” is just another partially applicable metaphor for what software devs do. But software development is its own set of disciplines. It’s wonderful to pull helpful concepts from other disciplines, but I draw the line at coopting the whole designation.
Margaret Hamilton coined the term. But then again, anyone who can keep a lunar lander from turning into a new crater probably has more right to that term than most of us.
Well crap, I guess I’m going to have to burn my diploma that clearly says I’m an electrical engineer.
I believe I heard this in the Pragmatic Programmer: engineering is the practice of applying scientific understanding to real world problems. Or more succinctly, engineering is applied science. So software engineering is applying computer science to solve real world problems.
The second condition is a bit stupid, most failures or inappropriate functioning of the system in software development can be considered a harm in economic interests...
I write server-side software for a security system - anyone else can write a similarly complex piece of software to monitor grains of sand on the beach. So I am an engineer and they are not just because my software is used by some pre-described group of people?
“It’s not real engineering if someone can’t get hurt” seems like a strange definition to me.
That's because it is a strange definition.
If you work on the software in a self driving system in a car, that makes you an engineer. If you're working on software for a space satellite with no occupants... that's not an engineer?
If you work on the software in a self driving system in a car, that makes you an engineer. If you're working on software for a space satellite with no occupants... that's not an engineer?
Well, the failure of a satellite would definitely result in harm to property and economic interests, so it sounds like you would still be an engineer in that case.
Yes, I think we sometimes use the term "Engineer" a little too liberally in the US. For example, sometimes the janitor of an office building is called a "Custodial Engineer" which often just gets shortened to "Engineer". I remember the first time I heard a coworker say, "I'll call the engineer to have the thermostat adjusted". I thought that was overkill, but then a guy in overalls showed up and it made a little more sense.
Was your colleague from the UK? A number of trade professions in the UK are referred to as Engineers, such as for the boiler etc.
So what do you call electrical engineers who design consumer level non mains voltage hardware? Looks like they fail the second bullet point. Sort of an honest question, since most of what you’d likely learn in an EE degree would probably not fall under number 2 either.
We call Software Developers to coders and then, Consultant or Software Architect to the ones who design the systems. In between you have Analysts.
Any of them can be Software Engineers or not, because we call Software Engineers to the ones with the university career finished
Any of them can be Software Engineers or not, because we call Software Engineers to the ones with the university career finished
The wonderful Hillel Wayne has two great essays on the "Engineer"ing question:
https://www.hillelwayne.com/post/are-we-really-engineers/
https://www.hillelwayne.com/post/we-are-not-special/
https://www.hillelwayne.com/post/are-we-really-engineers/
https://www.hillelwayne.com/post/we-are-not-special/
It'll be interesting to see if they can ever manage to enforce it. I haven't heard of any cases yet since Microsoft challenged them and won.
Microsoft lost their appeal in Quebec
https://www.oiq.qc.ca/en/media/pressReleases/Pages/default.a...
https://www.oiq.qc.ca/en/media/pressReleases/Pages/default.a...
That's interesting, thanks for sharing!
INAL; it seems, to me, difficult to enforce. You're not allowed to call yourself an engineer but you can still practice as one as long as you call yourself a developer. What's the difference? In practice... very little.
Most developers I know do all the things professional engineers do.
Unless the government wants to step in and say that you're not allowed to release software without a professional software engineer at the helm I think it's trivial. Unless a company pays the insurance of an engineer and faces severe penalties for disregarding their direction I don't see the point of hiring a professional software engineer. Companies will simply hire developers rather than deal with trifling matters like liability.
And we'll continue to see avoidable security breaches in the wild for ever and onward because of it. The financial incentives are behind "move fast and break things," rather than "protect the public interest."
(Mind you I think we should have more of the latter and I'm all for liability for the things we create as long as we're in control of our future... I'll take the exam if I can be brought in with my 20+ years of experience)
INAL; it seems, to me, difficult to enforce. You're not allowed to call yourself an engineer but you can still practice as one as long as you call yourself a developer. What's the difference? In practice... very little.
Most developers I know do all the things professional engineers do.
Unless the government wants to step in and say that you're not allowed to release software without a professional software engineer at the helm I think it's trivial. Unless a company pays the insurance of an engineer and faces severe penalties for disregarding their direction I don't see the point of hiring a professional software engineer. Companies will simply hire developers rather than deal with trifling matters like liability.
And we'll continue to see avoidable security breaches in the wild for ever and onward because of it. The financial incentives are behind "move fast and break things," rather than "protect the public interest."
(Mind you I think we should have more of the latter and I'm all for liability for the things we create as long as we're in control of our future... I'll take the exam if I can be brought in with my 20+ years of experience)
In this case, I think the enforcement wasn't on the people using the tittle. Rather it was on Microsoft "granting" someone the tittle of "Engineer".
"Microsoft Corporation announced in May 2001 its intention to stop using the term engineer in Canada in the title Microsoft Certified System Engineers - MCSE."
Going against the individual professionals for using the tittle might have been harder. Some are probably real engineers or have received the certification but don't necessarily advertise themselves as engineers...
"Microsoft Corporation announced in May 2001 its intention to stop using the term engineer in Canada in the title Microsoft Certified System Engineers - MCSE."
Going against the individual professionals for using the tittle might have been harder. Some are probably real engineers or have received the certification but don't necessarily advertise themselves as engineers...
It's a bit like saying that you are a doctor, nurse or a lawyer (attorney?). In Canada these are protected titles that can only be used if you are part of a professional order that has oversight over your activities and can audit your work at basically any time. There are some tasks that can only be performed if you are certified and pay the annual fees.
Where this falls apart is that "Software Engineering" is a real discipline recognized by the organization that handles engineering programs in Canada, however there are no "reserved tasks" so a lot of Software Developers have a Software Engineering degree but can't call themselves that because they (rightfully in my opinion but still) refuse to pay the annual membership fees (about 600$) since their professional order is actually not equipped to audit software engineering work.
Hopefully that helps a little.
Where this falls apart is that "Software Engineering" is a real discipline recognized by the organization that handles engineering programs in Canada, however there are no "reserved tasks" so a lot of Software Developers have a Software Engineering degree but can't call themselves that because they (rightfully in my opinion but still) refuse to pay the annual membership fees (about 600$) since their professional order is actually not equipped to audit software engineering work.
Hopefully that helps a little.
Exactly what I was trying to get across. The protected term is meaningless even if enforced, it seems to me, because there are no "reserved tasks," as you say.
It's bit like... being able to practice law as long as you don't call yourself a lawyer. You're a legal assistant instead. In a similar fashion developers are practising software engineering without calling themselves, "engineers."
I don't think we all need to be licensed in order to work -- but companies should be required to hire X number of licensed engineers per Y number of developers. They should be required to pay for the liability insurance to hire those licensed engineers. And there should be repercussions if the company goes against the engineers' direction.
It's bit like... being able to practice law as long as you don't call yourself a lawyer. You're a legal assistant instead. In a similar fashion developers are practising software engineering without calling themselves, "engineers."
I don't think we all need to be licensed in order to work -- but companies should be required to hire X number of licensed engineers per Y number of developers. They should be required to pay for the liability insurance to hire those licensed engineers. And there should be repercussions if the company goes against the engineers' direction.
For what it's worth, the latest revision of the Engineers Act in Quebec (2020, the previous revision was from 1962), has a much wider definition of engineering works and reserved acts, which does include software, if it can have an impact on the safety of persons.
I am not a lawyer (mech engineer), but that's the message that the OIQ has been sending lately. It's unclear when and how they plan to start applying these new regulations.
I am not a lawyer (mech engineer), but that's the message that the OIQ has been sending lately. It's unclear when and how they plan to start applying these new regulations.
I believe that Shopify will change your job title from Engineer to Engineering Technician (or something of that nature) if you don't have your professional engineering certification.
I've met Canadian Software Engineers who referred to themselves as Software Engineers...
Some of us call ourselves "engineers". It just depends whether you want to pay the order for the privilege of having the title (and pretty much no other tangible benefit in 90+% of cases) :).
Genuine question. What is so important about the word "engineer" that people not licensed to practice it want to call themselves engineer?
In Canada, I studied in a mechanical engineering technology program that lead to an engineering degree if you stayed on for 4 years. It was hammered into us that we weren't engineers until after you graduated and went through the professional licensing process.
In Canada there is a way to become a P.Eng. in software engineering (and until 2018 in the US there was the P.E. in software engineering), so there is a way for someone who wants to be called a software engineer to legally obtain it. So why is there so much resistance?
In Canada, I studied in a mechanical engineering technology program that lead to an engineering degree if you stayed on for 4 years. It was hammered into us that we weren't engineers until after you graduated and went through the professional licensing process.
In Canada there is a way to become a P.Eng. in software engineering (and until 2018 in the US there was the P.E. in software engineering), so there is a way for someone who wants to be called a software engineer to legally obtain it. So why is there so much resistance?
> So why is there so much resistance?
Because,
1) a PE license is useless for software/computer engineering.
2) the FE exam covers a bunch of irrelevant material.
3) once you pass the FE exam, there's no real mechanism to advance because there are no apprenticeships available in computer engineering. And you can't take the PE exam without the apprenticeship.
My college spent a lot of money getting an ABET accreditation for their CS/CE programs. As such, they pushed students really, really, really hard to take the FE exam. I went down the path to getting it and realized those aforementioned points. The study guide covered electronics theory that I had no idea about. It also covered silicon chemistry, which was only briefly covered at very high levels.
So I'd be learning pretty complex topics on my own, which have no professional value. Then, if I wanted to take the PE exam, I'd have to find a job where I could apprentice for four years. And, as we know, sticking with a job that long is terrible for your lifetime earnings.
So yeah, PEs are never going to be a thing in software unless they fundamentally change how engineers are licensed. Maybe if it was like nursing or law school where there's a big exam afterwards that you can take, and if you pass, you're licensed. But as it stands now, four years of apprenticeship after 4-5 years of schooling is ridiculous.
Because,
1) a PE license is useless for software/computer engineering.
2) the FE exam covers a bunch of irrelevant material.
3) once you pass the FE exam, there's no real mechanism to advance because there are no apprenticeships available in computer engineering. And you can't take the PE exam without the apprenticeship.
My college spent a lot of money getting an ABET accreditation for their CS/CE programs. As such, they pushed students really, really, really hard to take the FE exam. I went down the path to getting it and realized those aforementioned points. The study guide covered electronics theory that I had no idea about. It also covered silicon chemistry, which was only briefly covered at very high levels.
So I'd be learning pretty complex topics on my own, which have no professional value. Then, if I wanted to take the PE exam, I'd have to find a job where I could apprentice for four years. And, as we know, sticking with a job that long is terrible for your lifetime earnings.
So yeah, PEs are never going to be a thing in software unless they fundamentally change how engineers are licensed. Maybe if it was like nursing or law school where there's a big exam afterwards that you can take, and if you pass, you're licensed. But as it stands now, four years of apprenticeship after 4-5 years of schooling is ridiculous.
Most companies already have the "apprenticeship" half-codified in "Junior Developer" versus "Senior Developer" distinctions or "Level Ranks" or other ladders like that. If you switch jobs mid-"apprenticeship" today in the software industry depending on who you interview with and how well you can negotiate you either "start over" at a low rank/level/job title or luck/bs into "skipping that step" and jumping to a higher rank/level/job. Standardizing that across the industry wouldn't necessarily be a bad thing for the industry.
Similarly, PE licenses would be so hugely worth it to the industry if it saved everyone time in "technical interviews", both interviewees and interviewers alike. How many collective labor hours as an industry are we wasting annually on "technical interviews"? For most classic Civil Engineering firms the "technical" part of the interview is almost entirely "Is your PE license valid and up to date?" "Yes." "Great, you're hired." The software industry would rather waste multiple hours (if not entire days) of wages of everyone involved instead, and it's rather sad when you think about it.
Similarly, PE licenses would be so hugely worth it to the industry if it saved everyone time in "technical interviews", both interviewees and interviewers alike. How many collective labor hours as an industry are we wasting annually on "technical interviews"? For most classic Civil Engineering firms the "technical" part of the interview is almost entirely "Is your PE license valid and up to date?" "Yes." "Great, you're hired." The software industry would rather waste multiple hours (if not entire days) of wages of everyone involved instead, and it's rather sad when you think about it.
> Most companies already have the "apprenticeship" half-codified in "Junior Developer" versus "Senior Developer" distinctions or "Level Ranks" or other ladders like that. If you switch jobs mid-"apprenticeship" today in the software industry depending on who you interview with and how well you can negotiate you either "start over" at a low rank/level/job title or luck/bs into "skipping that step" and jumping to a higher rank/level/job. Standardizing that across the industry wouldn't necessarily be a bad thing for the industry.
In my experience no-one cares who's "junior" or "senior" day-to-day, and no-one can compare levels across multiple companies, and that's good for the industry; I've worked with plenty of "juniors" who were better than corresponding "seniors", standardising and formalising some years-of-experience metric would make the industry much less meritocratic.
> Similarly, PE licenses would be so hugely worth it to the industry if it saved everyone time in "technical interviews", both interviewees and interviewers alike. How many collective labor hours as an industry are we wasting annually on "technical interviews"? For most classic Civil Engineering firms the "technical" part of the interview is almost entirely "Is your PE license valid and up to date?" "Yes." "Great, you're hired." The software industry would rather waste multiple hours (if not entire days) of wages of everyone involved instead, and it's rather sad when you think about it.
I've yet to find any software-related qualification that wasn't an active negative. I've worked in a place that applied the acknowledged "best practices" of 10 years ago and it was a terrible environment for producing good code.
In my experience no-one cares who's "junior" or "senior" day-to-day, and no-one can compare levels across multiple companies, and that's good for the industry; I've worked with plenty of "juniors" who were better than corresponding "seniors", standardising and formalising some years-of-experience metric would make the industry much less meritocratic.
> Similarly, PE licenses would be so hugely worth it to the industry if it saved everyone time in "technical interviews", both interviewees and interviewers alike. How many collective labor hours as an industry are we wasting annually on "technical interviews"? For most classic Civil Engineering firms the "technical" part of the interview is almost entirely "Is your PE license valid and up to date?" "Yes." "Great, you're hired." The software industry would rather waste multiple hours (if not entire days) of wages of everyone involved instead, and it's rather sad when you think about it.
I've yet to find any software-related qualification that wasn't an active negative. I've worked in a place that applied the acknowledged "best practices" of 10 years ago and it was a terrible environment for producing good code.
Thanks for providing the US PE perspective. There are definitely people practicing as PEngs and apprenticing as EITs up in Canada under both the software engineering and computer engineering disciplines. So there is some value up here to those.
Undergrad covers irrelevant material such as humanities, social sciences, and communication that add cost and time to an education. Or at least that's the argument people enrolled in computer science majors where I graduated put forth.
Again, the American perspective is useful. I had no idea you would be bound to one employer during the apprenticeship process. In Canada, employees are free to move around.
Undergrad covers irrelevant material such as humanities, social sciences, and communication that add cost and time to an education. Or at least that's the argument people enrolled in computer science majors where I graduated put forth.
Again, the American perspective is useful. I had no idea you would be bound to one employer during the apprenticeship process. In Canada, employees are free to move around.
> In Canada, employees are free to move around.
I think you can here as well, but the problem is finding an apprentice program in Computer & Electrical engineering is next to impossible. My school had one option for people looking for an apprenticeship. It might be better elsewhere in the country.
I think you can here as well, but the problem is finding an apprentice program in Computer & Electrical engineering is next to impossible. My school had one option for people looking for an apprenticeship. It might be better elsewhere in the country.
> My college spent a lot of money getting an ABET accreditation for their CS/CE programs.
Why? Even here Stanford isn't even ABET and nobody seems to care.
Why? Even here Stanford isn't even ABET and nobody seems to care.
Calling yourself an "engineer" involves licensing fees, continuing education, and the most fun of all - a university degree.
Some jobs require you to be a member, but most of these jobs aren't in software.
So most software people I know just use adjacent titles like "developer" or "designer". It's essentially the same job - just without all the extra responsibility.
The word "engineer" has a certain social clout to it, though. Hard for your mom to brag to her friends if your title is "developer".
Some jobs require you to be a member, but most of these jobs aren't in software.
So most software people I know just use adjacent titles like "developer" or "designer". It's essentially the same job - just without all the extra responsibility.
The word "engineer" has a certain social clout to it, though. Hard for your mom to brag to her friends if your title is "developer".
On the upper end (probably even in the middle) software developers earn more than licensed engineers. I'm pretty sure your mom can brag about her child the developer making 3x what her friend's child the engineer makes.
There are engineers who end up moving to software for just this reason.
Software is super important and becomes more so over time. I'm not sure why being proud of being a developer isn't enough and why it has to end up with wanting to use the term engineer.
There are engineers who end up moving to software for just this reason.
Software is super important and becomes more so over time. I'm not sure why being proud of being a developer isn't enough and why it has to end up with wanting to use the term engineer.
Yeah, titles are a strange thing. There are a lot of PhDs out there earning bupkiss, but they're still "doctor"s, and that carries a certain respect.
I agree it's mostly BS and doesn't make much sense, but I could say the same for much of reality...
I agree it's mostly BS and doesn't make much sense, but I could say the same for much of reality...
Because there's a pretty clear difference between software engineering and simply just writing code and people who do the former pride themselves on that work and want to be recognized for it as an engineer rather that just some programmer.
You would much rather be recognized as the person who devises the plumbing system for a building rather than just being a "plumber".
You would much rather be recognized as the person who devises the plumbing system for a building rather than just being a "plumber".
There is a formal qualification process to be called an engineer. If they truly feel that they should be recognized, then they can go through the process.
Because they aren't going through the process the word and the recognition can't be that valuable.
I feel there is a contradiction in here somewhere that I can't reconcile.
Because they aren't going through the process the word and the recognition can't be that valuable.
I feel there is a contradiction in here somewhere that I can't reconcile.
Yeah, exactly. I got my degrees in electrical and computer engineering but mostly work as a software engineer. I got the PE just in case. The tests and other requirements are not exactly onerous; it's about what you'd expect for a worthwhile professional designation like becoming a CPA, an attorney, or even a CFA.
Not to toot my own horn, but I cruised through the FE and PE exams, but those exams filter out lots of people. Do you really want engineers who are incapable of performing simple calculations? The exams represent a minimum level of competence, and they shouldn't be difficult if you stayed awake in college.
Not to toot my own horn, but I cruised through the FE and PE exams, but those exams filter out lots of people. Do you really want engineers who are incapable of performing simple calculations? The exams represent a minimum level of competence, and they shouldn't be difficult if you stayed awake in college.
Because some people here are hiring people they need to work for less money.
There is value in predictability, even if it stems from someone else's preferences.
Current home wiring requires you put wires in the wall at (I think) between 10 and 20 cm from the border, and a small number of cm inside the wall. This means you only have to check that zone, and can use detectors, to find the wires.
My home is from the 1950's. Some wires go diagonally from top left to bottom right at the other side of the wall. We had great fun finding out where they were hiding.
Even if the new wires waste a lot more wiring and PVC tube, I vastly prefer them when redecorating or drilling holes.
Current home wiring requires you put wires in the wall at (I think) between 10 and 20 cm from the border, and a small number of cm inside the wall. This means you only have to check that zone, and can use detectors, to find the wires.
My home is from the 1950's. Some wires go diagonally from top left to bottom right at the other side of the wall. We had great fun finding out where they were hiding.
Even if the new wires waste a lot more wiring and PVC tube, I vastly prefer them when redecorating or drilling holes.
100% that's true! I'm not saying developers having preferences and everybody abiding by them is a bad thing, more just that a lot of what constitutes "best practices" are often preferences and we should call them that.
Doesn't that kind of imply that everyone's opinions are equally valid? If 95% of your profession is on the same page with a certain practice then I'd argue it's really not reasonable to go against the grain without a very good reason.
I think "best practices" strikes a good balance between things that are personal preferences and things that are laws.
I think "best practices" strikes a good balance between things that are personal preferences and things that are laws.
Yeah it does. Software is basically a mental model and different people have different mental models of the world so we make up languages/practices/etc. that fit those models.
The point of the examples I gave (and a lot of browsing HackerNews) seems to suggest that 95% of the profession is not on board with our most basic practices around unit testing, version control, etc.
The point of the examples I gave (and a lot of browsing HackerNews) seems to suggest that 95% of the profession is not on board with our most basic practices around unit testing, version control, etc.
Maybe we just disagree about what constitutes best practices. I can't speak much about Java land, but I wouldn't describe rebasing in general as a best practice without further context. If you're working on a team that always rebases feature branches then your preference for not rebasing doesn't seem valid to me.
I'm not sure if there's anything 95% of developers are on the same page about.
From what I've seen, every company has a different idea of what _best practices_ are. Generally comes down to what some influential developer likes.
From what I've seen, every company has a different idea of what _best practices_ are. Generally comes down to what some influential developer likes.
From what I've seen, every company has a different idea of what _best practices_ are.
And that's fine. "Best practices" don't necessarily need to be universal in scope. Read the Knowledge Management literature and you'll see plenty of discussion of the idea of scoping "best practices" to in terms of "site best practice", "company best practice", "industry best practice" and so on.
There's also a lot of discussion about using different language other than "best practice" exactly to acknowledge that "best practices" aren't always BEST practices, if you get what I mean. Calling them something like "recommended practices" or "proven practices" or similar lingo gives a way to denote things that are recommended at least locally, without having to claim that they are either universal in scope, or absolutely "best" in any sense.
And that's fine. "Best practices" don't necessarily need to be universal in scope. Read the Knowledge Management literature and you'll see plenty of discussion of the idea of scoping "best practices" to in terms of "site best practice", "company best practice", "industry best practice" and so on.
There's also a lot of discussion about using different language other than "best practice" exactly to acknowledge that "best practices" aren't always BEST practices, if you get what I mean. Calling them something like "recommended practices" or "proven practices" or similar lingo gives a way to denote things that are recommended at least locally, without having to claim that they are either universal in scope, or absolutely "best" in any sense.
I agree, at least in my experience of android development, "Best Practice" often means: what I read on Medium, or what Google said.
It's for people who aren't confident enough to admit to simply having a preference, or knowledgeable enough to be able to explain it
It's for people who aren't confident enough to admit to simply having a preference, or knowledgeable enough to be able to explain it
1950's onwards they used ribbon cables close to surfaces for household wiring. It was best practice, just not today's.
As a freelancer jumping projects, I can't help but see parallels, in that you've really got to study code bases wrt the time of authorship to understand their particular idiosyncrasies.
In the 2010's, people believed in "REST" without considering the context in which these concepts were introduced (eg thin browser UIs, or generalizations thereof as a baseline). Customers, even highly capable devs, flaunt their REST best practices, yet see HATEOAS as optional and pretentious, failing to see the entire point of loose coupling and discovery, and engaging in zealotry about squeezing parameters into URLs instead. Or pretend to, to stop pointless discussions with mediocre, bureaucratic peers.
As a freelancer jumping projects, I can't help but see parallels, in that you've really got to study code bases wrt the time of authorship to understand their particular idiosyncrasies.
In the 2010's, people believed in "REST" without considering the context in which these concepts were introduced (eg thin browser UIs, or generalizations thereof as a baseline). Customers, even highly capable devs, flaunt their REST best practices, yet see HATEOAS as optional and pretentious, failing to see the entire point of loose coupling and discovery, and engaging in zealotry about squeezing parameters into URLs instead. Or pretend to, to stop pointless discussions with mediocre, bureaucratic peers.
In many countries this is coded (mandated by standards), it is not a best practice.
I hate the expression "best practice", it's so, so often used by someone to justify applying cargo cult without actually understanding why.
"Hey why are you having a try-catch there, it seems like it's just gonna break our stack trace and we don't even graciously recover from it" - it's best practice
"Hey why are you using model/view/controller folders?" - it's best practice
"Why are you building microservices?" - best practice.
I got out of a code base with stylecop's settings set to max and treated as errors. Trailing white spaces, mandatory comments on everything, etc. The only exceptions are file size and method size. Files are often in the thousands of lines, and methods can reach that as well. 10 levels of nested if/else. So we're in an unmanageable code base, but at least we don't have trailing white spaces.
Most of the time it could be replaced by "tradition", "pattern", or "the way I've seen others do". If it's a tradition and most people agree to it, fine, might help with readability. If it's pattern, fine, tell me why it's applicable and helpful in our context. If you can't actually explain why you're doing something, maybe rethink it and educate yourself on the topic
"Hey why are you having a try-catch there, it seems like it's just gonna break our stack trace and we don't even graciously recover from it" - it's best practice
"Hey why are you using model/view/controller folders?" - it's best practice
"Why are you building microservices?" - best practice.
I got out of a code base with stylecop's settings set to max and treated as errors. Trailing white spaces, mandatory comments on everything, etc. The only exceptions are file size and method size. Files are often in the thousands of lines, and methods can reach that as well. 10 levels of nested if/else. So we're in an unmanageable code base, but at least we don't have trailing white spaces.
Most of the time it could be replaced by "tradition", "pattern", or "the way I've seen others do". If it's a tradition and most people agree to it, fine, might help with readability. If it's pattern, fine, tell me why it's applicable and helpful in our context. If you can't actually explain why you're doing something, maybe rethink it and educate yourself on the topic
Same with Clean Code, SOLID, DD
SOLID is especially funny because majority of developers doesn't understand / can explain it, let alone have read papers e.g [0],
except maybe S letter, yet everybody acts like they do SOLID*.
Or Clean Code's small function craziness or misinterpretation and going into "avoid comments" approach
* - unless you ask for details
[0] - https://www.cs.cmu.edu/~wing/publications/LiskovWing94.pdf
SOLID is especially funny because majority of developers doesn't understand / can explain it, let alone have read papers e.g [0],
except maybe S letter, yet everybody acts like they do SOLID*.
Or Clean Code's small function craziness or misinterpretation and going into "avoid comments" approach
* - unless you ask for details
[0] - https://www.cs.cmu.edu/~wing/publications/LiskovWing94.pdf
So the only caveat I would put on that: it's useful to have common language for things, my threshold is that you understand why things are this way.
It's useful to tell someone: "you should have that thing in another class because it's clearly another responsibility", and have a debate on the responsibility itself ; or even on the merits of having a single responsibility per class.
What is not useful is when someone will start making monofunction classes that are 10 lines long on the hotel of "smaller functions are better" and sticking to that because "it's a best practice" with no better argument.
Basically my point is: if you understand what you are doing, great, use vocab all you want. But don't use it as a justification.
It's useful to tell someone: "you should have that thing in another class because it's clearly another responsibility", and have a debate on the responsibility itself ; or even on the merits of having a single responsibility per class.
What is not useful is when someone will start making monofunction classes that are 10 lines long on the hotel of "smaller functions are better" and sticking to that because "it's a best practice" with no better argument.
Basically my point is: if you understand what you are doing, great, use vocab all you want. But don't use it as a justification.
Or, common language comes with some assumptions.
Lots of people in software use lots of marketing terms as descriptions of the practice of their work. This is the crux of this conversation, actually: that absent "best practices" rooted in enforced standards, they're all really just marketing terms until proven otherwise.
Lots of people in software use lots of marketing terms as descriptions of the practice of their work. This is the crux of this conversation, actually: that absent "best practices" rooted in enforced standards, they're all really just marketing terms until proven otherwise.
Interesting, I guess SOLID must have been a buzzword from an earlier era, because while I've vaguely heard of it I had to look it up. Don't think it's come up in my 8 years of professional work.
There's always an evolution of these methodologies and I often feel like in practice they're just a way to mix things up and make code health feel more interesting to those involved. Often people know there are problems with the design of their system, but they can't get buy in to fix them. These methodologies provide some authoritative justification for refactoring work.
There's always an evolution of these methodologies and I often feel like in practice they're just a way to mix things up and make code health feel more interesting to those involved. Often people know there are problems with the design of their system, but they can't get buy in to fix them. These methodologies provide some authoritative justification for refactoring work.
> I hate the expression "best practice", it's so, so often used by someone to justify applying cargo cult without actually understanding why.
> Most of the time it could be replaced by "tradition", "pattern", or "the way I've seen others do".
The most common valid / defensible case I've seen it used is when a person fully understands the "why" in depth, and have formed that understanding on the basis of experience (not blind following or "tradition"), but doesn't have time to deliver a long in-depth explanation every time they do a code-review.
That's not to say it isn't still "developer preferences": there are multiple "best-practice" approaches out there and some even contradict eachother. But I strongly believe that even many of the very subjective, hotly-debated approaches are valid and useful in certain contexts.
e.g. I personally lean toward a pseudo-FP style of programming and am growing less and less enamoured with OO patterns for various reasons. But OO is still a useful abstraction, and if you're doing OO, I've found something like SOLID to contain a great deal of wisdom. I never sat down and decided to do things "the SOLID way", and learned that. Rather I wrote a lot of bad OO, ran into problems, gained insight from experience, and later stumbled across SOLID and found the pitfalls it mitigates familiar.
A sibling commenter has the following quote, which I agree with:
> SOLID is especially funny because majority of developers doesn't understand / can explain it, let alone have read papers
I think this is exactly why the term "best-practice" is so popular. I would not have understood SOLID in any depth if I had come to it fresh: I needed to learn SOLID informally by accident, internalise the challenges it's designed to overcome, and then recognise that intuitively from my experience when reading about SOLID later.
That's not a level of understanding you can typically impart easily in a conversation when suggesting someone do something differently. It's much easier to just say "best-practice".
> Most of the time it could be replaced by "tradition", "pattern", or "the way I've seen others do".
The most common valid / defensible case I've seen it used is when a person fully understands the "why" in depth, and have formed that understanding on the basis of experience (not blind following or "tradition"), but doesn't have time to deliver a long in-depth explanation every time they do a code-review.
That's not to say it isn't still "developer preferences": there are multiple "best-practice" approaches out there and some even contradict eachother. But I strongly believe that even many of the very subjective, hotly-debated approaches are valid and useful in certain contexts.
e.g. I personally lean toward a pseudo-FP style of programming and am growing less and less enamoured with OO patterns for various reasons. But OO is still a useful abstraction, and if you're doing OO, I've found something like SOLID to contain a great deal of wisdom. I never sat down and decided to do things "the SOLID way", and learned that. Rather I wrote a lot of bad OO, ran into problems, gained insight from experience, and later stumbled across SOLID and found the pitfalls it mitigates familiar.
A sibling commenter has the following quote, which I agree with:
> SOLID is especially funny because majority of developers doesn't understand / can explain it, let alone have read papers
I think this is exactly why the term "best-practice" is so popular. I would not have understood SOLID in any depth if I had come to it fresh: I needed to learn SOLID informally by accident, internalise the challenges it's designed to overcome, and then recognise that intuitively from my experience when reading about SOLID later.
That's not a level of understanding you can typically impart easily in a conversation when suggesting someone do something differently. It's much easier to just say "best-practice".
> Java is infamous for its verbosity. [...]
This paragraph highlights something I've been saying for ages.
Most criticism of Java needs to be directed towards Java programmers and not the language itself.
The language allows you to simply make a class. You're not required to make an interface and then make a class that implements it, and yet, Java programmers do it anyways and then criticize the language for being verbose.
Getters and Setters? You probably don't need them. Classes can have public member variables.
Java programmers seem to have the hardest time understanding YAGNI.
This paragraph highlights something I've been saying for ages.
Most criticism of Java needs to be directed towards Java programmers and not the language itself.
The language allows you to simply make a class. You're not required to make an interface and then make a class that implements it, and yet, Java programmers do it anyways and then criticize the language for being verbose.
Getters and Setters? You probably don't need them. Classes can have public member variables.
Java programmers seem to have the hardest time understanding YAGNI.
> Getters and Setters? You probably don't need them. Classes can have public member variables.
The getter / setter debate and public fields is about exposing the internal implementation of the object (and thus making it unchangeable without breaking other code) and being able to reason about where the internals are used (if you do need to change them).
For example, if I've got a java.util.Date exposed as a public field and someone uses it, I can't change that later to a java.time.LocalDateTime unless I change all of the things using it. If this is a library that others are using it may mean a cascade of unknown changes.
If, on the other hand, the Date was exposed as a public Date getDate() { return date.clone(); } then I don't have to worry about it. When the internals are changed to LocalDateTime, then Date getDate() { return Date.from(local.atZone(ZoneId.systemDefault()).toInstant()); } and everything will still work.
I don't have an issue with the infrequently used "default package private" level of field visibility where only classes in the same package can see that field as that limits the range of the changes to the classes within single package (in a single project).
The getter / setter debate and public fields is about exposing the internal implementation of the object (and thus making it unchangeable without breaking other code) and being able to reason about where the internals are used (if you do need to change them).
For example, if I've got a java.util.Date exposed as a public field and someone uses it, I can't change that later to a java.time.LocalDateTime unless I change all of the things using it. If this is a library that others are using it may mean a cascade of unknown changes.
If, on the other hand, the Date was exposed as a public Date getDate() { return date.clone(); } then I don't have to worry about it. When the internals are changed to LocalDateTime, then Date getDate() { return Date.from(local.atZone(ZoneId.systemDefault()).toInstant()); } and everything will still work.
I don't have an issue with the infrequently used "default package private" level of field visibility where only classes in the same package can see that field as that limits the range of the changes to the classes within single package (in a single project).
Getters and Setters also permit you to specify that something can only be retrieved or assigned, but not the other. This is non-trivial in most programming languages so having this as a common pattern is useful. Though I like C#'s properties versus seeing a bunch of getFoo and setFoo methods running around, if Java had provided the same or a similar capability there would probably be no controversy. It's the noisiness of the Java solution that seems to irk people more than the concept.
Java now has records which handles the creation of getters (and since its an immutable, it doesn't have any setters).
https://blogs.oracle.com/javamagazine/post/records-come-to-j... and https://dzone.com/articles/what-are-java-records
I'm really looking forward to using the local records defined mid stream for bundling the information to the next part.
https://blogs.oracle.com/javamagazine/post/records-come-to-j... and https://dzone.com/articles/what-are-java-records
I'm really looking forward to using the local records defined mid stream for bundling the information to the next part.
> Getters and Setters also permit you to specify that something can only be retrieved or assigned, but not the other.
Only retrieved? `final` and set the fields through the constructor.
Sure someone could implement setters-only if they wanted that. Except I’ve never seen it and get/set are always used instead. Just one layer of indirection for no benefit.
Only retrieved? `final` and set the fields through the constructor.
Sure someone could implement setters-only if they wanted that. Except I’ve never seen it and get/set are always used instead. Just one layer of indirection for no benefit.
That's not equivalent. You may want a field to be updated by other actions. That is, its value is derived from the other properties of the system. You could recompute those on each request, but that's potentially costly. You could also recreate the entire object with each small field change. That's also very costly.
Consider a collection class which has a size field. `final` would be the wrong thing to use. If you expose the size field but make it final, well, it's immutable and your entire collection is either lying or also immutable. If you expose the size field but it's not final, then anything can alter it. Consequently, a getter (the concept of one at least, see C# again for a cleaner approach than what Java did historically) is useful and then when another element of the interface is used (adding or removing elements) the size field can be updated appropriately. The next time it's retrieved, it's correct and you don't need to recompute it.
This kind of thing can be a consequence of many other systems, a collection is just sufficiently universally understood that it's a good example of the concept.
Consider a collection class which has a size field. `final` would be the wrong thing to use. If you expose the size field but make it final, well, it's immutable and your entire collection is either lying or also immutable. If you expose the size field but it's not final, then anything can alter it. Consequently, a getter (the concept of one at least, see C# again for a cleaner approach than what Java did historically) is useful and then when another element of the interface is used (adding or removing elements) the size field can be updated appropriately. The next time it's retrieved, it's correct and you don't need to recompute it.
This kind of thing can be a consequence of many other systems, a collection is just sufficiently universally understood that it's a good example of the concept.
A collection is a red herring. A collection uses a “getter” for the size since the size is not something you get/set like in a value object.
But then again no one calls it a “getter” (not even Java calls it `getSize()`) since the get/set discussion is about updatable fields, not the inner guts of objects.
Has anyone argued against encapsulation? No one has.
But then again no one calls it a “getter” (not even Java calls it `getSize()`) since the get/set discussion is about updatable fields, not the inner guts of objects.
Has anyone argued against encapsulation? No one has.
C# properties are good until you need them to be delegates, and then they are annoying.
Apparently your field was used both for some internal shenanigans as well as a public field through the get/set indirection. Then you changed the field but kept the old public behavior. I wonder whether (1) that dual purpose internal/public role was wise to be begin with, and (2) whether that change of the internal logic of the getter might have just papered over a more significant change.
It might be good if a change just breaks client code. The client expects just to get/set something: they might not expect that some update migth add arbitrary logging or internal logic (like setting this value will also set another value, but we won’t tell you).
Most of the get/set stuff that I see are for value objects with either no or little business logic. Simple value objects _should_ just expose their implementation.
It might be good if a change just breaks client code. The client expects just to get/set something: they might not expect that some update migth add arbitrary logging or internal logic (like setting this value will also set another value, but we won’t tell you).
Most of the get/set stuff that I see are for value objects with either no or little business logic. Simple value objects _should_ just expose their implementation.
The backing implementation of what supplies the DTO shouldn't be an issue for the client / other part of the application if the contract that the DTO provides remains the same.
If that contract is the underlying field implementation, then that means that those fields are frozen and cannot change.
If that contract is instead methods, the underlying field types can change (for example from a Date to a LocalDateTime) while the method contracts remain the same and new method contracts are added to expose more functionality for other clients / application modules.
In particular, this was code written in the Java 1.7 days and it was Date (and all the mess with java.util.Date and java.sql.Date) while in 1.8 java.time was provided which allowed the underlying implementation of the object to cleaned up without changing the contract of the methods (things wanting a Date still get a Date).
Yes, changing from a Date to a Calendar (because of the aforementioned java.sql.Date mess) to a LocalDateTime were significant changes -- but the clients didn't notice because the methods they were using remained consistent.
The deeper you expose the client contract into the guts of the object, the more difficult it is to change when a change is needed.
Now, if you're just passing DTOs around between classes within a single package or local to one library that don't leak - feel free to do whatever is needed. I suspect that records will solve a lot of the boilerplate DTO code, though passing a record outside of a library boundary gives me a bit of unease because it means that changes to the record will be breaking changes to the clients.
If that contract is the underlying field implementation, then that means that those fields are frozen and cannot change.
If that contract is instead methods, the underlying field types can change (for example from a Date to a LocalDateTime) while the method contracts remain the same and new method contracts are added to expose more functionality for other clients / application modules.
In particular, this was code written in the Java 1.7 days and it was Date (and all the mess with java.util.Date and java.sql.Date) while in 1.8 java.time was provided which allowed the underlying implementation of the object to cleaned up without changing the contract of the methods (things wanting a Date still get a Date).
Yes, changing from a Date to a Calendar (because of the aforementioned java.sql.Date mess) to a LocalDateTime were significant changes -- but the clients didn't notice because the methods they were using remained consistent.
The deeper you expose the client contract into the guts of the object, the more difficult it is to change when a change is needed.
Now, if you're just passing DTOs around between classes within a single package or local to one library that don't leak - feel free to do whatever is needed. I suspect that records will solve a lot of the boilerplate DTO code, though passing a record outside of a library boundary gives me a bit of unease because it means that changes to the record will be breaking changes to the clients.
Thank you. I have programmed Java for years, but it's been frustrating. The clean language I learnt at university, that I love to bits, seems to be used approximately nowhere.
Instead, it's always some monstrosity held together by inheritance, XML/(awful) Gradle and liberal sprinklings of magical annotations that always (always!) bite you in the backside at runtime rather than at compile time, because why would you prefer to have good tooling that takes advantage of static typing to tell you what might go wrong.
I am appalled by what Spring mentality did to my language.
Instead, it's always some monstrosity held together by inheritance, XML/(awful) Gradle and liberal sprinklings of magical annotations that always (always!) bite you in the backside at runtime rather than at compile time, because why would you prefer to have good tooling that takes advantage of static typing to tell you what might go wrong.
I am appalled by what Spring mentality did to my language.
> The language allows you to simply make a class. You're not required to make an interface and then make a class that implements it, and yet, Java programmers do it anyways and then criticize the language for being verbose.
That's the 'D' in SOLID -- dependency inversion. An object's dependencies should be defined in terms of abstract interfaces, not concrete classes. The verbosity is just boilerplate, and it would appear in any statically typed language if you're following SOLID principles.
> Getters and Setters? You probably don't need them. Classes can have public member variables.
Getters and setters are part of the JavaBeans spec for being able to load and configure arbitrary beans. If you're writing JavaBeans, as many EJB or Spring application developers are, you'll use getters and setters.
That's the 'D' in SOLID -- dependency inversion. An object's dependencies should be defined in terms of abstract interfaces, not concrete classes. The verbosity is just boilerplate, and it would appear in any statically typed language if you're following SOLID principles.
> Getters and Setters? You probably don't need them. Classes can have public member variables.
Getters and setters are part of the JavaBeans spec for being able to load and configure arbitrary beans. If you're writing JavaBeans, as many EJB or Spring application developers are, you'll use getters and setters.
> That's the 'D' in SOLID -- dependency inversion. An object's dependencies should be defined in terms of abstract interfaces, not concrete classes
DI does not talk about the interface keyword in Java. It talks about interface as the public surface of an object or system.
Programming to a Java interface declaration does not guarantee the code is depending on higher-level abstractions - this depends on how the interface is defined. An interface which just replicate the public surface of a class (a "header interface") is on the exact same abstraction level as the class, it just introduce needless boilerplate.
DI does not talk about the interface keyword in Java. It talks about interface as the public surface of an object or system.
Programming to a Java interface declaration does not guarantee the code is depending on higher-level abstractions - this depends on how the interface is defined. An interface which just replicate the public surface of a class (a "header interface") is on the exact same abstraction level as the class, it just introduce needless boilerplate.
I.e. (together with the S and I) this implies that the interface should be defined by its immediate consumer and should consist of all and only the methods required to implement the functionality in the most straightforward way (i.e. the consumer shouldn't have to deal with the idiosyncrasies of the provider).
On most languages this requires a lot of boilerplate and indirections though.
On most languages this requires a lot of boilerplate and indirections though.
Java was for very long missing anonymous functions, so for anything involving callbacks you had to make gazillion of Listener- or Factory-classes instead, which further forced you to create an interface for each of them. Leading to all these infamously verbose design-patterns.
It was also for a very long time missing some fundamental Stream, List and String processing features. Just getting the contents of a file or converting a string to bytes, or even just initializing an Array often required 2-3 lines of verbose OutputStream(StreamBuilder().fromArray(Arrays.asList(1,2))).readBytes().add(3), wrapped in a try-catch for all the checked exceptions. For things that in C# would just be a oneliner of new List<int>({1,2,3}) or in Python [1,2,3].
This is mostly solved in current versions of the language, but the reputation and the "best practice" design-patterns remains.
It was also for a very long time missing some fundamental Stream, List and String processing features. Just getting the contents of a file or converting a string to bytes, or even just initializing an Array often required 2-3 lines of verbose OutputStream(StreamBuilder().fromArray(Arrays.asList(1,2))).readBytes().add(3), wrapped in a try-catch for all the checked exceptions. For things that in C# would just be a oneliner of new List<int>({1,2,3}) or in Python [1,2,3].
This is mostly solved in current versions of the language, but the reputation and the "best practice" design-patterns remains.
> Getters and Setters? You probably don't need them. Classes can have public member variables.
We do need them if the objects interact with a lot the libraries that we use. Libraries that we didn’t make. They expect get/set.
I agree that getters/setters are very overrated. I tend to make public-final fields when I can. Most of the time I can’t though.
We do need them if the objects interact with a lot the libraries that we use. Libraries that we didn’t make. They expect get/set.
I agree that getters/setters are very overrated. I tend to make public-final fields when I can. Most of the time I can’t though.
Very true but Java devs tend to have limited perspective and flexibility. If you get rid of the cruft it’s a fine language.
[deleted]
Amusingly, j2ee did require you to make an interface and an implementation. I seem to recall you had to also have a "stub" class.
Which is to say, early ecosystems in Java certainly needed this criticism. They did adjust, though.
Which is to say, early ecosystems in Java certainly needed this criticism. They did adjust, though.
Yeah, I'm actually a pretty big fan of Java programming. It gets a lot of hate on HN for things that have been mostly solved or can be solved if you implement it a certain way.
Steven Sinofsky gave a talk and said something to the effect of, we've been building roads, bridges and edifices for thousands of years. So, best practices and solved problems abound---and even then we still get it wrong sometimes. Whereas, software engineering is maybe 70 years old (generously)? So, there is much to learn and a lot of "baseline" knowledge that has yet to be established. I think it's a good way to think about things.
Eh, I mean we've been building computer chips for approximately the same amount of time as computer software, and it's pretty clear chip engineering is more like civil engineering than software engineering. I would guess many of the best practices in bridge building in the modern day were developed in the last 70 years.
I think it's that engineers of physical things have many more hard constraints they have to wrestle with, and software engineers largely don't. Your code doesn't need to obey the rules of gravity and chemistry and materials science, it just needs to somehow accomplish the task.
And you see those best practices in the places of software engineering where there are hard constraints: cryptography. high performance code. realtime systems.
It's not just a senior engineer's opinion whether you should use ruby or C if you're writing the firmware for your race car. If you use md5 to hash user passwords on a major site, you'll be hung from the rafters.
I think it's that engineers of physical things have many more hard constraints they have to wrestle with, and software engineers largely don't. Your code doesn't need to obey the rules of gravity and chemistry and materials science, it just needs to somehow accomplish the task.
And you see those best practices in the places of software engineering where there are hard constraints: cryptography. high performance code. realtime systems.
It's not just a senior engineer's opinion whether you should use ruby or C if you're writing the firmware for your race car. If you use md5 to hash user passwords on a major site, you'll be hung from the rafters.
> Eh, I mean we've been building computer chips for approximately the same amount of time as computer software, and it's pretty clear chip engineering is more like civil engineering than software engineering.
Is it actually anything like civil engineering? To my knowledge chip engineering revolves around yield. There's no such analogous concept in designing buildings that can only be reasonably constructed correctly 70% of the time and attempting to reuse the bad buildings for other projects.
Is it actually anything like civil engineering? To my knowledge chip engineering revolves around yield. There's no such analogous concept in designing buildings that can only be reasonably constructed correctly 70% of the time and attempting to reuse the bad buildings for other projects.
Sure, and civil engineering is really different from chemical engineering. But those are minor compared with the differences between physical engineering disciplines and software engineering.
Software engineers:
- cost of components is $0 (use one class or split into 2, there is no cost metric to decide)
- physics don't apply to components (we can't use this doping agent because X or Y. We need to move the factory to an area of low seismic activity to improve yields etc.. etc..)
Basically, physical engineers have so many constraints, solving the problem is the hard part. Software engineers have so few constraints, usually solving the problem is the easy part, and we have time left over to argue about abstract cleanliness concepts like composition vs. inheritance and such.
(Again, this is the rule, the exception is problems like "We need this service to do 2 million requests per second", and there we don't argue about functional vs. OOP, you do anything you can to hit the number)
Software engineers:
- cost of components is $0 (use one class or split into 2, there is no cost metric to decide)
- physics don't apply to components (we can't use this doping agent because X or Y. We need to move the factory to an area of low seismic activity to improve yields etc.. etc..)
Basically, physical engineers have so many constraints, solving the problem is the hard part. Software engineers have so few constraints, usually solving the problem is the easy part, and we have time left over to argue about abstract cleanliness concepts like composition vs. inheritance and such.
(Again, this is the rule, the exception is problems like "We need this service to do 2 million requests per second", and there we don't argue about functional vs. OOP, you do anything you can to hit the number)
Well I think this is just a case of easy Software Engineering
vs hard Software Engineering where the requirements are hard to satisfy.
Most of the industry does easy Engineering and that's what we talk about for the most part. The part of the industry that does hard engineering (the largest orgs, developers of mission critical systems like weapons) keep mostly quiet about how they solve their problems because that's a trade secret or highly classified.
Most of the industry does easy Engineering and that's what we talk about for the most part. The part of the industry that does hard engineering (the largest orgs, developers of mission critical systems like weapons) keep mostly quiet about how they solve their problems because that's a trade secret or highly classified.
Buildings are constructed correctly closer to 10% of the time, I assume. The ones built incorrectly still get used, just with lower lifespans and are more likely to run into issues.
Civil (and other engineering) got better because there was motivation to improve that came from multiple directions: literal lives at stake, the pride of good craftsmanship, iterative or even grand steps forward in knowledge, etc.
Software engineering as a discipline is dominated by appeals to authority ("Clean Code", "Google does it this way", "Djikstra said so", etc.) without any (or at least not much) attempt to ask why or whether. I think we'll automate away much of software engineering (likely with very poor, inefficient, and buggy implementations) before it matures enough as an industry to be actual engineering. Engineering (and the science behind it for that matter) advances from curiosity and a healthy skepticism, not the rampant ego-driven self-promotion that runs through SE.
Software engineering as a discipline is dominated by appeals to authority ("Clean Code", "Google does it this way", "Djikstra said so", etc.) without any (or at least not much) attempt to ask why or whether. I think we'll automate away much of software engineering (likely with very poor, inefficient, and buggy implementations) before it matures enough as an industry to be actual engineering. Engineering (and the science behind it for that matter) advances from curiosity and a healthy skepticism, not the rampant ego-driven self-promotion that runs through SE.
This is a symptom of the lack of knowledge not a cause. Imagine you want to built a building but no one really knows how, then copying successfully completed buildings, and established construction engineers and companies is a pretty good idea. That's what's going on in SE.
The difference is the feedback is pretty incontrovertible if you build a building and it falls down. If you use composition instead of inheritance, the evidence of whether you're right or wrong comes in the form of ... slightly faster refactoring two years later? Maybe?
All of the stuff engineers argue about and that seem really subjective are the things where you just get very little feedback about who is right or wrong.
All of the stuff engineers argue about and that seem really subjective are the things where you just get very little feedback about who is right or wrong.
It's both, as it's a feedback cycle. This industry, like many others, rewards narcissism and loudmouths above all else. It does so in the large (e.g. Fowler or Uncle Bob worship; "ex-FAANG" cache) and in the small (the self-promoting engineer who touts his work even if it's not all that great gets promoted over the "soft-power" engineer managing tough projects lowkey). In this environment the symptom feeds the cause, because nobody stops to question whether the symptom is even a symptom. The root cause, ignorance, is entrenched and made deeper, which feeds the symptom. And so on.
I just want the fuck out, there no realistic alternative.
What about we apply this to software engineering?
> If a builder constructs a house for a man but does not make it conform to specifications so that a wall then buckles, that builder shall make that wall sound using his own silver.
- Code of Hammurabi, 1755–1750 BC
> If a builder constructs a house for a man but does not make it conform to specifications so that a wall then buckles, that builder shall make that wall sound using his own silver.
- Code of Hammurabi, 1755–1750 BC
The software is as sturdy as the day it was written, there has been no deterioration - if your copy has become broken, the builder can easily supply another copy using his own silver.
On the other hand, if the customer finds out that their door is inconvenient and it would be much better to have it a bit to the right, noone expects a house builder to fix that at their expense, you bought what you saw. And the same thing if it turns out that the house is very difficult to maintain because it's inconvenient to get to the piping. And ifthe customer buys a bigger car and the garage needs to be adapted to fit it, that's their expense.
Those three would be the main equivalents of all the commonly seen software "best practices" which generally either refer to feature design, the maintainability of the code, and ensuring compatibility when an integrated system changes.
On the other hand, if the customer finds out that their door is inconvenient and it would be much better to have it a bit to the right, noone expects a house builder to fix that at their expense, you bought what you saw. And the same thing if it turns out that the house is very difficult to maintain because it's inconvenient to get to the piping. And ifthe customer buys a bigger car and the garage needs to be adapted to fit it, that's their expense.
Those three would be the main equivalents of all the commonly seen software "best practices" which generally either refer to feature design, the maintainability of the code, and ensuring compatibility when an integrated system changes.
Unfortunately only consulting and high integrity computing are the main areas where software companies get liability for delivering faulty products.
One day that will extend to everyone like in all industries.
Who can't manage then closes doors, just like bad restaurants after a surprise health check.
One day that will extend to everyone like in all industries.
Who can't manage then closes doors, just like bad restaurants after a surprise health check.
Define "specifications" and "conform" in terms that I might hear from a non technical client.
The engineer is responsible for taking non-technical language from the client and turning it into technical engineering specifications. Why does this fall to the client in software?
That is what contracts are for.
I feel like I already spend 90% of my day gluing together various disparate APIs. Is this the logical conclusion to software development?
I adore the craft-like parts of software dev, wouldn't trade it for anything.
I adore the craft-like parts of software dev, wouldn't trade it for anything.
Furthermore, there are far fewer physical constraints in software, so the range of possible designs is dramatically wider.
(Actually I dare say that sotware itself has no physical constraints at all: software artifacts and software executions do.)
(Actually I dare say that sotware itself has no physical constraints at all: software artifacts and software executions do.)
Which is why I don't buy the "software has only been around for 70 years so give it time" argument. Software has nothing to be grounded in like other engineers do with physics. It's most likely always going to be endless cargo culting.
That's simply not true. Software is grounded in mathematics. Most people just try to ignore that fact for convenience.
There are, for instance, famous books written about which errors can be proven to be absent in your program and how (vulgo typechecking). There is a huge amount of research about data structures and their internal logic (and at least one, very weird observation about the meaning of the derivatives of data structures). And I don't need to mention complexity theory, do I?
Just because a huge part of the practitioners ignores the scientific base of our discipline doesn't mean it doesn't exist.
There are, for instance, famous books written about which errors can be proven to be absent in your program and how (vulgo typechecking). There is a huge amount of research about data structures and their internal logic (and at least one, very weird observation about the meaning of the derivatives of data structures). And I don't need to mention complexity theory, do I?
Just because a huge part of the practitioners ignores the scientific base of our discipline doesn't mean it doesn't exist.
As an oficially qualified computer scientist, I can say that software is grounded in mathematics, but this does not imply what you're thinking. *All* formalisms, including mathematics, are in the end nothing but an incredibly precise language to talk about ideas in your head. Programming languages are created for communication, so this is specially true for them.
The fact that code has an extremely precise semantics comes from it being a formal system. But its close relation with maths and physics, besides that they are all formal systems, is mainly because mathematicians and physicists were the first to create it; it's mostly a matter of tradition. There are ways to create, use and study software that are closer to language studies than they are to math, and those are legitimate comp-sci too. Non-formal aspects of building software, like which style guide to establish in your organization, are part of the discipline even if you don't use math to study them.
Formal proof is a convenient way to check that your detailed, precise assertions are consistent with your initial axioms. This doesn't prove at all that there are no errors in your code, only that there are no contradictions in what you are saying. Your specification could still be wrong, and then you could still be saying the wrong thing in terms of what you intend to say or achieve; and the formalism won't help.
It is not surprising that managers gets to decide how software is built in their department. Software is an explanation of concepts with a particular style, and those who set the tone implant their quirks in it. You're building what the manager tells you to build, and end using the same language.
The fact that code has an extremely precise semantics comes from it being a formal system. But its close relation with maths and physics, besides that they are all formal systems, is mainly because mathematicians and physicists were the first to create it; it's mostly a matter of tradition. There are ways to create, use and study software that are closer to language studies than they are to math, and those are legitimate comp-sci too. Non-formal aspects of building software, like which style guide to establish in your organization, are part of the discipline even if you don't use math to study them.
Formal proof is a convenient way to check that your detailed, precise assertions are consistent with your initial axioms. This doesn't prove at all that there are no errors in your code, only that there are no contradictions in what you are saying. Your specification could still be wrong, and then you could still be saying the wrong thing in terms of what you intend to say or achieve; and the formalism won't help.
It is not surprising that managers gets to decide how software is built in their department. Software is an explanation of concepts with a particular style, and those who set the tone implant their quirks in it. You're building what the manager tells you to build, and end using the same language.
> Formal proof is a convenient way to check that your detailed, precise assertions are consistent with your initial axioms. This doesn't prove at all hat there are no errors in your code, only that there are no contradictions in what you are saying. Your specification could still be wrong, and then you could still be saying the wrong thing in terms of what you intend to say or achieve; and the formalism won't help.
Software assurance is still a somewhat nebulous process and I'm partly involved in some research around it and proving that a program is logically sound is indeed only a small piece of the pie and hardly gets you anywhere valuable.
FizzBuzz is provably logical, but that doesn't mean you can load FizzBuzz onto a space shuttle and expect it to fly correctly.
Software assurance is still a somewhat nebulous process and I'm partly involved in some research around it and proving that a program is logically sound is indeed only a small piece of the pie and hardly gets you anywhere valuable.
FizzBuzz is provably logical, but that doesn't mean you can load FizzBuzz onto a space shuttle and expect it to fly correctly.
Great example!
How does research in software assurance treats the human side of behaviors and desires, which can't be formalized? Are there protocols that can increase reliability for an established purpose?
How does research in software assurance treats the human side of behaviors and desires, which can't be formalized? Are there protocols that can increase reliability for an established purpose?
Many times there are authorities that have formalized protocols for systems involving people. For example, the FAA has prescribed thresholds where pilots should be alerted of possible failures when navigation system measurements have exceeded those thresholds. Other times thresholds like those can be found just through user testing and feedback. The goal there is to ensure safety without losing the confidence of the user or overwhelming them with information.
There are a number of general Software Assurance protocols. I'm not super familiar with them, but DO-178C is one I hear about often which is a process specifically for assuring/certifying airborne systems.
There are a number of general Software Assurance protocols. I'm not super familiar with them, but DO-178C is one I hear about often which is a process specifically for assuring/certifying airborne systems.
It's more like mathematics. While it's true that everyone can invent their own maths, this is only really done in advanced academia for research. Almost everything in practical use is standarized. No-one is arguing about whether you need integration or what the right notation for differential equations is.
This took time to achieve. You wouldn't be able to read Newton's papers easily, even though a large amount of high school mathematics is based on things he invented/discovered.
This took time to achieve. You wouldn't be able to read Newton's papers easily, even though a large amount of high school mathematics is based on things he invented/discovered.
Also, there isn't that much in the way of scientific grounding.
Mechanical engineering has physics as a foundation.
Chemical engineering has chemistry as a foundation.
What is the scientific foundation of software engineering?
I suspect it is a mix of cognitive science, linguistics, and anthropology.
Mechanical engineering has physics as a foundation.
Chemical engineering has chemistry as a foundation.
What is the scientific foundation of software engineering?
I suspect it is a mix of cognitive science, linguistics, and anthropology.
> I suspect it is a mix of cognitive science, linguistics, and anthropology.
Computer Science (more abstract) and Computing Science (less abstract) are branches of Science that have given a foundation to Software Engineering.
The problem is that most of the programming and software development that happens nowadays (and what people pay for) doesn't use it.
I compare it as Chemistry and Alchemy. We are still in the "alchemy" stage of software development. Sure, people who see themselves as "experts" are combining existing stuff to create new things. But there is a few set of experts that use the science expertise to implement systems.
Computer Science (more abstract) and Computing Science (less abstract) are branches of Science that have given a foundation to Software Engineering.
The problem is that most of the programming and software development that happens nowadays (and what people pay for) doesn't use it.
I compare it as Chemistry and Alchemy. We are still in the "alchemy" stage of software development. Sure, people who see themselves as "experts" are combining existing stuff to create new things. But there is a few set of experts that use the science expertise to implement systems.
I'm a computer science and computer engineering major, and I've never once heard the term "computing science". Is there a context in which this term is regularly used?
Math. Which seems that many practitioners are proud of not knowing
Math provides no answer for a lot of the problems one encounter in day to day software development. It does not help you decide how much test coverage you need,it does not help you decide how to review, it does not help you figure out what features are desired, it does not help you collaborate with the juniors etc etc.
I agree that math describes limitation to computer science and formalisation. But software engineering is more than computation.
I agree that math describes limitation to computer science and formalisation. But software engineering is more than computation.
Logic maybe but a very large amount of software written does not use much if any math beyond the very basics.
Lots of people in other engineering disciplines don't use math beyond the very basics either. A large amount of parts are designed in CAE software which handles most/all of the mathematics. And in some larger companies, the person designing the part and the person testing the part are on different teams.
An old HN post - https://news.ycombinator.com/item?id=20912718 and its corresponding material - https://cse.buffalo.edu/~rapaport/Papers/phics.pdf looks to address some of that.
Section 3 gets into the "what is computer science". 3.10 through 3.13 get into the engineering aspect. Section 6.5 puts it into historical context.
Section 3 gets into the "what is computer science". 3.10 through 3.13 get into the engineering aspect. Section 6.5 puts it into historical context.
> I suspect it is a mix of cognitive science, linguistics, and anthropology.
I agree. Creating a solution that is clear to navigate for future developers is valuable, as is one that is flexible for future modifications. These things depend much more on how humans understand the code than on how machines understand it.
That said, other engineering disciplines aren't entirely bereft of that kind of human aspect either. Take architecture for example. It's critical for a building to handle the forces put on it. But it's also important that humans can use it. Having a good building layout is much more a matter of understanding humans than of understanding physics.
And then there's the whole style thing that architecture has. A building is not always only functional. It can very much be a work of art. And that style is not just decorative. A style can conjure up certain emotions to put people in a certain mindset when dealing with the building. (E.g. putting a modern art museum in a neo-classical building would be dissonant.)
I agree. Creating a solution that is clear to navigate for future developers is valuable, as is one that is flexible for future modifications. These things depend much more on how humans understand the code than on how machines understand it.
That said, other engineering disciplines aren't entirely bereft of that kind of human aspect either. Take architecture for example. It's critical for a building to handle the forces put on it. But it's also important that humans can use it. Having a good building layout is much more a matter of understanding humans than of understanding physics.
And then there's the whole style thing that architecture has. A building is not always only functional. It can very much be a work of art. And that style is not just decorative. A style can conjure up certain emotions to put people in a certain mindset when dealing with the building. (E.g. putting a modern art museum in a neo-classical building would be dissonant.)
> cognitive science, linguistics, and anthropology.
Would love to hear your thoughts on this, esp. the linguistics and anthropology piece.
Would love to hear your thoughts on this, esp. the linguistics and anthropology piece.
How about math? Complexity theory, all kinds of logic, computational theory, category theory?
Honest question. How does that help?
Category theory: I suspect that category theory (well, really just abstract algebra) will tend to make software engineers better at writing code. However, on the other hand, the category theory operator soup that sometimes shows up in haskell, et al makes me think that too much and not enough restraint isn't a good thing.
Computational theory: After 14 years of software engineering, I only needed to care about this once. It looks like the answer is try not to make loops inside of loops, use the standard library, know the bare minimum, and if all else fails then find a way to cheat with hardware (graphics cards, simd, massive distributed systems, asci, etc).
Logic: So ... like type checking? Or prolog? I mean, knowing logic is good. But, like, where exactly do you expect the benefits to show up.
Complexity theory: Are you talking computational complexity? If so then I guess my answer for computational theory (also what did you mean by computational theory then? like lambda calculus and turing machines? When does that help?).
Category theory: I suspect that category theory (well, really just abstract algebra) will tend to make software engineers better at writing code. However, on the other hand, the category theory operator soup that sometimes shows up in haskell, et al makes me think that too much and not enough restraint isn't a good thing.
Computational theory: After 14 years of software engineering, I only needed to care about this once. It looks like the answer is try not to make loops inside of loops, use the standard library, know the bare minimum, and if all else fails then find a way to cheat with hardware (graphics cards, simd, massive distributed systems, asci, etc).
Logic: So ... like type checking? Or prolog? I mean, knowing logic is good. But, like, where exactly do you expect the benefits to show up.
Complexity theory: Are you talking computational complexity? If so then I guess my answer for computational theory (also what did you mean by computational theory then? like lambda calculus and turing machines? When does that help?).
Well, if you make broad generalizations like that, then software engineering has mathematics as a foundation.
Perhaps you don't want to make broad generalizations?
Perhaps you don't want to make broad generalizations?
Computer Science?
Edit: this is a discussion forum. The downvote button is not an agree/disagree button, it's to penalize irrelevant comments. If you'd like to disagree, please reply and state your thinking instead.
Edit: this is a discussion forum. The downvote button is not an agree/disagree button, it's to penalize irrelevant comments. If you'd like to disagree, please reply and state your thinking instead.
Programming changes practice quickly and often because it's cheap to do so compared to physical engineering which is slowed down by execution time, high materials cost, and sunk costs.
The interesting question is this: would other engineering pursuits (say civil) have just as much chaos and lack of authoritative practices, if changing practices would be equally fast and cheap for them?
The interesting question is this: would other engineering pursuits (say civil) have just as much chaos and lack of authoritative practices, if changing practices would be equally fast and cheap for them?
Best practices in civil engineering are connected to outcomes. You know that something is a good practice if not doing it causes things to collapse or catch on fire.
"Best practices" in software engineering are usually about internal development processes and don't have any verifiable connection to outcomes.
In other words, we have two entirely different things labeled with the same name. People who commonly use the phrase "best practices" for software are literally trying to confuse you and generally are not worth listening to.
That said, some things in software are worth analyzing to have a better process, but those things need to be examined within a specific context. If someone claims that you need to, say, create an interface for every class, they should be able to explain why and how it is relevant to your work. If people make claims they cannot explain by connecting them to meaningful outcomes, those people are, again, not worth listening to. They might be mindlessly parroting something they have heard without having any clue as to the meaning of the practice. Unfortunately, our field is full of "professionals" that do exactly that.
Software is a pretty messed up domain that is frequently a self-licking ice-cream cone. (You write code to solve problems created by other code.) Because of that, it's often socially mediated, just like non-engineering fields. To establish anything for real in this self-referential environment you need to be able to have conversations about costs, tradeoffs and outcomes - within a specific context.
"Best practices" in software engineering are usually about internal development processes and don't have any verifiable connection to outcomes.
In other words, we have two entirely different things labeled with the same name. People who commonly use the phrase "best practices" for software are literally trying to confuse you and generally are not worth listening to.
That said, some things in software are worth analyzing to have a better process, but those things need to be examined within a specific context. If someone claims that you need to, say, create an interface for every class, they should be able to explain why and how it is relevant to your work. If people make claims they cannot explain by connecting them to meaningful outcomes, those people are, again, not worth listening to. They might be mindlessly parroting something they have heard without having any clue as to the meaning of the practice. Unfortunately, our field is full of "professionals" that do exactly that.
Software is a pretty messed up domain that is frequently a self-licking ice-cream cone. (You write code to solve problems created by other code.) Because of that, it's often socially mediated, just like non-engineering fields. To establish anything for real in this self-referential environment you need to be able to have conversations about costs, tradeoffs and outcomes - within a specific context.
Right, but have you ever worked in a place where no practices at all are being followed?
Where there are hacks after hacks, giant classes with giant methods, no interfaces, static methods, bad names everywhere, you need to find a bug? good look, you want to write a test to avoid regression? Ok that would take you 5 times more time.
I agree, following a “best practice” without understanding the “bad practice” that it’s trying to prevent is silly. But just discarding best practices because no one understands the reasons behind is also silly.
I agree, following a “best practice” without understanding the “bad practice” that it’s trying to prevent is silly. But just discarding best practices because no one understands the reasons behind is also silly.
> I agree, following a “best practice” without understanding the “bad practice” that it’s trying to prevent is silly. But just discarding best practices because no one understands the reasons behind is also silly.
I would argue that there is also a lot of value in following team-level best practices even if you do not fully grasp the rationale or understanding "bad practices". For starters, it ensures that the team's work complies with the principle of least surprise and follows a common and standard style, which helps with onboarding and forming a mental model of where and how all things are.
I would argue that there is also a lot of value in following team-level best practices even if you do not fully grasp the rationale or understanding "bad practices". For starters, it ensures that the team's work complies with the principle of least surprise and follows a common and standard style, which helps with onboarding and forming a mental model of where and how all things are.
> But just discarding best practices because no one understands the reasons behind is also silly.
So what do you do with a "best practice" that doesn't make any sense to you? Do you just keep doing it forever because you can't understand why anybody would invent it in the first place? To take an example I'm familiar with, there's a good chance if you don't understand a Java OOP best practice it's because you've never encountered the problems it was designed to cope with. The OOP design principles that came out of the 1990s and became orthodox in Java around the turn of the century were built to solve the problem of scaling monolithic application development to teams of dozens or hundreds of developers. You would have dozens of people, imperfectly coordinated, hacking on a monolithic codebase for an application that was released quarterly (if that!) and ran on servers that cost more than the CEO's car. The coding style innovations of that era naturally focused on coming up with more and more ways to add layers of protective abstraction, and on training programmers to add those layers to their code no matter what, even if it doesn't seem worth it because 99% of the time, if somebody didn't understand that it was worth it, it was because they were inexperienced and hadn't lived through a horrific integration debacle that delayed the quarterly release by a month.
In my opinion, if your problems don't resemble those turn-of-the-century enterprise monolith problems, then you shouldn't program in turn-of-the-century OOP style, and you should take "best practices" from that era with a huge grain of salt. You should only use them if you can see how your codebase will benefit from them.
Even Java, the bastion of OOP conservatism, is acknowledging that "best practices" are relative by adding record classes. Record classes are first-class language support for violating the best practices that were drilled into generations of Java programmers!
(There are people who do have those turn-of-the-century enterprise monolith problems, for example, library developers! They ship their changes to hundreds or even thousands of people they've never met, who don't keep up with project updates, and who don't budget time to deal with breaking changes. So a lot of the ideas turn out to be really valuable! Just not for, say, small teams building microservices.)
So what do you do with a "best practice" that doesn't make any sense to you? Do you just keep doing it forever because you can't understand why anybody would invent it in the first place? To take an example I'm familiar with, there's a good chance if you don't understand a Java OOP best practice it's because you've never encountered the problems it was designed to cope with. The OOP design principles that came out of the 1990s and became orthodox in Java around the turn of the century were built to solve the problem of scaling monolithic application development to teams of dozens or hundreds of developers. You would have dozens of people, imperfectly coordinated, hacking on a monolithic codebase for an application that was released quarterly (if that!) and ran on servers that cost more than the CEO's car. The coding style innovations of that era naturally focused on coming up with more and more ways to add layers of protective abstraction, and on training programmers to add those layers to their code no matter what, even if it doesn't seem worth it because 99% of the time, if somebody didn't understand that it was worth it, it was because they were inexperienced and hadn't lived through a horrific integration debacle that delayed the quarterly release by a month.
In my opinion, if your problems don't resemble those turn-of-the-century enterprise monolith problems, then you shouldn't program in turn-of-the-century OOP style, and you should take "best practices" from that era with a huge grain of salt. You should only use them if you can see how your codebase will benefit from them.
Even Java, the bastion of OOP conservatism, is acknowledging that "best practices" are relative by adding record classes. Record classes are first-class language support for violating the best practices that were drilled into generations of Java programmers!
(There are people who do have those turn-of-the-century enterprise monolith problems, for example, library developers! They ship their changes to hundreds or even thousands of people they've never met, who don't keep up with project updates, and who don't budget time to deal with breaking changes. So a lot of the ideas turn out to be really valuable! Just not for, say, small teams building microservices.)
Yup, I 100% agree. The point of the post wasn't to bemoan practices, more just that it's frustrating to be told repeatedly that a certain thing is a "best practice" when really it's just what the developer who wrote it preferred.
Software Engineers should just say "this is how we like to do things" and not pretend that there's a holy grail of correctness when really it's just what they like.
Software Engineers should just say "this is how we like to do things" and not pretend that there's a holy grail of correctness when really it's just what they like.
Most places I have worked had zero agreed standards. It wasn’t a problem at all. And people didn’t waste their time getting into fights about how to interpret the “agreed standards” or policing it. Great!
I feel like at this point, comparaison between software engineers and civil engineers should fall under the "does not gratify intellectual curiosity" category. I haven't seen anything interesting said about this topic since the article series "are we really engineers?" https://www.hillelwayne.com/post/are-we-really-engineers/.
> At the end of the day, you wind up in a lot of fairly pointless arguments about tech stack and coding conventions that 99.9% of the time don’t make a bit of difference to the final product.
That's a great conclusion.
> At the end of the day, you wind up in a lot of fairly pointless arguments about tech stack and coding conventions that 99.9% of the time don’t make a bit of difference to the final product.
That's a great conclusion.
> You can’t do it “correctly” if “correct” is “whatever the guy who’s been here longer wants.”
To be honest, "correctly" is whatever actually works. But since we as an industry haven't been around for a long time and don't collectively know what actually works, it is simply the case that we defer to those who have comparatively more experience, so that we may get decent solutions now, as opposed to excellent ones later.
It took the ancient civilizations hundreds if not thousands of years to perfect architecture to a reasonable degree, where it's possible to be fairly certain about the viability of most typical designs, as well as the tradeoffs that nonstandard ones might require.
Personally, i think that we'll only be able to talk about what truly works and what doesn't once the industry cools down - when there are new JS frameworks once a month or once a year as opposed to every day (or for any technology, really). When there are very few breaking framework changes, because the frameworks would finally be stable. When the primitives around doing web development, interfacing with devices and everything else have been distilled to their most usable possible forms. When a developer doesn't need 10 languages or 20 frameworks to do their job, but can instead rely upon a few, after most others would have died off after a sort of singularity of languages.
That's when useful certifications would be possible. That's when estimates wouldn't be guesswork. That's when the education systems could actually prepare people fully for working in the industry. That's when the development of projects wouldn't be such Wild West, but instead would be a process with far higher quality, a true engineering discipline even at the expense of projects taking longer to actually develop, much like you don't construct buildings in an ad hoc fashion.
Now, whether that will happen in a 100 years, a 1000 years or never, is another question entirely.
To be honest, "correctly" is whatever actually works. But since we as an industry haven't been around for a long time and don't collectively know what actually works, it is simply the case that we defer to those who have comparatively more experience, so that we may get decent solutions now, as opposed to excellent ones later.
It took the ancient civilizations hundreds if not thousands of years to perfect architecture to a reasonable degree, where it's possible to be fairly certain about the viability of most typical designs, as well as the tradeoffs that nonstandard ones might require.
Personally, i think that we'll only be able to talk about what truly works and what doesn't once the industry cools down - when there are new JS frameworks once a month or once a year as opposed to every day (or for any technology, really). When there are very few breaking framework changes, because the frameworks would finally be stable. When the primitives around doing web development, interfacing with devices and everything else have been distilled to their most usable possible forms. When a developer doesn't need 10 languages or 20 frameworks to do their job, but can instead rely upon a few, after most others would have died off after a sort of singularity of languages.
That's when useful certifications would be possible. That's when estimates wouldn't be guesswork. That's when the education systems could actually prepare people fully for working in the industry. That's when the development of projects wouldn't be such Wild West, but instead would be a process with far higher quality, a true engineering discipline even at the expense of projects taking longer to actually develop, much like you don't construct buildings in an ad hoc fashion.
Now, whether that will happen in a 100 years, a 1000 years or never, is another question entirely.
I think you will find that there is a large set of ways to solve the same problem equally well. So arguing about the best way to solve the problem is a waste of time.
In many cases this is only because of unnecessary duplication of languages and frameworks.
People wonder about whether they should create their back end in Ruby or PHP. People wonder about whether they should create their front end in Angular or React. People wonder about whether they should use MySQL or PostgreSQL for persistence. They wonder about which of the many OS distributions they should use for hosting their application.
But perhaps that's the true waste of time - maybe we shouldn't need multiple approaches to each problem. Maybe we'd only need one, which could then be the sole focus of the industry. The tooling would be incredible if there would be just one workflow to support. The technologies would be tightly integrated, since that's where all of the effort would go. And there could be models built around the language and frameworks to such a level that any usages of antipatterns could be immediately identified and even fixed automatically.
If you ask me, the millions of man-hours that have been spent on creating a brittle and fragmented landscape of tools that don't work well and make developer's knowledge obsolete in a few years while also urging people to do CV driven development are the real waste of time.
Of course, that's the reality that we live in but maybe for the developers in 500-1000 years it won't be that way.
People wonder about whether they should create their back end in Ruby or PHP. People wonder about whether they should create their front end in Angular or React. People wonder about whether they should use MySQL or PostgreSQL for persistence. They wonder about which of the many OS distributions they should use for hosting their application.
But perhaps that's the true waste of time - maybe we shouldn't need multiple approaches to each problem. Maybe we'd only need one, which could then be the sole focus of the industry. The tooling would be incredible if there would be just one workflow to support. The technologies would be tightly integrated, since that's where all of the effort would go. And there could be models built around the language and frameworks to such a level that any usages of antipatterns could be immediately identified and even fixed automatically.
If you ask me, the millions of man-hours that have been spent on creating a brittle and fragmented landscape of tools that don't work well and make developer's knowledge obsolete in a few years while also urging people to do CV driven development are the real waste of time.
Of course, that's the reality that we live in but maybe for the developers in 500-1000 years it won't be that way.
I don’t think having multiple ecosystems is a bad thing. Think about it as a market place where ecosystems compete to attract the attention of developers. A bit like a decentralised economy. While what you are suggesting is the equivalent of a top down centrally planned economy where a dictator will tell everybody what to use. And (I assume) police and punish everybody who doesn’t comply. That doesn’t sound like a good thing.
All the problems stated require more context:
- extract an interface or not -> an interface can speed up compilation (under the right conditions)
- pass more or less arguments -> how many call sites exist? What’s the performance difference? Would it complicate testing?
- testing -> depends on what you’re building, when do you need it by, and how problematic a bug may be (and more)
The reason it looks like some random preference is because over time we naturally gravitate (or been told to do) what works, and we keep choosing it heuristically since a thorough analysis of the problem is too costly or impossible.
Civil engineering has a bunch of hard rules on have X slack here because people will die for such mistakes. But I suspect you use best practices for less high stake stuff (do we use this outlet configuration or this one?) (actual civil engineers are welcome to correct me)
- extract an interface or not -> an interface can speed up compilation (under the right conditions)
- pass more or less arguments -> how many call sites exist? What’s the performance difference? Would it complicate testing?
- testing -> depends on what you’re building, when do you need it by, and how problematic a bug may be (and more)
The reason it looks like some random preference is because over time we naturally gravitate (or been told to do) what works, and we keep choosing it heuristically since a thorough analysis of the problem is too costly or impossible.
Civil engineering has a bunch of hard rules on have X slack here because people will die for such mistakes. But I suspect you use best practices for less high stake stuff (do we use this outlet configuration or this one?) (actual civil engineers are welcome to correct me)
Did structural engineering for a bit before coming back to software.
More or less right about hard rules. They're not truly hard, and it's different in different countries. Some countries have performance based rules, others have descriptive rules (must have 35mm of concrete cover over reinforcement bars) but even in those situations you can usually get some sort of person to overrule the rule, it's just costly in both time and money, but sometimes its worth it.
Take ultra high performance concrete for example. It's almost a different material compared to the normal stuff. But for run of the mill construction everyone kinda likes sticking to the rules because it's like outsourcing handling all the edge-cases. Kinda like using Postgres over writing your own persistence layer.
As for hard rules in software, that would be tough. It's much more multidimensional and maneuverable than civil engineering is and we have less history dealing with it. Also, there are way more security concerns than civil engineering, which is mostly about safety concerns, where there are no arms races against you.
We could still do it abstractly though. Favouring maxims and penalties over nitty gritty rules.
More or less right about hard rules. They're not truly hard, and it's different in different countries. Some countries have performance based rules, others have descriptive rules (must have 35mm of concrete cover over reinforcement bars) but even in those situations you can usually get some sort of person to overrule the rule, it's just costly in both time and money, but sometimes its worth it.
Take ultra high performance concrete for example. It's almost a different material compared to the normal stuff. But for run of the mill construction everyone kinda likes sticking to the rules because it's like outsourcing handling all the edge-cases. Kinda like using Postgres over writing your own persistence layer.
As for hard rules in software, that would be tough. It's much more multidimensional and maneuverable than civil engineering is and we have less history dealing with it. Also, there are way more security concerns than civil engineering, which is mostly about safety concerns, where there are no arms races against you.
We could still do it abstractly though. Favouring maxims and penalties over nitty gritty rules.
Short answer: No, they're not.
Longer answer: I'm confused by the examples given. Nothing there is a best practice IMO, they are only opinions.
This writer is confusing "use git" or more basically "use version control" with the how's and why's underneath. Everything beyond "use it" is an opinion, with multiple "best" options depending on your desired workflow or requirements.
Same for Java - the senior explained why this version of "best" is best for them, but the real best practice of "define your interface as a contract" is hidden behind these opinions.
Contrast this with the civil engineer used as an example, who might say "use a safety factor of 3x rated weight for all fasteners" as their best practice. Using fasteners rated at 2x is a violation of that, but using screws vs bolts vs adhesive are all opinions and depend on the particulars and preferences of whoever is doing the work.
Longer answer: I'm confused by the examples given. Nothing there is a best practice IMO, they are only opinions.
This writer is confusing "use git" or more basically "use version control" with the how's and why's underneath. Everything beyond "use it" is an opinion, with multiple "best" options depending on your desired workflow or requirements.
Same for Java - the senior explained why this version of "best" is best for them, but the real best practice of "define your interface as a contract" is hidden behind these opinions.
Contrast this with the civil engineer used as an example, who might say "use a safety factor of 3x rated weight for all fasteners" as their best practice. Using fasteners rated at 2x is a violation of that, but using screws vs bolts vs adhesive are all opinions and depend on the particulars and preferences of whoever is doing the work.
The two aren't mutually excusive. What I mean is, you can develop a preference for doing a software engineering task according to a best practice. Getting into the habit of using one or more time-tested practice(s) will only benefit you over time.
But, more fundamentally, what the author could have responded to their friend is: "Yes, we do have a code of ethics and professional practice standards[0]. We do have well-researched best practices and a rich standardized body of knowledge we can use[2]. We do have formally adopted standards through IEEE, ISO and IEC[1]."
I do get the sentiment behind the question though and personally wish we were more formally trained and held more rigorously to a professional set of standards. It does diminish the term "Software Engineer" as a engineering field when we use the title so loosely but (on some level) expect the same level of respect, pay and status as other engineers.
[0] https://ethics.acm.org/code-of-ethics/software-engineering-c... [1] https://en.wikipedia.org/wiki/ISO/IEC_JTC_1/SC_7 [2] https://www.computer.org/education/bodies-of-knowledge/softw...
But, more fundamentally, what the author could have responded to their friend is: "Yes, we do have a code of ethics and professional practice standards[0]. We do have well-researched best practices and a rich standardized body of knowledge we can use[2]. We do have formally adopted standards through IEEE, ISO and IEC[1]."
I do get the sentiment behind the question though and personally wish we were more formally trained and held more rigorously to a professional set of standards. It does diminish the term "Software Engineer" as a engineering field when we use the title so loosely but (on some level) expect the same level of respect, pay and status as other engineers.
[0] https://ethics.acm.org/code-of-ethics/software-engineering-c... [1] https://en.wikipedia.org/wiki/ISO/IEC_JTC_1/SC_7 [2] https://www.computer.org/education/bodies-of-knowledge/softw...
I did say that to be fair, I just omitted it from the post.
The question was more of a jumping off point for my thoughts on the practices vs. preferences question.
The question was more of a jumping off point for my thoughts on the practices vs. preferences question.
Fair enough! Thank you for posting the article and getting this discussion going, by the way.
After reading this article, the theory that comes to mind is that "best practices" not just developer preferences - rather, "best practices" is cargo culting by mediocre programmers, trying to copy techniques that a really skilled programmer once employed to do amazing things.
This is the part of the article that made me think this:
>As I type this, I’m in a discussion about whether it’s better to pass a few unnecessary parameters to simplify a bash script’s internal logic or pass fewer parameters and make the bash script more complex.
This sounds like they're on the verge of parameterized, object-capability design - passing in the paths to operate on, rather than hardcoding some internal logic to determine what to do. If you do this in the right places and at the right time, you can do amazing stuff, reuse scripts in totally novel environments and for novel purposes. At other times, it's not necessary. But I'm guessing neither side really knows how to use that to do amazing stuff.
Some programmers don't have the skill to recognize when a specific technique is justified or unjustified. So, unmoored from technical reality, they just argue about cultural norms - blindly copy what someone else did once, which brought someone else success - cargo culting.
That all sounds very mean, but if this is what's actually going on, I'm not sure what the solution is. Maybe more focus on really impressive and amazing concrete projects, rather than just individual practices in isolation?
This is the part of the article that made me think this:
>As I type this, I’m in a discussion about whether it’s better to pass a few unnecessary parameters to simplify a bash script’s internal logic or pass fewer parameters and make the bash script more complex.
This sounds like they're on the verge of parameterized, object-capability design - passing in the paths to operate on, rather than hardcoding some internal logic to determine what to do. If you do this in the right places and at the right time, you can do amazing stuff, reuse scripts in totally novel environments and for novel purposes. At other times, it's not necessary. But I'm guessing neither side really knows how to use that to do amazing stuff.
Some programmers don't have the skill to recognize when a specific technique is justified or unjustified. So, unmoored from technical reality, they just argue about cultural norms - blindly copy what someone else did once, which brought someone else success - cargo culting.
That all sounds very mean, but if this is what's actually going on, I'm not sure what the solution is. Maybe more focus on really impressive and amazing concrete projects, rather than just individual practices in isolation?
I think we'd be better off as a whole if we could agree on exactly what it was we were trying to get out of software best practices rather than arguing about what they are. To me, the biggest problem with all software I've ever worked on - since I started programming in 1992 - is how difficult it is to reproduce a scenario that a user reports. Making this as simple as possible seems to me to be an incredibly important as well as relatively straightforward goal, but I have yet to find anybody who agrees further than in principle.
> rather, "best practices" is cargo culting by mediocre programmer, trying to copy techniques that a really skilled programmer once employed to do amazing things.
and then when this does not work, they call themselves artists.
i actually heard this quite a lot in all these years in the field - "coding is an art". it is for some, for most is just copy/paste from SO :)
and then when this does not work, they call themselves artists.
i actually heard this quite a lot in all these years in the field - "coding is an art". it is for some, for most is just copy/paste from SO :)
Yes and no.
Given the context of the authors ( and this also includes employment context, socioeconomic and personality factors for everyone involved ), the best practice is something that has been "proved" to work well.
So no, it's not just a preference, but in practical terms many times it's a preference that some people agree it worked ( in their context ).
And let's not even talk about the "best practices" and technologies created just to sell you something. I think by now it's not a secret that most "developer evangelists" or even "famous" developers are just people doing sales and marketing, some of them don't even realize it such is their ego trip.
Given the context of the authors ( and this also includes employment context, socioeconomic and personality factors for everyone involved ), the best practice is something that has been "proved" to work well.
So no, it's not just a preference, but in practical terms many times it's a preference that some people agree it worked ( in their context ).
And let's not even talk about the "best practices" and technologies created just to sell you something. I think by now it's not a secret that most "developer evangelists" or even "famous" developers are just people doing sales and marketing, some of them don't even realize it such is their ego trip.
In some cases, perhaps, but the _state of the art_ is always evolving and a lot of it is informed by how people practice software engineering in the wild.
Professional Engineer is a modern concept. In the United States it started in 1907. Sure we have been building irrigation systems for thousands of years but it wasn't regulated by governments until recent history.
Until then it was a practice guarded by guilds and seen as a craft.
Software isn't without its own history. The mathematicians and logicians had been working on it long before the first computing machine was built. We've known how to compute values for thousands of years.
Are we still in the craft/guild phase of the discipline? I don't think so. There are professional engineering organizations around the world that are certifying software engineers. If that is all that is required you can apply today.
The missing piece is that it's not required by governments around the world to have any professional affiliation or certification to practice programming professionally. Some argue this is a good thing as it keeps the playing field level. Others argue its bad as it enables profit-motivated companies to cut corners that harm businesses and users.
But as far as best practices go, as long as there are enough people practising them across the industry, then it's not simply a preference. A good guide on this is the SWEBOK [0] published by the IEEE which attempts to catalogue these practices in a living document that gets updated as the state of the art develops.
[0] https://en.wikipedia.org/wiki/Software_Engineering_Body_of_K...
Professional Engineer is a modern concept. In the United States it started in 1907. Sure we have been building irrigation systems for thousands of years but it wasn't regulated by governments until recent history.
Until then it was a practice guarded by guilds and seen as a craft.
Software isn't without its own history. The mathematicians and logicians had been working on it long before the first computing machine was built. We've known how to compute values for thousands of years.
Are we still in the craft/guild phase of the discipline? I don't think so. There are professional engineering organizations around the world that are certifying software engineers. If that is all that is required you can apply today.
The missing piece is that it's not required by governments around the world to have any professional affiliation or certification to practice programming professionally. Some argue this is a good thing as it keeps the playing field level. Others argue its bad as it enables profit-motivated companies to cut corners that harm businesses and users.
But as far as best practices go, as long as there are enough people practising them across the industry, then it's not simply a preference. A good guide on this is the SWEBOK [0] published by the IEEE which attempts to catalogue these practices in a living document that gets updated as the state of the art develops.
[0] https://en.wikipedia.org/wiki/Software_Engineering_Body_of_K...
Make the simplest thing you possibly can, write lots of software tests and keep in mind that your code is a piece of communication to the next developer, like a story. Everything else is just vanity or preferences.
Lots of small, simple things can add up to a really complex and not very much maintainable result if you are not careful
So what I think you’re trying to say here is paraphrasing the (apocryphal?) Einstein quote, “as simple as possible and no simpler”. I agree, you need to design the software to be as simple as possible, that might include building some quite complex abstractions but again the net total should be the code ends up overall being simpler.
In a nutshell. Getting "as simple as possible" right is the art, and many times we can only really know we went too far with oversimplification (or overengineering) in retrospect.
I get your friend, and there's another point he can make: Imagine a world with self taught Civil Engineers.
Oh yeah the last bridge collapsed, but that is a known issue. It is fixed in this bridge, trust me.
Blame the contractor is what you normally do in this case :-)
I once built a system reverse engineering a program used for soil analysis to see why one of our bridges fell off its suports.
I once built a system reverse engineering a program used for soil analysis to see why one of our bridges fell off its suports.
Can you tell us more? This sounds oddly fascinating.
That’s sort of the Tacoma Narrows Bridge story.
Pretty much. IT as a field is a toddler. But it makes so many people happy we don't care it's still at the anal stage.
Maybe in a century techs and standards will stabilize.
Maybe in a century techs and standards will stabilize.
>Pretty much. IT as a field is a toddler.
It's exactly as old as nuclear engineering.
If it's a toddler, it's because of the mentality of the people involved, not because there was no time to figure things out.
It's exactly as old as nuclear engineering.
If it's a toddler, it's because of the mentality of the people involved, not because there was no time to figure things out.
It’s almost like we have different standards for different types of engineering.
The devs writing code for the next social media app operate under very different standards than the ones writing code for nuclear reactors. And that’s ok.
The devs writing code for the next social media app operate under very different standards than the ones writing code for nuclear reactors. And that’s ok.
nuclear engineering is a direct combination of applied physics, civil engineering and mechanical engineering, all having a long history.
SE started out from mathematics, but the hardest problems are not related to it. We're only pretty good at nailing the things directly from mathematics like algorithmic complexity or distributed system guarantees.
SE started out from mathematics, but the hardest problems are not related to it. We're only pretty good at nailing the things directly from mathematics like algorithmic complexity or distributed system guarantees.
Which was left in the hands of a small elite from the beginning. I don't think reddit could have been born that way :)
Pretty sure this is because most of our public investing goes towards spying programs instead of more funding for places like NIST.
Not to mention funding for governments that actively sell exploits to other nations. Standards seem to be left up to the industry. I saw the Kubernetes hardening guildelines from NIST a while back that was cool.
Not to mention funding for governments that actively sell exploits to other nations. Standards seem to be left up to the industry. I saw the Kubernetes hardening guildelines from NIST a while back that was cool.
To make the comparison fair, in that world civil engineers would also have the ability to change the laws of physics.
And the bridge collapsing would usually not kill people but strip all their clothes.
Also you can start a bridge in your garage.
Also you can start a bridge in your garage.
Or you can just compare them to software engineers that work on critical software like launch systems and nuclear reactors.
Software can be just as reliable when there is a need for it. Thing is, 99% of the time you don't need those extra 9s.
Software can be just as reliable when there is a need for it. Thing is, 99% of the time you don't need those extra 9s.
Yeah, that’s a very good point! I imagine if civil engineers could change physics, they’d lockdown what you’re allowed to change for critical systems. And like you said, systems that don’t need the 9s can experiment and learn.
Aren't best practices things like "don't roll your own crypto if you can avoid it", "store your code in version control", or "write down migrations as well as up migrations"? These are all choices where the right option has been absorbed into the craft.
Civil engineering best practices are written in blood, but I think software engineering best practices can be stretched to include sweat and tears too.
Civil engineering best practices are written in blood, but I think software engineering best practices can be stretched to include sweat and tears too.
Developers end up at local maxima because a whole bunch of practices add up to a working system. It's a mistake to champion any single practice without understanding how it fits into an ecosystem: time budget, testing, language features available, efficiency, tolerance for errors, imposed deadlines, third-party technical ecosystem, etc. It's all about the system where they all work together.
To truly suggest something as a best practice, you need to understand what it requires from the technical and social environment around it, and when it applies and doesn't apply. We're nowhere near that level of discipline as a field. This lack of discipline is why we wince when we hear that a startup is implementing something like voting machines: we know the financial incentives that lead to startups focusing on speed, and we can imagine the discipline that voting systems require. We know there's a mismatch between the social environment and the likely project management approach. But we're blind to the social and technical requirements that allow other practices to work well. When is it appropriate to use inheritance? Someone will inevitably say, "You shouldn't use it?" Why does it work so well in Rails?
IMO it's how developers like John Carmack[0] and Martin Fowler[1] can make opposite arguments about things like the benefits of having code inline or in functions. These two opinions work in conjunction with their environments; maybe video game and aerospace coding requires budgeted performance requires mutability, so Carmack has to control how you interleave side-effects. Maybe enterprise-grade Java programming doesn't have much of a performance budget at all, or maybe he values isolating testable functions more, so Fowler can take other approaches that allow more "readable" styles and not worry so much about side effects (since there are few).
[0] http://number-none.com/blow/john_carmack_on_inlined_code.htm...
[1] https://www.martinfowler.com/bliki/FunctionLength.html
To truly suggest something as a best practice, you need to understand what it requires from the technical and social environment around it, and when it applies and doesn't apply. We're nowhere near that level of discipline as a field. This lack of discipline is why we wince when we hear that a startup is implementing something like voting machines: we know the financial incentives that lead to startups focusing on speed, and we can imagine the discipline that voting systems require. We know there's a mismatch between the social environment and the likely project management approach. But we're blind to the social and technical requirements that allow other practices to work well. When is it appropriate to use inheritance? Someone will inevitably say, "You shouldn't use it?" Why does it work so well in Rails?
IMO it's how developers like John Carmack[0] and Martin Fowler[1] can make opposite arguments about things like the benefits of having code inline or in functions. These two opinions work in conjunction with their environments; maybe video game and aerospace coding requires budgeted performance requires mutability, so Carmack has to control how you interleave side-effects. Maybe enterprise-grade Java programming doesn't have much of a performance budget at all, or maybe he values isolating testable functions more, so Fowler can take other approaches that allow more "readable" styles and not worry so much about side effects (since there are few).
[0] http://number-none.com/blow/john_carmack_on_inlined_code.htm...
[1] https://www.martinfowler.com/bliki/FunctionLength.html
As I read this I'm building a distribution of a web framework that eliminates block templates and will only have one page template (for the head HTML). I'm gonna have CSS generation and upload built in the CMS as well (tailwind or tachyons only).
I'm sure there will be howls of "you can't let them put code in the database!"
Why not? It's their (the customer's) database and their web service, after all. You can do all sorts of validation on a form input and a database field (like with Tidy and Bleach in my case with Python). Can't do any on a plain text template file.
But "separation of concerns!"
For who? It's always been bad practice in my opinion to assume that not only do end users have on-staff development, or contract development, but that they have multiple tiers of it which need lines drawn between the duties of each. Who says everyone who needs custom software or custom web services is an IBM-sized conglomerate with multiple departments full of software developers? Why can't a mom and pop restaurant have a nice website and a nice phone app? Because they don't want to learn to use javascript, webpack, npm, git, and an IDE? Is that the only reason why?
The least accessible (in a physical sense) parts of web development are the parts that a customer might do themselves (CSS and HTML). I will not believe there is a good reason for that other than software developers trying to talk themselves into more jobs and more contracts.
I'm sure there will be howls of "you can't let them put code in the database!"
Why not? It's their (the customer's) database and their web service, after all. You can do all sorts of validation on a form input and a database field (like with Tidy and Bleach in my case with Python). Can't do any on a plain text template file.
But "separation of concerns!"
For who? It's always been bad practice in my opinion to assume that not only do end users have on-staff development, or contract development, but that they have multiple tiers of it which need lines drawn between the duties of each. Who says everyone who needs custom software or custom web services is an IBM-sized conglomerate with multiple departments full of software developers? Why can't a mom and pop restaurant have a nice website and a nice phone app? Because they don't want to learn to use javascript, webpack, npm, git, and an IDE? Is that the only reason why?
The least accessible (in a physical sense) parts of web development are the parts that a customer might do themselves (CSS and HTML). I will not believe there is a good reason for that other than software developers trying to talk themselves into more jobs and more contracts.
Question- if you're using eval() and bleach, won't your security be totally dependent on bleach not having a vulnerability?
Sure.
Kinda like how storing web templates in files is totally dependent on the people who upload them not putting crypto miners in the linked javascript(s) [1]. Or totally dependent on PAM not having a vulnerability [2]. Or totally dependent on SSH not having a vulnerability [3].
In terms of libraries and utilities I can give PAM and SSH a pass for fixing these things long ago. In the case of restricting a customer's access to the mechanism that renders their thing in favor of the option of "trust this guy who uploads things instead" you've got a much tougher sell about why that's better.
1. https://www.fortinet.com/blog/threat-research/the-growing-tr...
2. https://www.cvedetails.com/cve/CVE-2002-1227/
3. https://www.cvedetails.com/cve/CVE-2002-0083/
Kinda like how storing web templates in files is totally dependent on the people who upload them not putting crypto miners in the linked javascript(s) [1]. Or totally dependent on PAM not having a vulnerability [2]. Or totally dependent on SSH not having a vulnerability [3].
In terms of libraries and utilities I can give PAM and SSH a pass for fixing these things long ago. In the case of restricting a customer's access to the mechanism that renders their thing in favor of the option of "trust this guy who uploads things instead" you've got a much tougher sell about why that's better.
1. https://www.fortinet.com/blog/threat-research/the-growing-tr...
2. https://www.cvedetails.com/cve/CVE-2002-1227/
3. https://www.cvedetails.com/cve/CVE-2002-0083/
I hope at least that we're in a phase of the profession where we're "discovering" the actual best practices.
There have been a lot of best practices that have been hypothesized over time: OOP, functional programming, unit testing, generative testing, formal analysis, strict typing, weak typing, etc.
And all these as-of-yet unfounded hypotheses are important! You've got to have a theory of how something works before you can prove that it does. Hopefully we can start to devise those proofs.
There have been a lot of best practices that have been hypothesized over time: OOP, functional programming, unit testing, generative testing, formal analysis, strict typing, weak typing, etc.
And all these as-of-yet unfounded hypotheses are important! You've got to have a theory of how something works before you can prove that it does. Hopefully we can start to devise those proofs.
We're definitely still figuring out what the best practices are. In my relatively short career as a software developer, we've already flipped back and forth between separation of concerns is important when it comes to views, styling, and logic. (Frontend dev)
Gone are the days when we threw together a php, html, and JavaScript in one file... wait, or is it?
Gone are the days when we threw together a php, html, and JavaScript in one file... wait, or is it?
Give it a couple years, it'll come back around!
"So what are these rituals for?"
"Some are purely ritual, but some are there so that we can guard this dimension from horrors that live within!"
"Uh, I guess we should at least do the latter?"
"Oh? You can tell the difference? That's great!"
-- Girl Genius
"Some are purely ritual, but some are there so that we can guard this dimension from horrors that live within!"
"Uh, I guess we should at least do the latter?"
"Oh? You can tell the difference? That's great!"
-- Girl Genius
In your example, read the spring manual. You need the inference to help spring generate proxies for your service class. You could use cglib to remove this requirement but it's the way the spring API has been for ages. Also using an interface let's you easily mock things out and write dummy test implementations. Pretty valuable.
I read about spring's best practices and think some are unnecessary boilerplate code without any real benefits.
I get the theory, but in practice, the benefits are just theoretical. You could reimplement interfaces for your tests, but it is easier just to use a mocking library.
I get the theory, but in practice, the benefits are just theoretical. You could reimplement interfaces for your tests, but it is easier just to use a mocking library.
A lot of "best practices" are developers who make code complex in order to attain some level of architectural purity for its own sake.
An example of this I recently experienced was trying to understand and debug what should have been a simple integration app, but where a ton of injected commands and queries were used to implement the functionality. Following the logic was painful as the code was completely atomized for no particular reason. Worse, real-world concerns, like proper logging, were ignored.
I hate to call this an "autism tax", but perhaps there's something to the term: many intelligent developers, especially left unsupervised, tend to pursue highly abstract solutions, to what should be straightforward problems in order to satisfy a compulsion for order and symmetry.
An example of this I recently experienced was trying to understand and debug what should have been a simple integration app, but where a ton of injected commands and queries were used to implement the functionality. Following the logic was painful as the code was completely atomized for no particular reason. Worse, real-world concerns, like proper logging, were ignored.
I hate to call this an "autism tax", but perhaps there's something to the term: many intelligent developers, especially left unsupervised, tend to pursue highly abstract solutions, to what should be straightforward problems in order to satisfy a compulsion for order and symmetry.
I had a principal engineer who wouldn’t use the term “best practices”. Instead, he called them “proven practices.” I’ve adopted that term myself, because it is much more accurate- there is a body of knowledge on how to build software well, but it’s a tool kit not an instruction manual.
There also really is software engineering that goes on- I work in an org that does extensive analysis, testing, and validation of firmware before it is rolled out. It’s a real thing. That being said, so is cranking out a CRUD web app with zero testing to make our PMs data collection tasks easier. It’s all on a continuum. The key trick for software “engineering” versus just development is knowing where in the continuum a given project needs to be and what tools are appropriate in that context.
There also really is software engineering that goes on- I work in an org that does extensive analysis, testing, and validation of firmware before it is rolled out. It’s a real thing. That being said, so is cranking out a CRUD web app with zero testing to make our PMs data collection tasks easier. It’s all on a continuum. The key trick for software “engineering” versus just development is knowing where in the continuum a given project needs to be and what tools are appropriate in that context.
Lots of Java Frameworks (definitely Spring) will generate wrapper classes for your code to handle things like method level authorization, pre/post method logging, Exception transformation. This is generally termed "Aspect Oriented Programming". This is exactly whats going on with Spring's @Service annotation. In order for you to still be able to call your methods even though the class will be some sort of proxy at runtime, an Interface is required. It may seem silly but it all makes perfect sense when you understand whats going on.
Edit: Surprised I haven't seen this mentioned in any other comments. I had thought this was pretty common knowledge, at least amongst people with Java experience.
Edit: Surprised I haven't seen this mentioned in any other comments. I had thought this was pretty common knowledge, at least amongst people with Java experience.
What code would you rather maintain:
A is similar to Roman numerals. We all know that Roman numerals are no longer used for most purposes and were replaced by the numeral system we currently use. Not only the new numeral system is more convenient for various reasons but it allowed people to advance math further. So A is better than B in that sense.
Then, A uses an identifier that doesn't represent its value. We can also say it's bad because of that reason.
You can try to seek ways to compare and improve code. Not all of them will be effective, but at least you will be trying. That is better than being that disagreeable, nihilistic guy that thinks that everything is subjective and relative and won't agree with anything you say.
You have to learn how to treat your code with respect and prevent it from becoming a tech debt dumpster.
There is code that is objectively bad. And you will know when you try to maintain, debug or profile it, or when you have to explain it to someone else. Or when it keeps breaking over and over again and many defects are connected with it. Or when it becomes a product limitation and you have to apologize to customers about it.
// A
const int giraffe = 1 + 1 + 1 + 1 + 1;
// B
const int number = 5;
At some moment, you will meet some disagreeable person that will say they are the same and it doesn't matter which one you pick.A is similar to Roman numerals. We all know that Roman numerals are no longer used for most purposes and were replaced by the numeral system we currently use. Not only the new numeral system is more convenient for various reasons but it allowed people to advance math further. So A is better than B in that sense.
Then, A uses an identifier that doesn't represent its value. We can also say it's bad because of that reason.
You can try to seek ways to compare and improve code. Not all of them will be effective, but at least you will be trying. That is better than being that disagreeable, nihilistic guy that thinks that everything is subjective and relative and won't agree with anything you say.
You have to learn how to treat your code with respect and prevent it from becoming a tech debt dumpster.
There is code that is objectively bad. And you will know when you try to maintain, debug or profile it, or when you have to explain it to someone else. Or when it keeps breaking over and over again and many defects are connected with it. Or when it becomes a product limitation and you have to apologize to customers about it.
To some extend best practices are just developer preferences, but some best practices are also due to experience which has shown alternatives to attract problems down the lane.
Personally I think the most important thing is to agree within a project, what style and what practices to follow, so everyone is going in the same direction. This should in my opinion make the code more maintainable and extensible, due to the reduction in cognitive overload for the developers involved.
Personally I think the most important thing is to agree within a project, what style and what practices to follow, so everyone is going in the same direction. This should in my opinion make the code more maintainable and extensible, due to the reduction in cognitive overload for the developers involved.
I don't see the point of this. As an engineer you get a task and then pick a solution from a bag you have, that is not optimal, but fulfills the constraints you got. Time and money, features, accuracy, speed, waste, etc.
Where is the difference with software? You get the same kind of constraints and need to build something from libraries and custom code, that fits all of them.
There may be more constraints for a skyscraper than a small garage, and there are more constraints for airplane software than a website. You can't write flight controllers in javascript, the same way you cannot build your airplane out of toilet paper. There are also more constraints for airplane software than for your backyard garage. It only depends on the regulations in the field. Most of the times software doesn't have the potential to harm people, like houses and bridges have. So you have less regulations.
If you want to build a bicycle, there is no right solution either. You could benchmark it by weight, like you could benchmark software by memory usage.
Most engineering products only rely on best practice and the way the company does it since years, from experience. There is no "right" solution, neither in civil-, nor in software-, nor in engineering in general.
Where is the difference with software? You get the same kind of constraints and need to build something from libraries and custom code, that fits all of them.
There may be more constraints for a skyscraper than a small garage, and there are more constraints for airplane software than a website. You can't write flight controllers in javascript, the same way you cannot build your airplane out of toilet paper. There are also more constraints for airplane software than for your backyard garage. It only depends on the regulations in the field. Most of the times software doesn't have the potential to harm people, like houses and bridges have. So you have less regulations.
If you want to build a bicycle, there is no right solution either. You could benchmark it by weight, like you could benchmark software by memory usage.
Most engineering products only rely on best practice and the way the company does it since years, from experience. There is no "right" solution, neither in civil-, nor in software-, nor in engineering in general.
Well the choices should be based on data, does method 1 or method 2 result in code which functions longer without needing to be fixed, or updated.
There _IS_ data about some of this, but the results frequently go against the opinions of various people, so they are discounted. And then there is the problem that the industry as a whole has a tendency to run away from old/stale/well understood/etc technologies in support of untested new products. Which is how you get the cool language churn. You can just look at the last 20 years of server side web development, php, ruby, python, javascript, were all the "best choice" at one point or another, only to be pushed to the sidelines when they were discovered to be sub-optimal in some way.
So, its like the C/java/etc brace problem. There were a fair number of actual studies showing that matched brace styles seem to result in fewer bugs back in the 1990's, yet overwhelmingly the opensource community rejects that in nearly every single project regardless of language. Why? Presumably its just personal preference going back to the old days of 80x25 tty's where whitespace was at a premium, same as the 80 column limits many projects employ.
There _IS_ data about some of this, but the results frequently go against the opinions of various people, so they are discounted. And then there is the problem that the industry as a whole has a tendency to run away from old/stale/well understood/etc technologies in support of untested new products. Which is how you get the cool language churn. You can just look at the last 20 years of server side web development, php, ruby, python, javascript, were all the "best choice" at one point or another, only to be pushed to the sidelines when they were discovered to be sub-optimal in some way.
So, its like the C/java/etc brace problem. There were a fair number of actual studies showing that matched brace styles seem to result in fewer bugs back in the 1990's, yet overwhelmingly the opensource community rejects that in nearly every single project regardless of language. Why? Presumably its just personal preference going back to the old days of 80x25 tty's where whitespace was at a premium, same as the 80 column limits many projects employ.
A big issue in this industry is that folks do things like if no one else had done them before, reinventing the wheel continually. It feels like it evolves fast, but really, it's going in slow motion, because we're constantly starting over.
It doesn't matter if someone, or a group of people, spent years researching a topic: even given an extremely similar situation with similar resources and constraints, an engineer right out of school will still feel compelled to try and solve the problem anew.
Part of the issue is that we're very bad at identifying constraints and context, and thus it's really hard to apply pre-existing solutions. Eg: people trying to apply concepts developed by large FAANG-style companies in a startup.
Part of it though, is sheer arrogance. Everyone feel like they know better. There's also a bit of "playing programmer" going on: folks do a lot of things because they find them more fun, even if it was somehow objectively a worse solution (and they knew it). Because software engineers are in such high demand, people above are afraid to drop the hammer. Concept such as team or individual autonomy are put above the global maximum of the business. This autonomy and freedom is justified by saying it drives innovation, but you're not innovating if you're constantly starting over. For example, while modern languages do have some cool new features, we also keep reinventing the tooling, editors and debuggers around them, which drives progress in those areas to a crawl.
All around, there's a balance between solidifying some concepts, vs continuing to innovate. Right now we're leaning a bit too hard toward chaos, and the industry would benefit a little from letting things mature.
It doesn't matter if someone, or a group of people, spent years researching a topic: even given an extremely similar situation with similar resources and constraints, an engineer right out of school will still feel compelled to try and solve the problem anew.
Part of the issue is that we're very bad at identifying constraints and context, and thus it's really hard to apply pre-existing solutions. Eg: people trying to apply concepts developed by large FAANG-style companies in a startup.
Part of it though, is sheer arrogance. Everyone feel like they know better. There's also a bit of "playing programmer" going on: folks do a lot of things because they find them more fun, even if it was somehow objectively a worse solution (and they knew it). Because software engineers are in such high demand, people above are afraid to drop the hammer. Concept such as team or individual autonomy are put above the global maximum of the business. This autonomy and freedom is justified by saying it drives innovation, but you're not innovating if you're constantly starting over. For example, while modern languages do have some cool new features, we also keep reinventing the tooling, editors and debuggers around them, which drives progress in those areas to a crawl.
All around, there's a balance between solidifying some concepts, vs continuing to innovate. Right now we're leaning a bit too hard toward chaos, and the industry would benefit a little from letting things mature.
[deleted]
I think there is just some semantic confusion here.
I think a "best practice" should be a practice that is good to apply across a certain problem domain (regardless of where you work or what dev team you are part of).
And there are coding styles/guidelines which can apply only to a specific dev group or codebase. They can often be arbitrary, in the sense where it would be fine to do it in different ways, but one is chosen, for consistency (to promote maintainability/readability). They can be one way to achieve a best practice.
Day to day, it's probably fine to loosely call all these "best practices" since you apply them the same. But it is also sometimes useful to make the distinction, e..g, so you understand why a certain practice is being used.
The first example is a coding style, and a judgement call. The underlying "best practice" is to separate interface from implementation. There are various other ways to do that, of course, and need not be done like this. (Personally, I find this practice a little "enterprise-y", which I consider an insult.)
The example about version control also depends on the process and practice of the dev group.
I think a "best practice" should be a practice that is good to apply across a certain problem domain (regardless of where you work or what dev team you are part of).
And there are coding styles/guidelines which can apply only to a specific dev group or codebase. They can often be arbitrary, in the sense where it would be fine to do it in different ways, but one is chosen, for consistency (to promote maintainability/readability). They can be one way to achieve a best practice.
Day to day, it's probably fine to loosely call all these "best practices" since you apply them the same. But it is also sometimes useful to make the distinction, e..g, so you understand why a certain practice is being used.
The first example is a coding style, and a judgement call. The underlying "best practice" is to separate interface from implementation. There are various other ways to do that, of course, and need not be done like this. (Personally, I find this practice a little "enterprise-y", which I consider an insult.)
The example about version control also depends on the process and practice of the dev group.
Skimming all of these comments I think that creating software remains more of a craft than an engineering discipline. Not that that’s a bad thing, in that it permits creativity. And for most cases, engineering-level rigor isn’t worth the effort. As Tom West said in Soul “Not everything worth doing is worth doing well.”
Sadly, this approach seems to have been used in the interface software of my RAV4.
Sadly, this approach seems to have been used in the interface software of my RAV4.
The issue here is that people abuse the term and call many things and anything a "best practice".
An actual best practice is based on objective criteria and experience, and can be shown to lead to better outcomes over the alternatives.
If that's not the case, then it is just a preference, indeed.
For instance, version control is a best practice. It objectively improves software development. So is unit testing, etc.
An actual best practice is based on objective criteria and experience, and can be shown to lead to better outcomes over the alternatives.
If that's not the case, then it is just a preference, indeed.
For instance, version control is a best practice. It objectively improves software development. So is unit testing, etc.
>“How can Software Engineers call themselves engineers when there’s no rules, governing bodies, or anything to stipulate what true Software Engineering is? The parallel he drew was to another friend who’s a Civil Engineer. His friend had to be state certified ”
That friend simply didn't realize that "engineer" has different semantics with different historical evolution of word usage:
(1) "professional engineer" -- as in state license board and certification e.g. civil engineer
(2) "engineer" as a descriptive modifier -- e.g. "software engineer" and also some non-programming examples such as "audio engineer", "video engineer", "supply chain engineer": https://www.google.com/search?q=%22supply+chain+engineer%22
We could ask a similar question the friend asked: How can there be a "supply chain engineer" when there are no governing bodies for "supply chain certification" ?!?
It's because some people like to concatenate "engineer" at the end of a job role and others adopt the label and the usage gains wide currency. On the other hand, "dessert pastry engineer" hasn't really caught on so creating a fancier title doesn't always get accepted.
Back in the old days (1960s & 70s), the job titles of programmers on org charts -- especially at non-software companies like banks using COBOL, etc -- was "PROGRAMMER I", "PROGRAMMER II", etc. The "software engineer" seemed to be mostly popularized by software-focused companies like Microsoft, Silicon Valley. But now, even old companies like banks where coding is a cost-center instead of profit-center also have "engineer" in programming job titles.
That friend simply didn't realize that "engineer" has different semantics with different historical evolution of word usage:
(1) "professional engineer" -- as in state license board and certification e.g. civil engineer
(2) "engineer" as a descriptive modifier -- e.g. "software engineer" and also some non-programming examples such as "audio engineer", "video engineer", "supply chain engineer": https://www.google.com/search?q=%22supply+chain+engineer%22
We could ask a similar question the friend asked: How can there be a "supply chain engineer" when there are no governing bodies for "supply chain certification" ?!?
It's because some people like to concatenate "engineer" at the end of a job role and others adopt the label and the usage gains wide currency. On the other hand, "dessert pastry engineer" hasn't really caught on so creating a fancier title doesn't always get accepted.
Back in the old days (1960s & 70s), the job titles of programmers on org charts -- especially at non-software companies like banks using COBOL, etc -- was "PROGRAMMER I", "PROGRAMMER II", etc. The "software engineer" seemed to be mostly popularized by software-focused companies like Microsoft, Silicon Valley. But now, even old companies like banks where coding is a cost-center instead of profit-center also have "engineer" in programming job titles.
Even in infra, those jobs used to be called Operator/Administrator. Now everything is also an engineer, with increasingly baroque acronyms prepended (DevSecOps the new hotness)
> How can Software Engineers call themselves engineers when there’s no rules, governing bodies, or anything to stipulate what true Software Engineering is?
So the world had no engineers before the creation of governing bodies? That doesn't sound right to me. Thus, I think this person's definition needs some tweaking.
So the world had no engineers before the creation of governing bodies? That doesn't sound right to me. Thus, I think this person's definition needs some tweaking.
Not quite, a governing body is what stipulates who can be called an engineer and who cannot (at least this is the case in Canada.)
Certainly those who did engineering-like work existed before governing bodies, you just never really knew whether they were any good, because there was no minimum set of competency defined.
Ironically, one might say this is what software development is like right now! It is both a blessing and a curse, the accessibility of modern software development is what makes it so great, pitfalls and all.
Certainly those who did engineering-like work existed before governing bodies, you just never really knew whether they were any good, because there was no minimum set of competency defined.
Ironically, one might say this is what software development is like right now! It is both a blessing and a curse, the accessibility of modern software development is what makes it so great, pitfalls and all.
Yes...?? And what's wrong with that?
"Best Practices" means - given this problem set, these other engineers have tried a number of ideas and put together a framework, idea, code, whatever that represents a *good enough* solution.
There is no such thing as literal best, greatest, perfect. We're all just balancing tradeoffs in the "best" way we can.
For teams, consistency is more important than cleverness. If something needs to be "clever" then it is important enough to become consistently used because if the person who built the "clever" thing leaves, it becomes expensive to maintain it.
That's what "best practices" are, they are a consistent set methods that enough people have tried them that allows you to "stand on the shoulder of giants" and focus on more critical problems.
"Best Practices" means - given this problem set, these other engineers have tried a number of ideas and put together a framework, idea, code, whatever that represents a *good enough* solution.
There is no such thing as literal best, greatest, perfect. We're all just balancing tradeoffs in the "best" way we can.
For teams, consistency is more important than cleverness. If something needs to be "clever" then it is important enough to become consistently used because if the person who built the "clever" thing leaves, it becomes expensive to maintain it.
That's what "best practices" are, they are a consistent set methods that enough people have tried them that allows you to "stand on the shoulder of giants" and focus on more critical problems.
I found this video on the topic very compelling: Intro to Empirical Software Engineering: What We Know We Don't Know • Hillel Wayne • GOTO 2019: https://www.youtube.com/watch?v=WELBnE33dpY
The only objective thing for best practice is simplification. Problem with loose coupling, OOP etc... is that a lot of it sounds like "done" right but becomes complicated over time - even though it might be a good idea. So only "KPI" for best practice should be simplicity over time.
Serious question. Can humanity define what it means for something to be simple or complex? It seems like we all have an intuition that such a thing should exist. However, most times when I talk to people about it, the conclusion I reach is that they're talking about what is familiar or unfamiliar.
I've been working on something since approximately 2014 that I think finally has a reasonable chance of being correct (or at least useful ... for me). Now all I need to do is run a bunch of studies to see if this is actually a universal property or if it's just a bunch of bullshit that only makes sense to me.
But the point is that I don't want to use some weird self invented pseudo mathematical framework. I want there to be some obscure branch of mathematics that people already invented back in the 1800's that actually lets us define when some thing is complex and when it's simple. But as far as I can tell, it's just preference or poetics.
[
Okay, so there are a few things that sort of sound like they fit the bill, but when I looked into them I decided that they probably don't.
Cyclomatic complexity: This only works for if-statements (ie not for weird tangled OO object graphs or incomprehensible FP category theory operator soup) and some studies show that line count is a better indicator for defect rate.
Rich Hickey's Simple Made Easy talks are a gift to the software engineering community. But they're ultimately a poetic expression. You don't get to define one term and then pretend that you've solved how to write software. I view these talks as a very eloquent way of capturing the desire to create high quality craftsman like software. However, I don't believe that they're useful in a code review unless you need to appeal to pathos for some reason.
Kolmogorov complexity: This was really exciting to discover. However, I'm not really sure there's much here for programming. I guess you could use it to mathematically describe a boiler plate to apl spectrum. But I'm not sure you can use it to declare that any given point in the spectrum is better than any other point. Also, it doesn't really say anything about when mutable state is good or bad, etc. At best it's one metric out of many.
Information theory: Basically the same story with Kolmogorov complexity. You might be able to use this to decide that your variable naming is off, but there's so much more to good or bad software that this really can only be a single aspect at best.
]
I've been working on something since approximately 2014 that I think finally has a reasonable chance of being correct (or at least useful ... for me). Now all I need to do is run a bunch of studies to see if this is actually a universal property or if it's just a bunch of bullshit that only makes sense to me.
But the point is that I don't want to use some weird self invented pseudo mathematical framework. I want there to be some obscure branch of mathematics that people already invented back in the 1800's that actually lets us define when some thing is complex and when it's simple. But as far as I can tell, it's just preference or poetics.
[
Okay, so there are a few things that sort of sound like they fit the bill, but when I looked into them I decided that they probably don't.
Cyclomatic complexity: This only works for if-statements (ie not for weird tangled OO object graphs or incomprehensible FP category theory operator soup) and some studies show that line count is a better indicator for defect rate.
Rich Hickey's Simple Made Easy talks are a gift to the software engineering community. But they're ultimately a poetic expression. You don't get to define one term and then pretend that you've solved how to write software. I view these talks as a very eloquent way of capturing the desire to create high quality craftsman like software. However, I don't believe that they're useful in a code review unless you need to appeal to pathos for some reason.
Kolmogorov complexity: This was really exciting to discover. However, I'm not really sure there's much here for programming. I guess you could use it to mathematically describe a boiler plate to apl spectrum. But I'm not sure you can use it to declare that any given point in the spectrum is better than any other point. Also, it doesn't really say anything about when mutable state is good or bad, etc. At best it's one metric out of many.
Information theory: Basically the same story with Kolmogorov complexity. You might be able to use this to decide that your variable naming is off, but there's so much more to good or bad software that this really can only be a single aspect at best.
]
The best best practices I've heard usually have stories behind them. Someone did or didn't do X, and bad thing Y happened. Therefore we do or don't do X in the hopes of avoiding Y again.
The danger is that X keeps happening without the story of Y also being passed along; otherwise it turns into the Five Monkeys problem (https://intersol.ca/news/organizational-culture-and-the-5-mo...).
I'm not disagreeing with the author's friend's point. But at least if there's a story attached to the practice, then it's less of an appeal to authority and more of collective wisdom that can continue to evolve.
The danger is that X keeps happening without the story of Y also being passed along; otherwise it turns into the Five Monkeys problem (https://intersol.ca/news/organizational-culture-and-the-5-mo...).
I'm not disagreeing with the author's friend's point. But at least if there's a story attached to the practice, then it's less of an appeal to authority and more of collective wisdom that can continue to evolve.
Sometimes those historically best practices become outdated but clung onto as doctrine by programmers who let experience get in the way of evolution.
What may have been true 10 years ago may no longer be accurate or important but is still held up as a best practice today.
If allowed to evolve then we are all good but finding the correct speed of evolution (and helping everyone evolve at a similar speed) is harder than ideal. Flip-side of that is the organization or programmer that blindly chases the new.
What may have been true 10 years ago may no longer be accurate or important but is still held up as a best practice today.
If allowed to evolve then we are all good but finding the correct speed of evolution (and helping everyone evolve at a similar speed) is harder than ideal. Flip-side of that is the organization or programmer that blindly chases the new.
There are people on both side arguing that "best practices" are good and bad. But that's not the point.
Best practices are necessary. The value of "best practices" rests not on whether it is good. Its value is that there is an enforced standard across a business/organization. The existence of a standard (and recommended way) helps smooth out the execution/operation. In software engineering, that means easier refactoring, easier migration, easier tooling development, easier training, easier for people to move around within an organization instead of moving out...
I'd recommend any organization to find, install and periodically improve their "best practices". Just the virtue of their existence is a net positive to the business.
Best practices are necessary. The value of "best practices" rests not on whether it is good. Its value is that there is an enforced standard across a business/organization. The existence of a standard (and recommended way) helps smooth out the execution/operation. In software engineering, that means easier refactoring, easier migration, easier tooling development, easier training, easier for people to move around within an organization instead of moving out...
I'd recommend any organization to find, install and periodically improve their "best practices". Just the virtue of their existence is a net positive to the business.
>How can Software Engineers call themselves engineers
I always wondered the same thing, even now, az a so-called Lead Software Engineer. Frankly I call myself a programmer and that's it, maybe a "manager of sorts" now that I'm a "lead". I don't want to assume what others are doing, maybe engineering level work, but I'm rather an overpriced jack of all trades myself, who happened to have a nicely paying trade as a hobby, and an agreeable personality to sell it.
Architect is another glorified software position. Millenia of architects pushing the limits of human technology, often bearing huge responsibility for their plans, just so that later I can come in, advise my client to use the AWS vendor lock-in vehicle, and call myself an architect.
I always wondered the same thing, even now, az a so-called Lead Software Engineer. Frankly I call myself a programmer and that's it, maybe a "manager of sorts" now that I'm a "lead". I don't want to assume what others are doing, maybe engineering level work, but I'm rather an overpriced jack of all trades myself, who happened to have a nicely paying trade as a hobby, and an agreeable personality to sell it.
Architect is another glorified software position. Millenia of architects pushing the limits of human technology, often bearing huge responsibility for their plans, just so that later I can come in, advise my client to use the AWS vendor lock-in vehicle, and call myself an architect.
Are there not also mediocre traditional architects? Why are you comparing architects that push the boundaries of human achievment with the most mediocre of software architects who just advise people use AWS?
Words change over time and it's not like programmers AREN'T pushing the limits of human technology. What is much more advanced than your cellphone right now? Or the software that drives the Super Colliders? Or the software that runs an MRI?
I agree that our industry mis-appropriates the title "Engineer", but there is no reason to be so dismissive either.
Words change over time and it's not like programmers AREN'T pushing the limits of human technology. What is much more advanced than your cellphone right now? Or the software that drives the Super Colliders? Or the software that runs an MRI?
I agree that our industry mis-appropriates the title "Engineer", but there is no reason to be so dismissive either.
Right now I am working on converting a front end application written in angualar/typescript using a monorepo technology called nx.dev into a micro-frontend architecture. All the teams that have been contributing code to the project never bothered to use nx in the way that it was intended and disabled linting for the entire project. The thing is if people had followed the linting rules it would have made my life 1000x times easier because now I have to take a scalpel to the monolith they've made and break it down into smaller parts. Linting rules would have told them to respect module boundaries and warned about circular dependencies. Now I have to clean up the mess.
That falls clearly into one of my best practices 'look at the logs they are trying to tell you something'. But like all 'best practices' it can be take too far. So now you have tons of logging but can not actually tell what is going on because there is too much noise.
I had something similar once I turned up all the logging on all the projects under my control. Suddenly 'there are tons of errors'. 'Yeah they were there the whole time because we ignored them'. Sort of like what happened with linux earlier this year. Turned up logging and suddenly everything is broken. It already is broken. You have just been ignoring it.
I had something similar once I turned up all the logging on all the projects under my control. Suddenly 'there are tons of errors'. 'Yeah they were there the whole time because we ignored them'. Sort of like what happened with linux earlier this year. Turned up logging and suddenly everything is broken. It already is broken. You have just been ignoring it.
There's all kinds of non mission-critical software that gets made with little life/death consequence on how it gets made. There doesn't seem to be the same notion of the "bridge that barely stands" in software either since compute power can be thrown at something way cheaper than a rewrite. Thus, when it comes to the people that make software, there's a wild amount of interpretation on what "good" means and here we are.
And if I can opine on your Spring Boot example, unit testing can sometimes be easier for mock purposes if you have a set of interfaces (vs concrete classes) to work with.
And if I can opine on your Spring Boot example, unit testing can sometimes be easier for mock purposes if you have a set of interfaces (vs concrete classes) to work with.
Vernor Vinge uses the term "Programmer-Achaeologist", which feels appropriate to any time we're doing software maintenance. If I'm truly creating something new I'd go with "Software-Alchemist" since the practice feels much more in line with the efforts of alchemists to fumblingly come to grips with actual chemistry than with modern engineering.
After reading about practices at JPL during the development of Curiosity, and the earlier work on Apollo (just two examples) I do think there is such a thing as an engineering practice of software development. I just don't think most of us are using it.
After reading about practices at JPL during the development of Curiosity, and the earlier work on Apollo (just two examples) I do think there is such a thing as an engineering practice of software development. I just don't think most of us are using it.
> the senior engineer had defined every single service class as an interface and then implemented that interface in an actual @Service. The logic from the senior engineer was that the interface represented the “contract” and the class the business logic.
This is mentioned as bad thing, but having service interfaces really helped in a large Java project I worked, where we had to reimplement and extract some important code. Using the interface for the new code made it much simpler to use a radically different implementation, and also made devs think about what the real interface should be, vs just coupling to some implementation.
This is mentioned as bad thing, but having service interfaces really helped in a large Java project I worked, where we had to reimplement and extract some important code. Using the interface for the new code made it much simpler to use a radically different implementation, and also made devs think about what the real interface should be, vs just coupling to some implementation.
There is a large difference between dogmatically declaring that every single service needs an interface, versus just introducing them at the point where you actually need more than one implementation.
I think that's the author's original argument - not that interfaces are bad in of themselves, but that cargo culting is problematic.
Furthermore, starting with an interface oftentimes makes you create the wrong abstraction, however when you have a concrete implementation, in my experience extracting an interface becomes easier to do, though mostly thanks to excellent IDE tooling.
I think that's the author's original argument - not that interfaces are bad in of themselves, but that cargo culting is problematic.
Furthermore, starting with an interface oftentimes makes you create the wrong abstraction, however when you have a concrete implementation, in my experience extracting an interface becomes easier to do, though mostly thanks to excellent IDE tooling.
Exactly, it would've made total sense to pull it out into an interface in other situations, but simply felt like a preference here.
I agree with the author, but saying "best practice" in a group discussion is frequently used to make someone's position sound more official. "Industry standard" gets used the same way. Some people think that saying these things is like pressing an "I get what I want" button.
I have to fight the urge to ask for citations whenever I see someone pull out one of these chestnuts. Rather than be contentious, I just think about whether or not their argument needs the extra oomph of authority that they're trying to give it. My hope is that not rewarding disingenuity reduces its power.
I have to fight the urge to ask for citations whenever I see someone pull out one of these chestnuts. Rather than be contentious, I just think about whether or not their argument needs the extra oomph of authority that they're trying to give it. My hope is that not rewarding disingenuity reduces its power.
This is a pet peeve of mine, but it’s so ingrained into dev culture that it seems impossible to stop. We could have a little bit of intellectual integrity and at least say “good” instead of “best” but we won’t.
We also use it to argue for opinion over empirical data points. E.g., tabs vs spaces. The “best practice” is some arbitrary number of spaces because “alignment”; this ignores entirely a substantial argument for tabs in the form of accessibility—you can make a tab whatever width you want, so if you’re visually impaired you don’t have to modify the code to read it and re-format it to the “best practice”. TLDR; tab indentation followed by space alignment would actually satisfy everyone’s needs, but it’s totally off the table because “best practice” is spaces.
We also use it to argue for opinion over empirical data points. E.g., tabs vs spaces. The “best practice” is some arbitrary number of spaces because “alignment”; this ignores entirely a substantial argument for tabs in the form of accessibility—you can make a tab whatever width you want, so if you’re visually impaired you don’t have to modify the code to read it and re-format it to the “best practice”. TLDR; tab indentation followed by space alignment would actually satisfy everyone’s needs, but it’s totally off the table because “best practice” is spaces.
> I was working on a Spring Boot REST API a few months ago and the senior engineer had defined every single service class as an interface and then implemented that interface in an actual @Service. The interfaces weren’t extended by multiple classes, this wasn’t an external library or a dependant, and there were no plans to implement additional classes later.
Reason I avoid working in Java and especially the "senior java engineers".
> The logic from the senior engineer was that the interface represented the “contract” and the class the business logic.
This is basically religious dogma
Reason I avoid working in Java and especially the "senior java engineers".
> The logic from the senior engineer was that the interface represented the “contract” and the class the business logic.
This is basically religious dogma
It doesn't make much sense for people who always heard and thought that "an interface just lists the public methods and properties of a class". In that view the classes always come first and the interfaces are unnecessary boilerplate.
However if instead you assume that "a class is just an implementation of an interface", then everything changes. Now the interfaces come first and classes are required to materialize them. In that paradigm objects only communicate with interfaces, never (or almost never) with other classes unless a specific implementation is required. Which is why an interface is always defined for a class even if there is no plan for other implementations of it.
Rather than a "contract", think of an interface as the description of a job. If you ever need to write a safety procedure, does it make more sense to write "In case of fire, call John; John happens to know how to extinguish a fire." or "In case of fire, call a fireman."? "Fireman" is an interface. "John" is a class implementing that job. It might be the only class in the codebase that implements it, but that is no concern of the caller. They just want that fire dealt with.
However if instead you assume that "a class is just an implementation of an interface", then everything changes. Now the interfaces come first and classes are required to materialize them. In that paradigm objects only communicate with interfaces, never (or almost never) with other classes unless a specific implementation is required. Which is why an interface is always defined for a class even if there is no plan for other implementations of it.
Rather than a "contract", think of an interface as the description of a job. If you ever need to write a safety procedure, does it make more sense to write "In case of fire, call John; John happens to know how to extinguish a fire." or "In case of fire, call a fireman."? "Fireman" is an interface. "John" is a class implementing that job. It might be the only class in the codebase that implements it, but that is no concern of the caller. They just want that fire dealt with.
I am doing this and it helps in mocking the interface in other classes tests.
I've never had the title "Software Engineer". It's always been "Software Developer". And that feels appropriate. I write business software. Nobody dies if it fails. The monetary damages are generally small (in absolute terms) and problems easily rectified (relative to fixing a failed bridge).
I would expect a software engineer to be working on safety-critical systems. Power grid control, military applications, etc. And I hope there's a massive amount more rigor applied to their work than there is to mine.
I would expect a software engineer to be working on safety-critical systems. Power grid control, military applications, etc. And I hope there's a massive amount more rigor applied to their work than there is to mine.
Pretty much. Just averaged over sufficiently large number of devolpers. And since the developers are the one that the code is read by then it's perfectly reasonable.
There are probably a ton of definitions of what a best practice is in SE.
When it comes to code, I like to think best practices are those that make code easier to change and understand, without significantly compromising performance.
Developers who mainly target high performance with their code probably think my best practices suck, and so on.
At a practical level, what really matters is consensus within an organization. Organizations where people hold incompatible ideas of what good engineering is are basically doomed.
When it comes to code, I like to think best practices are those that make code easier to change and understand, without significantly compromising performance.
Developers who mainly target high performance with their code probably think my best practices suck, and so on.
At a practical level, what really matters is consensus within an organization. Organizations where people hold incompatible ideas of what good engineering is are basically doomed.
A LOT of coding style, abstraction style, function vs inline is just preferences. This is what makes code reviews hard. Both the author and reviewer can easily fall into the trap of trying to "correct" the other person - without realizing that they are merely forcing preferences on the other.
That said, it is ok to write down some preferences as a team/org standard that everyone can follow.
Just don't make the job a lawyers attempt at software engineering.
That said, it is ok to write down some preferences as a team/org standard that everyone can follow.
Just don't make the job a lawyers attempt at software engineering.
> At the end of the day, you wind up in a lot of fairly pointless arguments about tech stack and coding conventions that 99.9% of the time don’t make a bit of difference to the final product.
99.9% of the time they do, maybe you don't see them functionally and visually, but probably you aren't measuring security flaws, performance and specially ease of maintenance which goes unnoticed most of the time...
99.9% of the time they do, maybe you don't see them functionally and visually, but probably you aren't measuring security flaws, performance and specially ease of maintenance which goes unnoticed most of the time...
Software engineering seems partially creative partially technical - so on the creative parts, yes absolutely teams should self define their preferences. Scrum vs agile vs whatever else IMO should be a team/org preference. However like someone else said some engineering has to be liable for criminal prosecution in some cases. So you need some practices to be enforced.
Sure, so who defines which parts are highly technical? We can all be in agreement that things like cryptography should use well known and vetted libraries, whereas something like a REST API interface can be a little more relaxed with adherence to a standard, but where do we draw the line?
I do not want to live in a world where my code must conform to a Java Bean factory class. I align more with the skunkworks style of development.
I once work on contract on a project where everything was abstracted to hell and back. We spent 90% of our time trying to figure out where references pointed to in the code. Never again.
I do not want to live in a world where my code must conform to a Java Bean factory class. I align more with the skunkworks style of development.
I once work on contract on a project where everything was abstracted to hell and back. We spent 90% of our time trying to figure out where references pointed to in the code. Never again.
It’s a difficult question and I’m not qualified to answer it as an amateur tbh.
Some certainly are, many are not.
To discern the two is very easy. You write a piece of code. If someone else or even yourself can still understand it after a month, then you're practicing the "best practices".
Whereas, if you don't follow some "best practices" and they're still clear to others, they are just "developer preferences".
To discern the two is very easy. You write a piece of code. If someone else or even yourself can still understand it after a month, then you're practicing the "best practices".
Whereas, if you don't follow some "best practices" and they're still clear to others, they are just "developer preferences".
Right, but your definition of discernment is itself a preference for readability over conciseness. Another developer could say "if it works a month or a year later, then you're practicing a best practice."
"Standards" cover what the system does. "Best practices" cover how it's done.
Best practices (generally opinions based on reasoning): language choice, KISS/DRY/YAGNI, linter rules, unit tests, static vs dynamic linking.
Standards (de-facto, at least): ISO, RFCs, PCI, and whatever is relevant for the industry the solution is for.
Best practices (generally opinions based on reasoning): language choice, KISS/DRY/YAGNI, linter rules, unit tests, static vs dynamic linking.
Standards (de-facto, at least): ISO, RFCs, PCI, and whatever is relevant for the industry the solution is for.
"best practices" = "common practices" in practice.
Not necessarily best. Best practices you get when you apply a darwinian approach in your org and try out several techniques before selecting the best. What is called best practices too often is a name for "we've done it this way since the beginning".
Not necessarily best. Best practices you get when you apply a darwinian approach in your org and try out several techniques before selecting the best. What is called best practices too often is a name for "we've done it this way since the beginning".
[deleted]
> My housemate the other day asked me something to the effect of “How can Software Engineers call themselves engineers when there’s no rules, governing bodies, or anything to stipulate what true Software Engineering is?”
There sure is, that is what countries that have Professional Engineering titles have.
There sure is, that is what countries that have Professional Engineering titles have.
I'd say that a lot of devs do have a hard time distinguishing "best practices" vs "the way I like to code". It's also tough because many of the motivated devs who can push these initiatives through need help with the sometimes subtle difference.
As someone who has a liberal arts background, software engineering has a lot more in common with writing than most admit. Sure there is grammar and syntax but good writing can be as varied from William Shakespeare to Stephen King. Same with software writing.
Software engineering best practices are stuff like version control and automated tests. Many teams still don't have those and they ought to have them. "Squashing commits" isn't an example of best practice even if some people try to say that.
In contradiction with the first paragraph, there are definitely fields of software engineering with external regulation, auditors, etc. I'm thinking of the banking sector and realtime critical software, like in avionics and such.
Yeah, I told him that, but by and large most developers don't work on those problems.
> Are Software Engineering “best practices” just developer preferences?
Some are, some aren't. Some are good practices but the state of the art evolves and better practices are uncovered.
And it's really had to tell the differences. it's a young field.
Some are, some aren't. Some are good practices but the state of the art evolves and better practices are uncovered.
And it's really had to tell the differences. it's a young field.
I've always used "best practices" as a nicer way of saying "commonly accepted". It's not really developer preferences -- there are a number of best practices that I don't prefer as a developer.
it feels like though, whats "commonly accepted" changes quite rapidly though doesnt it?
i think we probably need a more rigorous definition or else people will keep using "best practice" to justify what is actually a preference, and i think thats where conflicts start to happen within teams/orgs.
i think we probably need a more rigorous definition or else people will keep using "best practice" to justify what is actually a preference, and i think thats where conflicts start to happen within teams/orgs.
I don't think that it's changed that much over the decades of my career, really. The words used change, but the concepts seem reasonably stable.
New batches of commonly accepted practices come into play with new technologies, though, and most of the "hot" technologies today are still so new that the "accepted practices" unique to them have still not settled down. So, yes, in that space, they change rapidly because they don't yet really exist.
New batches of commonly accepted practices come into play with new technologies, though, and most of the "hot" technologies today are still so new that the "accepted practices" unique to them have still not settled down. So, yes, in that space, they change rapidly because they don't yet really exist.
IIRC, the book Code Complete talks about best practices and contains links to studies when they apply to those practices. I might be wrong, it's been a while since I read the book and I can't get to it right now.
[deleted]
Having an interface for a single implementation is just redundant. A class already has an interface - it's public API.
Other than that I agree, most "best practices" are subjective and boil down to personal preference.
Other than that I agree, most "best practices" are subjective and boil down to personal preference.
Having an interface let's you introduce versions or alternative implementations easily, this is important in a long run. It's much easier to handle the transitions, because you can have both versions in your code base and you can easily switch back to the old one if necessary. When you start with a class and you want to do similar thing, you either YOLO it and change everything at once, or you need to introduce an interface and replace every usage to use the interface to achieve a safer transition and you are back at the interface-class implementation with an extra pain.
Interfaces serve two roles:
1. They are (usually) concise specification/contract for the implementation to follow, and for the client to use.
2. They permit substitution.
These are, from my experience, the principle and most useful reasons to make use of "redundant" interface definitions. What's worse is when people want alternative implementations but only have a concrete instance, they subclass it and break all kinds of contracts making their square peg fit a round hole.
This is less useful when you have ducktyping and consequently every lookalike is considered substitutable for each other.
1. They are (usually) concise specification/contract for the implementation to follow, and for the client to use.
2. They permit substitution.
These are, from my experience, the principle and most useful reasons to make use of "redundant" interface definitions. What's worse is when people want alternative implementations but only have a concrete instance, they subclass it and break all kinds of contracts making their square peg fit a round hole.
This is less useful when you have ducktyping and consequently every lookalike is considered substitutable for each other.
I usually agree but sometimes you want to reduce the exposure of the public methods of the concrete class even if there's only one concrete implementer.
For example, you might want to pass around a class and only expose the getters and not the setters.
For example, you might want to pass around a class and only expose the getters and not the setters.
> Having an interface for a single implementation is just redundant. A class already has an interface - it's public API.
Depends on the language.
And sometimes you want to enforce a public contract of any implementation (current and future).
Personally for me, the biggest gain I see when writing against interfaces is that any class which expects a interface is already prepared for test-doubles, as opposed to classes written against concrete implementations which may even be initialised internally. Then just even starting to write a test becomes a so much bigger task.
Of course, everything with moderation, sometimes even moderation itself ;)
Depends on the language.
And sometimes you want to enforce a public contract of any implementation (current and future).
Personally for me, the biggest gain I see when writing against interfaces is that any class which expects a interface is already prepared for test-doubles, as opposed to classes written against concrete implementations which may even be initialised internally. Then just even starting to write a test becomes a so much bigger task.
Of course, everything with moderation, sometimes even moderation itself ;)
I feel like the responses to this comment are somewhat proving the point around most things being preference. ;)
Codified Software Best Practices have been around for decades.
Steve McConnell (Code Complete, Rapid Development, etc.)[0] used to be the Best Practices Editor for the IEEE.
It’s just as the author mentioned; no teeth. Companies are happy to pay for slapdash work (thus, undermining the drive to do good work), and employment tests often don’t really have much bearing on real-world engineering.
I’ve spent decades refining techniques and habits that I think work quite well. I occasionally write them down[1], which I find helpful in understanding them better.
[0] https://stevemcconnell.com/
[1] https://littlegreenviper.com/miscellany/
Steve McConnell (Code Complete, Rapid Development, etc.)[0] used to be the Best Practices Editor for the IEEE.
It’s just as the author mentioned; no teeth. Companies are happy to pay for slapdash work (thus, undermining the drive to do good work), and employment tests often don’t really have much bearing on real-world engineering.
I’ve spent decades refining techniques and habits that I think work quite well. I occasionally write them down[1], which I find helpful in understanding them better.
[0] https://stevemcconnell.com/
[1] https://littlegreenviper.com/miscellany/
Engineering is the wrong classification. I think the problem is it's new enough that people try to relate it to other disciplines. Coding is just its own thing.
I consciously use good practices as it leaves the door open to discussion and is not a strong appeal to authority.
The other one I’m not a fan is industry standard practice.
The other one I’m not a fan is industry standard practice.
[deleted]
If the entire Object Oriented and design patterns and Martin Fowler fan boys could read, they would be very angry.
Is there really a difference, if more friction for developers == less productivity, less happy developers, and so on?
Best practices create a shared experience that can help get you out of trouble when that practice was a bad decision.
It’s best practice to apply best practices when it makes sense.
The catch? Knowing when it makes sense requires experience ;)
The catch? Knowing when it makes sense requires experience ;)
I can't imagine someone arguing that avoiding tight coupling is a personal preference.
I can.
I currently work on a project that has about 1M SLoC in Java. Approximately 95% of the classes that have the @Service annotation are tightly coupled at the time of writing this. Yet, there are no issues with this approach.
Why? Because loose coupling is a nuisance if introduced at the expense of more code, which is how interfaces are currently done in Java, as opposed to them being implicit, based on implemented methods within a class, like Go does it.
In about 5% of the cases, we need more than one implementation and introduce an interface. In all the others, we don't. Now, what would happen if every single service would have an interface in front of it? The codebase would become far larger and it'd become more cumbersome to alter it.
Furthermore, IDE refactoring tools make it a non-issue - just choose which methods you want in your interface and create one, doing so at the point where you are clear about which methods are implementation specific and which aren't. Most smart tools will even offer you to replace your concrete classes with interfaces where possible.
I currently work on a project that has about 1M SLoC in Java. Approximately 95% of the classes that have the @Service annotation are tightly coupled at the time of writing this. Yet, there are no issues with this approach.
Why? Because loose coupling is a nuisance if introduced at the expense of more code, which is how interfaces are currently done in Java, as opposed to them being implicit, based on implemented methods within a class, like Go does it.
In about 5% of the cases, we need more than one implementation and introduce an interface. In all the others, we don't. Now, what would happen if every single service would have an interface in front of it? The codebase would become far larger and it'd become more cumbersome to alter it.
Furthermore, IDE refactoring tools make it a non-issue - just choose which methods you want in your interface and create one, doing so at the point where you are clear about which methods are implementation specific and which aren't. Most smart tools will even offer you to replace your concrete classes with interfaces where possible.
Or lowest common denominator, stuff you want get in trouble for doing, pablum?
Are civil engineering "best practices" just legal preferences?
One of the books I picked up to settle an argument about best practices once...
A Practical Guide for Policy Analysis by Eugene Bardach. ( https://us.sagepub.com/en-us/nam/a-practical-guide-for-polic... ) and https://en.wikipedia.org/wiki/Eightfold_path_(policy_analysi...
Legal practices often follow from established best practices rather than the other way around.
There are many practices that solve a problem. Some of them have an intrinsic "better" to them. Of those, when trying to solve a problem you look at all of them. The one that fits your needs best is then the best practice.
> Don't be mislead by the word best in so-called best practices research. Rarely will you have any confidence that some helpful-looking practice is actually the best among all those that address the same problem or opportunity. The extensive and careful research needed to document a claim of best will almost never have been done. Usually, you will be looking for what, more modestly, might be called "good practices."
A Practical Guide for Policy Analysis by Eugene Bardach. ( https://us.sagepub.com/en-us/nam/a-practical-guide-for-polic... ) and https://en.wikipedia.org/wiki/Eightfold_path_(policy_analysi...
Legal practices often follow from established best practices rather than the other way around.
There are many practices that solve a problem. Some of them have an intrinsic "better" to them. Of those, when trying to solve a problem you look at all of them. The one that fits your needs best is then the best practice.
> Don't be mislead by the word best in so-called best practices research. Rarely will you have any confidence that some helpful-looking practice is actually the best among all those that address the same problem or opportunity. The extensive and careful research needed to document a claim of best will almost never have been done. Usually, you will be looking for what, more modestly, might be called "good practices."
They are built on top of a ocean of blood
It’s called “building code”.
It doesn't really matter to me...
(as long as tabs stops/indent are 4)
(as long as tabs stops/indent are 4)
I'm pretty sure that most people consider "software engineer" to be just a fake title that makes business cards look fancier... sort of like referring to a janitor/custodian as a "sanitation engineer".
The phrase “best practice” is a sure fire way to signal “I don’t know what I’m talking about.” A lot of times these best practices are really good ideas. But misapplying them by rote can be more dangerous than ignoring them.
No, they are management's developer preferences.
Without empirical evidence, who knows what they are?
There are no solutions, only tradeoffs
best practices are programming style convergence, which helps estimating software in my opinion.
The answer is not binary.
The answer is not binary
I am all against standards and engineering boards defining what is right and what is wrong, but at the same time I also favor software developers being held civil and criminal responsibilities for the outcome of their work. It is pretty hard to have the second without the first, so here I am at a crossroads.
"The parallel he drew was to another friend who’s a Civil Engineer. His friend had to be state certified and build everything to certain codes that stand up to specific stressors and inspections.
I gave him the usual answer about how Software Engineers deal with low stakes and high iterability compared to Civil Engineers, but, honestly, he has a point."
I've argued for awhile now that Software Engineering with a big E should be licensed and regulated the same as any other Engineering discipline. Not all software is low stakes and fast changing. In fact I'd argue the most important software is never that. software for control systems, avionics, cars etc are very high stakes and have no reason to iterate beyond what is needed to interface with changing hardware. I think if software engineers had to be licensed to work on such things then those 737s wouldn't have fallen out of the sky and Tesla wouldn't be allowed to beta test self driving cars on public roads.
To those who ask what do you now call software engineers who don't work on those things, you are programmers. Or if you prefer a less formal term, coders. Engineer is a powerful word and I don't like how the we the IT industry have appropriated it for less critical tasks.
I gave him the usual answer about how Software Engineers deal with low stakes and high iterability compared to Civil Engineers, but, honestly, he has a point."
I've argued for awhile now that Software Engineering with a big E should be licensed and regulated the same as any other Engineering discipline. Not all software is low stakes and fast changing. In fact I'd argue the most important software is never that. software for control systems, avionics, cars etc are very high stakes and have no reason to iterate beyond what is needed to interface with changing hardware. I think if software engineers had to be licensed to work on such things then those 737s wouldn't have fallen out of the sky and Tesla wouldn't be allowed to beta test self driving cars on public roads.
To those who ask what do you now call software engineers who don't work on those things, you are programmers. Or if you prefer a less formal term, coders. Engineer is a powerful word and I don't like how the we the IT industry have appropriated it for less critical tasks.
In a way there are standards for software but those standards are not expressed in software terms.
Firstly, most software is harmless. If it goes wrong people may be annoyed, but no one is harmed. But if I write software to control an aircraft, then it would have to abide by aviation standards. If I write financial software then I would have financial regulations to follow. Same for medical devices. So, there are standards for software but they are indirect and expressed in terms of the wider domain in which it runs.
Firstly, most software is harmless. If it goes wrong people may be annoyed, but no one is harmed. But if I write software to control an aircraft, then it would have to abide by aviation standards. If I write financial software then I would have financial regulations to follow. Same for medical devices. So, there are standards for software but they are indirect and expressed in terms of the wider domain in which it runs.
While that's true, those standards don't really fully account for the needs of proper software engineering practices IMO. You can say aircraft code follow aerospace standards yet those standards didn't stop Boeing from making a system that overrode pilot input while only relying on two sensors. It also didn't stop Boeing from launching a space capsule that didn't have the thrusters mapped properly. Nor did it prevent Lockheed from shipping GPS code that caused the navigation system of the F-22 from crashing when it crossed the international dateline. Standards and norms aren't the same thing as a building code. Civil Engineers have a code they must meet at minimum for the things they build. There are ways that certain things must be done and they have to sign off on every project. We don't see that with equally important software. For some reason if a bridge collapses and it was found that it was designed wrong the engineer goes to jail but if a plane crashes because its autopilot had design flaws the developer doesn't.
Critical systems: https://en.wikipedia.org/wiki/Critical_system :
> There are four types of critical systems: safety critical, mission critical, business critical and security critical.
Safety-critical systems > "Software engineering for safety-critical systems" https://en.wikipedia.org/wiki/Safety-critical_system#Softwar... :
> By setting a standard for which a system is required to be developed under, it forces the designers to stick to the requirements. The avionics industry has succeeded in producing standard methods for producing life-critical avionics software. Similar standards exist for industry, in general, (IEC 61508) and automotive (ISO 26262), medical (IEC 62304) and nuclear (IEC 61513) industries specifically. The standard approach is to carefully code, inspect, document, test, verify and analyze the system. Another approach is to certify a production system, a compiler, and then generate the system's code from specifications. Another approach uses formal methods to generate proofs that the code meets requirements.[11] All of these approaches improve the software quality in safety-critical systems by testing or eliminating manual steps in the development process, because people make mistakes, and these mistakes are the most common cause of potential life-threatening errors.
awesome-safety-critical lists very many resources for safety critical systems: https://awesome-safety-critical.readthedocs.io/en/latest/
There are many ['Engineering'] certification programs for software and other STEM fields. One test to qualify applicants does not qualify as a sufficient set of controls for safety critical systems that must be resilient, fault-tolerant, and redundant.
A real Engineer knows that there are insufficient process controls from review of very little documentation; it's just process wisdom from experience. An engineer starts with this premise: "There are insufficient controls to do this safely" because [test scenario parameter set n] would result in the system state - the output of probably actually a complex nonlinear dynamic system - being unacceptable: outside of acceptable parameters for safe operation.
Are there [formal] Engineering methods that should be requisite to "Computer Science" degrees? What about "Applied Secure Coding Practices in [Language]"? Is that sufficient to teach theory and formal methods?
From "How We Proved the Eth2 Deposit Contract Is Free of Runtime Errors" https://news.ycombinator.com/item?id=28513922 :
>> From "Discover and Prevent Linux Kernel Zero-Day Exploit Using Formal Verification" https://news.ycombinator.com/item?id=27442273 :
>> [Coq, VST, CompCert]
>> Formal methods: https://en.wikipedia.org/wiki/Formal_methods
>> Formal specification: https://en.wikipedia.org/wiki/Formal_specification
>> Implementation of formal specification: https://en.wikipedia.org/wiki/Anti-pattern#Software_engineer...
>> Formal verification: https://en.wikipedia.org/wiki/Formal_verification
>> From "Why Don't People Use Formal Methods?" https://news.ycombinator.com/item?id=18965964 :
>>> Which universities teach formal methods?
>>> - q=formal+verification https://www.class-central.com/search?q=formal+verification
>>> - q=formal+methods https://www.class-central.com/search?q=formal+methods
>>> Is formal verification a required course or curriculum competency for any Computer Science or Software Engineering / Computer Engineering degree programs? https://news.ycombinator.com/item?id=28513922
From "Ask HN: Is it worth it to learn C in 2020?" https://news.ycombinator.com/item?id=21878372 :
> There are a number of coding guidelines e.g. for safety-critical systems where bounded running time and resource consumption are essential. These coding guidelines and standards are basically only available for C, C++, and Ada.
awesome-safety-critical > Software safety standards: https://awesome-safety-critical.readthedocs.io/en/latest/#so...
awesome-safety-critical > Coding Guidelines: https://awesome-safety-critical.readthedocs.io/en/latest/#co...
> There are four types of critical systems: safety critical, mission critical, business critical and security critical.
Safety-critical systems > "Software engineering for safety-critical systems" https://en.wikipedia.org/wiki/Safety-critical_system#Softwar... :
> By setting a standard for which a system is required to be developed under, it forces the designers to stick to the requirements. The avionics industry has succeeded in producing standard methods for producing life-critical avionics software. Similar standards exist for industry, in general, (IEC 61508) and automotive (ISO 26262), medical (IEC 62304) and nuclear (IEC 61513) industries specifically. The standard approach is to carefully code, inspect, document, test, verify and analyze the system. Another approach is to certify a production system, a compiler, and then generate the system's code from specifications. Another approach uses formal methods to generate proofs that the code meets requirements.[11] All of these approaches improve the software quality in safety-critical systems by testing or eliminating manual steps in the development process, because people make mistakes, and these mistakes are the most common cause of potential life-threatening errors.
awesome-safety-critical lists very many resources for safety critical systems: https://awesome-safety-critical.readthedocs.io/en/latest/
There are many ['Engineering'] certification programs for software and other STEM fields. One test to qualify applicants does not qualify as a sufficient set of controls for safety critical systems that must be resilient, fault-tolerant, and redundant.
A real Engineer knows that there are insufficient process controls from review of very little documentation; it's just process wisdom from experience. An engineer starts with this premise: "There are insufficient controls to do this safely" because [test scenario parameter set n] would result in the system state - the output of probably actually a complex nonlinear dynamic system - being unacceptable: outside of acceptable parameters for safe operation.
Are there [formal] Engineering methods that should be requisite to "Computer Science" degrees? What about "Applied Secure Coding Practices in [Language]"? Is that sufficient to teach theory and formal methods?
From "How We Proved the Eth2 Deposit Contract Is Free of Runtime Errors" https://news.ycombinator.com/item?id=28513922 :
>> From "Discover and Prevent Linux Kernel Zero-Day Exploit Using Formal Verification" https://news.ycombinator.com/item?id=27442273 :
>> [Coq, VST, CompCert]
>> Formal methods: https://en.wikipedia.org/wiki/Formal_methods
>> Formal specification: https://en.wikipedia.org/wiki/Formal_specification
>> Implementation of formal specification: https://en.wikipedia.org/wiki/Anti-pattern#Software_engineer...
>> Formal verification: https://en.wikipedia.org/wiki/Formal_verification
>> From "Why Don't People Use Formal Methods?" https://news.ycombinator.com/item?id=18965964 :
>>> Which universities teach formal methods?
>>> - q=formal+verification https://www.class-central.com/search?q=formal+verification
>>> - q=formal+methods https://www.class-central.com/search?q=formal+methods
>>> Is formal verification a required course or curriculum competency for any Computer Science or Software Engineering / Computer Engineering degree programs? https://news.ycombinator.com/item?id=28513922
From "Ask HN: Is it worth it to learn C in 2020?" https://news.ycombinator.com/item?id=21878372 :
> There are a number of coding guidelines e.g. for safety-critical systems where bounded running time and resource consumption are essential. These coding guidelines and standards are basically only available for C, C++, and Ada.
awesome-safety-critical > Software safety standards: https://awesome-safety-critical.readthedocs.io/en/latest/#so...
awesome-safety-critical > Coding Guidelines: https://awesome-safety-critical.readthedocs.io/en/latest/#co...
But really, "best" and "right" are highly situational. Any rule of thumb, even the most basic and uncontroversial, has a situation where it doesn't apply. I was part of a discussion on a mailing list years ago, where somebody got flamed harshly when he mentioned using a global variable. He then explained that he was working on an embedded control system for cars and all the variables in that system were global. The team was well aware of the pitfalls of global state and used a combination of documentation, static analysis, custom tooling and elaborate testing to mitigate them. It was a considered design choice that made it possible to develop high-performance, hard-realtime software that could run on very limited hardware.