Software development often has an almost infinite number of ways to accomplish the same task.
Maintainability is as much, if not more, about correctly predicting the future uses and requirements of the software as it is about the initial coding practices and design patterns.
Working on older systems that are being used in ways that they were not originally intended is often uncomfortable for a developer. All but the most junior developers tend to have some painful memories of battling legacy software.
These add up to a situation where it is incredibly difficult and vague to determine the correct path. Both because there are so many ways to accomplish the task and because there are so many unknown future contingencies that ultimately determine how maintainable the software will be. Combine that with the painful memories most developers have from nightmare projects and you have yourself a recipe for emotional disagreements all around.
The grand irony is that, very often, once a developer becomes fully aware of this concept, they lose that internal fire and vigilance required to constantly seek out better ways to solve problems and their skills wane.
Any hints to guide one back to the path of passionate problem solving?
What fuels my passion: I try to stick to languages and concepts that are puristic. I loved SmallTalk, which is pure OO (so much more than Java). I love Haskell, which encapsulates a particular style of functional programming quite well. I love LISP, since it represents and embraces metaprogramming quite well. The more a language deviates from these extremes, the less 'thrill' I feel using them. I always try to solve problem with the purest form a paradigm has to offer.
In the real world, I am able and perfectly happy to choose whatever tool fits the need best and adapt to the team. But I will certainly voice my opinions ("This is a planning task - let's not reinvent the wheel - and waste time and fix unnecessary bugs - and just send the data to Prolog and translate the solution back into our program") tho and what I do in my free time is not bounded my industrial needs.
Every paradigm offers a different perspective on programming and is worth exploring. Thankfully I am not genious enough to run out of this particular motivation in my lifetime.
My maxim is "make it as complex as it needs to be, but not one bit more".
There is great satisfaction to be had from productively solving problems rather than endlessly "architecting" in futile search of the "perfect design".
Just my 2 cents!
Also, take a break and do something that is not programming as a hobby. Demotivation is more of function of routine and lack of sensory input and less of practical realities.
Lastly, embrace the concept.
Somewhat incidentally, but I believe this is a large part of why, to me, software development is not an engineering discipline. At the end of the day, engineers (I think; not actually being one myself) have to answer to physics. The 'possible model space' is relatively constrained, and everyone is working under, roughly, the same set of assumptions, rules, and standards. This kind of constraint allows for higher degrees of rigor, because there often is a 'right way' to do things, or an empirical set of tests to verify the quality of an idea.
Software is, on the other hand, only slightly more constrained than mathematics in its most basic form. We can introduce artificial constraint by monopolizing a domain with certain ideas that have proven robust and reliable (in the same way that we've decided that, in general, you turn a screw clockwise to tighten it), which in turn allows for the introduction of some engineering-style rigor and standards, but there's nothing really stopping you from stepping back and saying, "well I want to do it this way instead", in the way that an Engineer is prevented, by physics, from saying, "well, I think we should just alter the density of air so that we don't need to worry about lift for these airplanes we're building; they'll just be buoyant!". By and large, you can do that kind of thing in code; you're building the world within which you're going to solve the problem, and you can arrange that world as you see fit (by and large) to make certain aspects of the problem easier (often at the cost of making others harder), in the same way a mathematician does.
And if you've got one kind of world you really like, because it works well with how problems decompose in your head, it can, to the parent's point, be really difficult to understand why another representation might be just as useful to someone else's particular brain arrangement.
Not trying to make value judgement here, though I do envy and admire engineering rigor. Just a (likely naive) take on a fundamental difference.
When you're fighting for ease of use, you can't make your users forget their preconceptions, you have to adapt to these externalities.
I think sometimes engineering and software development have different degrees of freedom, but the difference isn't as clear cut as you make it.
Building a bridge doesn't have much of that: the bridge must withstand loads from the traffic, loads from the elements, material wear across decades; all that without falling down. There are aesthetical components to choose from but generally you can't avoid physics and financial cost when building one.
In programming you could choose to go with a number of alternate implementations that are as different as they would be unrealistic if only you were building a bridge instead of software. Anything from tying inflatable boats together to form a walkable chain to act as a bridge to draining all the water out and building a 6+6 lane highway across the bottom of the bay instead.
Performance is a likely domain for coming to terms with the limits of the physical qualities of computers but even then there are lots of different flavours of performance to consider, and innumerable ways to trade performance in and something else out.
Many software projects are profitable without being anywhere near physical limits. Other software projects are not, if you are working for an HFT, then you're counting microseconds and measure distances by how long it takes light to travel. If you're storing 10^10 bits of data you don't need to even think about it, at 10^15 bits of data you can go to the store and buy a bunch of hard drives, and at 10^20 bits of data you need a team of experts to make it even possible, never mind cost-effective.
If civil engineering looked like software engineering, a big chunk of our civil engineers would be building popsicle-stick bridges to carry occasional featherweight loads across 1-inch gaps, but there would still be some real bridges out there.
This even affects bridges. The new eastern span of the bay bridge didn't have to have a tower at all. They chose the more expensive option because it looks better.
As a software engineer who calls what I do "engineering", I have to answer to physics every day. The difference is that the relative cost of everything is skewed so far out of proportion to what other engineers work with that it's hard to account for the differences, and software engineers work with so many orders of magnitude. We are still working with physical stuff, basically refined sand and metal, which consumes electricity and other resources, just like other engineers.
Imagine that you were a civil engineer tasked with building a bridge. Except instead of using concrete and steel, I handed you some adamantium at the low, low cost of $0.01 per cubic meter, and a bunch of robots to machine it for you. Designing bridges is easy now, and you can basically make it look like whatever you want, just because adamantium is so amazing.
But just because we've made bridge-building trivially easy doesn't mean that civil engineering is obsolete. Adamantium is nice, and all, but now I'm asking you to build a Dyson shell, and you have to tell me that it's not physically possible, even with adamantium.
I would love to just handwave the design of the systems I work on, I would love to just arrange pieces however I felt like. Instead I have all these constraints like the reliability of components (hard drives fail), physical laws (speed of light constrains network latency), the memory hierarchy (the software manifestation of constraints on circuits), and all sorts of other problems that I can't just pretend don't exist. I have to choose algorithms that will complete with the computational resources that I have available. Maybe an exact algorithm is not physically realizable, maybe I have to choose some kind of approximation.
This is not true in mathematics. In mathematics, algorithms are not necessary (at least, for most mathematicians). In mathematics, I can prove that some object exists without concerning myself with whether some physical system is capable of constructing that object.
At the end of the day, I am writing software, and that software is one part of a real, physical system which obeys physical laws. This makes me an engineer. Maybe I play around with 20 orders of magnitude in my designs and the civil engineer plays around in 8, but so what?
Also, the industry has been pretty cavalier about measuring those costs, especially when it comes to programmer time.
I think 'working with real physical systems which obey physical laws' is necessary, but not sufficient to qualify a discipline as engineering. Architects are not typically engineers by the title, and yet they design real things, and have to worry about some aspects of pragmatic engineering when they work. Neither are applied physicists, even though their work to defines many of tools that engineers use. I'm not sure that the task of creation scales isometrically. I think there's a certain allometric aspect that means that the kind of thinking required at 8 orders of magnitude has a radically different shape to that at 20 orders of magnitude; there are still some hard yeses and hard nos (you can't build a Dyson shell out of adamantium), but the amount of grey area is vastly, non-linearly larger, and requires a lot more ad-hoc construction to work within, and thus strips away the shared language of rigor that engineering has the benefit of operating under.
I hope I haven't made it sound like I think it's completely black and white, and also that I somehow don't think software is hard. I just think it's a different kind of animal, because of the scale that it operates at, and the number of abstractions it depends on, even if it can't embrace them fully and transcend into pure mathematics.
The person that made my coffee this morning is also an engineer by this definition.
Apart from that I agree, we have real constraints to deal with and we can't hand wave away the environment the code runs in.
The verb choice is important here, someone who makes coffee doesn’t “write” coffee.
That said, any definition outside mathematics or logic is imperfect.
So do computer scientists! Random access memory isn't constant time, but logarithmic for physical reasons. Cache effects can dominate big-O for a surprisingly large range of input sizes.
A wonderful metaphor. Thanks.
Programming worldviews are political belief systems. They're just as subject to bias and groupthink. They can be just as free from empirical grounding. It's just that their context is somewhat abstracted away from the real world.
1 + 1 will always equal 2, no one debates that. AWS offers both Postgres and MySQL, no one debates that. But which one is better, that will be informed by possibly irrational value judgements ("Postgres bit me once, never again!")
I think people are irrational in terms of their inability to admit where their biases are ("Postgres bad") vs things that are largely factual ("we can choose between these vendors").
Challenge accepted.
* In boolean algebra, 1 + 1 = 1
* Over the field Z2 (the integers modulo 2), 1 + 1 = 0
* In binary, 1 + 1 = 10
* In a language that allows overloading +, 1 + 1 = usually 2, but potentially almost anything else
In conclusion, context matters
And then BIG changes are implemented in the process. Usually in the worst possible place: in the planning of the process in the first place. If a project succeeded, and finished, your adjustments towards future projects, of course, should be tiny and minimal. In practice people make sweeping changes ("level 3 testing needs to be planned in before we even make the software design" boomed the senior architect).
And yet one lesson you quickly learn in machine learning is that whilst making adjustments that are too small ... does pretty well. You can be off by a factor 10 and while sub-optimal it works (and often, the further you get the smaller the adjustments should be).
By contrast if your adjustments are 1.1x what they should be you are stuck. You will never get where you're going. Never. That's a complete failure and you should expect to do worse and worse over time with such a strategy. So a smart person should almost always err on the side of not adjusting a behavior. Certainly from one project to the next, making more than 2% adjustment is absolute lunacy. This never works in learning algorithms. Never (0.1% is the largest generally used value). That would mean that for every software engineer in your team there should be ONE day difference EVERY 2 MONTHS from one project to the next. That's 2%. Even that is an absurdly large change, far greater than wise.
But I've never even once seen a software team that doesn't start with making 20% (one day a week different) adjustments between projects. And I've seen people make much bigger changes than that, generally not with better results. And the thing they're proud of is that they avoided a previous mistake ... a mistake they solved ... often much quicker than the delays caused by the adjustments ...
If you collect the pros/cons from everyone and try to agree on which ones matter more in the current context then you're not tied to a previous commitment.
A coworker of mine who once worked at Symbolics used to call this, "Applied Philosophy."
Amen to this, and by the way, it doesn't even have to be in the context of a discussion about a particular issue, let's say issue A. You can blunder into someone else's kneejerks unknowingly, on a whole other topic called issue B, and they will MAKE it be about issue A.
Of course, this really just moves the complexity to the composition of these functions and destroys locality of reference for anyone trying to read it.
cons()
{
local newdir=cons_$((counter++))
local car=$1
local cdr=$2
mkdir $newdir
ln -s $car $newdir/car
ln -s $cdr $newdir/cdr
}It is nice when it works but a real pain in the ass any other time.
It would be cool if the participants of every discussion (programming or otherwise) labeled their worldviews explicitly, so we could at least know what we're dealing with. For example on here with a tag by our usernames.
Old religions used to serve that purpose at least to a first approximation - we really could use some words to describe the new ones.
My assumption currently is that you do not switch pronouns arbitrarily and as a result were not just as likely to send "social circumstances may necessitate that she adopt a new viewpoint" when writing about an abstract individual programmer.
I know it is annoying to have this brought to attention but my world view includes the notion that small actions like this can have a profound effect at scale.
>social circumstance may necessitate that he adopt a new viewpoint
>when trying to have rational discussions it is necessary to try to dig in to identify all of people assumptions
This is why I prefer to use singular they instead. It is less annoying, less likely to make people uncomfortable, and can easily be seen to include people no matter what their gender happens to be. It even includes those whose gender is ambiguous in some way.
It is a small thing, but my world view is that small improvements like this add up to create a more generally welcoming atmosphere.
> there is a good chance of of the other person's programming beliefs may play a big role in their thinking
Check.
Use the male pronoun for hypothetical person in detailed example who needs to be more flexible in his/her thinking?
> this social circumstance may necessitate that he adopt a new viewpoint
Where the female pronoun would sound awkwardly coercive and uninviting?
> this social circumstance may necessitate that she adopt a new viewpoint
Check.
I believe ilaksh has their bases covered.
The upshot is that whining from self-important grammarians notwithstanding, English has always had a third person singular pronoun in common use. It has been used in every century by established writers. Indeed frequently by the same people who were saying that nobody should use it. That pronoun is "they".
Which is not to say that programming worldviews can't change, it's just that by their nature it takes a strong effort to change then and the changes are usually gradual over time. Or something completely irrational changed them. For example if a programmer needs to find a new job and the team has a different approach to programming, this social circumstance may necessitate that he adopt a new viewpoint.
I think that people are less rational than they think they are. Which is not to say that they can't be rational, it's just that other preformed factors besides logic have a strong influence over our perspectives on a particular topic.
So we can certainly discuss things productively but we should be aware that people can't change their religion easily. And no matter how smart or rational everyone has strong beliefs because that's just how our brains operate.
One consequence is that when trying to have rational discussions it is necessary to try to dig in to identify all of people assumptions, since there is a good chance of of the other person's programming beliefs may play a big role in their thinking and you may not even be aware of it.