💾 Archived View for slashbinbash.de › software-development.gmi captured on 2022-01-08 at 14:05:22. Gemini links have been rewritten to link to archived content

View Raw

More Information

➡️ Next capture (2022-06-03)

-=-=-=-=-=-=-

Opinions on Software Development

I spend quite some time reading about software development and the experiences that people have when working as programmers. Since it is such a broad field, people have very different views on it. I'm always tempted to write my opinions on public forums but I feel like I would be wasting my time. Discussions online are never really productive.

What follows are my personal opinions on different software development topics that I care about.

False Assumptions: The Root of all Evil?

In my experience, false assumptions are one of the most common mistakes that lead to bugs. False assumptions creep up everywhere, especially along abstractions and interfaces.

It starts with the requirements that the customer has. The requirements can already be based on false assumptions about the problem that they are trying to solve. We then take these requirements and try to translate them into software functions. If you are not familiar with the problem domain, you are very likely to make mistakes. Problem domains usually have their own language and terminology. There is a lot of room for assumptions to creep in.

Next we have programming languages. If you are learning C++, you might have false assumptions about how memory management works. You might assume that variables are initialized by default to a sensible value, which is not the case. You might have assumptions about string representations or floating-point number representations that are wrong. If you don't question your assumptions, you will produce bugs and issues that can be very hard to trace later on.

It continues with the frameworks and libraries that we use. It's normal to assume the correctness of a library function. It's problematic to assume that a function always returns a certain value, or that a function returns a value based on another function's behavior. It's also problematic to assume different behavior than what was specified by the function implementation. For instance, in Java, you cannot reliably compare two strings with the equality-operator. It's a very easy mistake to make!

Then we have the operating system. In most cases this is a black box that can change its behavior depending on the version of its APIs, drivers, libraries, and the overall configuration of the system. Since there are also other programs that are running parallel to yours, your program will be affected by the scheduler and hardware interrupts. You can make a guess what the most likely outcome of your software running on the operating system will be, but that's about it.

It's not uncommon nowadays that there are also virtual machines running at some level of the system, be it the Java Virtual Machine or some hypervisor. Unless you are intimately familiar with the VMs, you better throw out any assumptions that you have about how they operate.

Last but not least, we have the hardware. If you've never read about how modern CPUs work, all your assumptions are probably wrong. The assumption that the CPU actually executes what you've written, in the order that you have written it, is mostly false. The only guarantee is that the observable result of the computation is what you would expect. And even then, hardware can have bugs and defects, too.

If you have wrong assumptions, you cannot make any kind of reliable prediction about how your code will behave. Thus, I would argue that it's key to minimize the amount of assumptions that you have to make about the system. Then you should question and test if your assumptions are true. If there is any kind of doubt, it's better to admit it, and to try to find a reliable answer, instead of basing your work on false assumptions.

What programming language should I learn?

Most people who have worked in the software industry for a couple of years know at least three or four programming languages. This is why I want to reframe the question a little bit.

I put languages into three categories:

It's rare that you find one language that fits into all three categories. If this is you, I'd be curious to hear which field you work in, and what programming language it is.

Should I make my project open-source?

I have a somewhat reserved opinion about open-source.

In my opinion, there are only a few types of projects that need to be open-source.

I think that's about it. That's not to say that you shouldn't make your project open-source. Especially if you want to join and contribute to the open-source community.

I deliberately chose not to make my personal projects open-source, because they don't contribute anything worthwhile. And even if they did, I don't want the responsibility of having to maintain public code, deal with pull requests, and provide appropriate documentation. I just don't have the time to do that, and I don't expect any strangers to do it for me.

I also think that if you are doing something that is worthwhile, you should consider applying your skills in an environment where you are adequately compensated for your work. This doesn't mean that the outcome can't be open-source.

Resourcefulness and Optimization

I'm frustrated about software developers who have no regard for efficient resource management. The bloated and slow software that we have today, is a result of the industry and academia failing to address the cost of computing.

The truth is that every memory that you allocate, every function that you call, every thread that you create, every file that you open, every framework that you use, has a certain cost attached to it. This cost might seem insignificant to you, but it is not zero. You should always consider the performance and memory implications of your algorithms.

Considering the performance and memory implications of your algorithms is not premature optimization. It's good design! Making optimizations based on false assumptions, that's where people make mistakes. But that goes for software development in general. If you don't have a complete understanding of the problem, it's easy to make mistakes.

Writing resource efficient code is also made more difficult by the fact that there are so many layers of abstractions between the software developer and the hardware nowadays. I'd argue that many software developers enter the industry with a wrong model of what the computer is doing when it's executing their code, and I don't blame them. The systems on which we develop software are neither trivial, nor are they easy to predict.

The least that I expect from a software developer, is that they don't shrug off matters of performance, and instead search for solutions that strike a good balance between the resources that are required to run the program, and the benefit that they deliver to the user (or society in general).

In my opinion, one of the worst offenders in this regard is the mining of cryptocurrency. I like cryptocurrency as a concept, but its implementation must be one of the most inefficient ways to create value. It is burning through physical resources like there's no tomorrow, while only being useful to a small group of people.

Creativity in Software Development

I think there might be a misconception when it comes to creativity in software development. What we need are developers that solve difficult problems in creative ways. What we don't need are developers who write code in creative ways.

Why do I say this? There are developers who are heavily invested in writing beautiful or elegant code (whatever that means), using design patterns wherever they can, trying to showing off their skills in the code that they write. I've been through such a phase and I think it was misguided. Too much emphasis is put on gurus in the industry. They spawn hundreds of courses and books about their methods, giving the impression that their way is the right way. This leads to developers who blindly follow rules instead of thinking for themselves.

The truth is that most of it are just guidelines and best practices. Even senior developers have biases and may hold opinions based on assumptions that are not true anymore - technology is changing and always evolving. My experience is that at the end of the day, everyone just does whatever they want. The only exceptions are probably companies whose software could lead to injury or death, if there is a software failure.

Don't be creative when you write code. Write down what the machine has to do, as readable as you can. Try to make your decisions obvious for other readers, so that there's not much room for interpretation and false assumptions. If you can do that while minimizing the dependencies in your code, you are probably already better than the average developer out there.

A Case for Software Engineering

I want to make the case for why and when Software Engineering is a good term to describe what we do. But before I do, I want to quickly mention a few other terms.

Programming is probably the most general term of all. To me, it describes the act of writing computer instructions and running the program to see that the computer does what it is supposed to do. However, it doesn't really convey all the other activities that are required to actually ship software to customers.

Software Development is a broadly accepted term that encompasses the design, development, release, and maintenance of a software product. It also implies that you work with other people to deliver something that fulfills the requirements of the customer. This often means that you have to acquire knowledge about the problem domain - you can't write music notation software without understanding what i.e. time and key signatures are, or what the parts of an orchestra are.

Software Craftsmanship is another term that is used by the community. The idea is related to craftsmanship in the traditional sense, that developing software is akin to the skill that you acquire in a trade like carpentry, where you start as an apprentice and work your way to becoming a master. It's used by the community to describe a certain set of principles and methods that speak for the skill, responsibility, and professionalism of the individual. I think it's a very noble approach and a totally valid view on the work that we do.

Software Engineering implies that creating software is akin to building bridges, or constructing a hospital. I think that there are cases in which this is true. We have language standards like the C++ ISO standard that we have to consider while developing software. We have to make decisions regarding software architecture, i.e. what are the different systems in our solution, and how do they operate and communicate with each other. We have frameworks that lay out the fundamental structure of the software. We have hardware specifications and requirements that we need to consider. We make predictions about how the software may operate, and do risk analysis. Rigorous testing is done when software needs to be reliable and robust. Security aspects have to be considered when software failure may result in injury or death.

I guess in the end, you have to make up your own mind. I see myself a software developer, I aspire to be a software engineer, but I'm not offended when someone calls me a programmer, because I love programming.