
The nihilist and optimist programmers (2015) - ingve
https://peter.bourgon.org/blog/2015/08/25/nihilist-optimist.html
======
YeGoblynQueenne
What's being missed here is that it's perfectly possible to be an optimist
that delivers, and does so reasonably fast. The problem is that it takes an
excruciatingly long time to understand how to do this and most people simply
don't have the patience to get there, so they get stuck in one of the two
camps - do the right thing slowly, or do the wrong thing fast.

Or perhaps it's a luxury- you have to make the right career moves and only
allow yourself to work for organisations and people who actively support you
while you develop your skills. You need to convince people to really invest in
you, that is. And that's hard to do.

Think though- what's the alternative? If you work for employers who believe
that everything you do is always going to be a bit shit, what can you expect
from them? You can certainly expect your pay to be a bit shit also, and then
your say in anything that matters. Way to go to become a useless, incompetent,
irrelevant, cost-center drone, there, buddy!

I'm not saying you should strive to be a rockstar. But you can get better at
what you do, and one day, even get to be good at it. Like, really good. People
do that in every craft, in every trade, in every art, even. Why is programming
any different?

Well, it ain't. The "nihilist" programmer in the article is really a
_pessimist_ programmer. The stack is always half full for them (get it?). But
if it wasn't for "optimists" we'd never have tail-call optimisation. See? It
gets better.

------
franciscop
This is so well written, I just wish it expanded a bit more in the end. I'll
tell my experience rocking from one side to the other:

When I started as a self-taught programmer I was basically fighting the code
all the time and reading about these _better practices_ and all. I followed a
top-to-down learning focusing first on the deliverables. As I started learning
more and more and constantly struggling with my own code, the ideal
implementation (of course involving OOP) seemed further and further far off,
always elusive. You could always add an extra layer, an extra abstraction here
and there.

At some point I realized I was lost in an abstraction sea and not getting
anything done. I abandoned some of the projects at mid-size and made
[https://picnicss.com/](https://picnicss.com/) as an example of the opposite.
Oh boy, what a difference. A single stylesheet made in few days with great
adoption and feedback from the community. I just saw a video of Google IO 2017
and they used it there in a demo! It also helped that I switched from PHP to
Node.js around that time.

So I kind of got hooked to that. I have made quite a few tiny-sized, one-off
projects ( [https://github.com/franciscop/](https://github.com/franciscop/) )
and learned a lot about this quick-iteration coding. I wouldn't say it's the
same as the OP's description of nihilist since that seems to be based on a
large codebase. What I made was nihilist in the sense that some projects
superseeded the previous ones. Example: first I made
[https://umbrellajs.com/](https://umbrellajs.com/) , then decided to re-
implement it all and created [https://superdom.site/](https://superdom.site/)
with an alternative syntax.

Now I think I've found a balance in the middle as I'm finishing
[https://serverjs.io/](https://serverjs.io/) ; the library's public API should
be fairly stable, but the implementation details can have their shortcomings
and be kind of messy at places. To finish off with a great saying for the
situation:

 _Perfect is the enemy of good._

~~~
manibatra
"Perfect is the enemy of good"

Could not agree more. Self taught programmer here too. For such a long time
chasing "perfection" had me stuck where I was not finishing any projects.

Taking a step back I decided that finishing projects is what really gives me
happiness. They don't have to be perfect or world changing. That coupled with
detachment from how the project is received has helped me so much.

Congrats on all your projects. Inspiring!

~~~
crehn
Same here. Although it was rewarding to write "perfect" code, getting
constantly hung up on the tiniest details was quite a soul-drainer.

Nowadays I see more beauty in the end product and refactoring. I still keep
that idea of perfection in my mind and do my best to write good code from the
start, I just don't let any of it become a blocker.

I'm more efficient, stress-free and productive as a result. And I don't feel
as repulsed when working with other people's code.

~~~
AstralStorm
Good thing you do not work on security or real time critical or life critical
applications then.

Seriously, the only kind of perfect code is the one that has been proven
correct. Or in fact the proof itself.

Otherwise you're talking about "code we think does the thing and looks nice".

~~~
doubleplusgood
In many, many circumstances, code that "does the thing [well enough]" is more
than enough. Not everyone works on avionics or pacemakers.

------
Slackwise
And then there is being the nihilist because the company and project managers
won't allow you to improve or fix anything anyway.

~~~
devoply
Well I was thinking the nihilist programmer gets fired a lot less often than
an optimist programmer does. Mainly because he gets the job done, while the
optimist programmer often finds he's bit off more than he can chew and is
choking on it... and the company is not happy because they are not getting
RESULTS, which is all that they care about.

~~~
tempodox
This may seem logical, but in practise it doesn't work that way. Optimists
make for a better mood in the workplace, which interestingly is more important
on a day-to-day basis than achieving results (barring any obvious negligence).

------
Iv
The thing is that the nihilist and optimist are not different persons but
different mindsets and that in some circumstances, one or the other is right.

Sometimes, management dooms a project and as a programmer there is only so
much you can do to make it forward. Interestingly, poor technical quality does
not prevent a project from being commercially successful.

Other times, especially at the start of a project, or as a project manager,
you have the ability of making it right. Do not pass on it! Have some
realistic expectations about how far people will go with recommendations and
best practices, but recognize opportunities to improve a design, as they are
rare and valuable.

tl;dr: be the nihilist 95% of the time, but do not miss the optimist's
opportunity that will happen 5% of the time!

------
kmicklas
Sometimes I wish I was a nihilist programmer. They seem much happier, and in
my experience optimist programmers slowly get all the life sucked out of them
when on a team of mostly nihilist programmers (which seems to be most in the
industry).

~~~
theclaw
I learned not to be overly optimistic, but that doesn't make me a nihilist. I
think most experienced programmers are pragmatists.

------
lmm
> If a thing is undefinable, you will naturally resist efforts to define it.
> If a thing is forever in flux, you will resist efforts to freeze it. If a
> thing is composed exclusively of compromise, you will resist efforts to make
> decisive decisions. And if a thing will never be good, you will resist
> efforts to make it good.

Isn't that a good way to approach software development? You probably shouldn't
make decisive decisions, you probably shouldn't freeze your project, and if
you define it you risk missing opportunities outside that definition.

~~~
pdonis
_> Isn't that a good way to approach software development?_

Not if your software needs to actually meet users' needs--in other words, not
if you want to make a living at it. To meet users' needs, your software has to
ship, which means you need to make decisive decisions, you need to freeze your
product, and you need to define what it does.

What you don't need to do is stop doing those things once you've done them
once. You can always update your software, you can always make new decisions,
and you can always redefine what your software does, in response to changing
user needs or changing understanding on your part of what user needs actually
are. But the only way to do that is to do it, which means you have to start
somewhere. And never making decisions, never freezing anything, and never
defining anything means never starting anywhere.

------
partycoder
The "nihilist" described here is a person that sees implementation as means
towards an end, and in this perspective, functional requirements are at the
center. Because of this, for these people software is a black box where the
only important things are the touching surfaces.

The "optimist" described here is a person that sees software in a more broader
sense: functional AND non-functional requirements. Non-functional requirements
include maintainability, scalability, performance, security, configuration,
etc. and will strive to implement them.

\--

Now, my opinion:

My name for the "nihilist" programmer are "feature fairies" or "duct tape
programmers". The problem with feature fairies are that they create more
problems than they solve, and never volunteer to fix them.

Feature fairies like to get credited with completed features, but never with
the defects associated with their contributions. Therefore they will usually
play dumb when a bug happens, or an incident is declared, and make someone
else clean up after them while they implement the next feature.

So after a couple of years, you have someone credited with a lot of features,
and a team of people that have been cleaning up after such person. The duct
tape fairy is now a 10xer, a rockstar whose time is very valuable therefore
needs to be paid more, even promoted, even though this person is responsible
for wasting 90% of the engineering payroll in fixing trivially avoidable
defects.

The way to prevent that is to leave a trail of evidence that can link commits
to bugs. When an incident happens, make sure to identify the commit id causing
the problem and put it directly in the ticket. Make it very clear where the
defects are coming from and who they're coming from.

Never volunteer to clean up after a feature fairy. By the time you do this,
the feature fairy marked their task as complete and from the eyes of
management you would be wasting your time working on a completed task. Rather
than doing that:

\- When the feature fairy wants to take on the next task, ask if they have
fixed one of the defects caused by them as per evidenced in the commit id.

\- Rather than opening a new ticket, reopen the original ticket. This better
reflects the situation: you are completing the work the duct taper failed to
complete, you are not adding new work. This also denies the duct taper of
their prized fake task completion.

When a feature fairy volunteers to be in a hiring committee, prevent it at all
costs. They last thing you need is having to clean up after more people.

Be careful while doing this to not be perceived as negative.

~~~
overgard
I've been programming professionally for a decade and I've yet to see a
"feature fairy" like you describe. I have seen a lot of crab mentality though
-- mediocre developers and managers trying to use process to bring everyone
back to the mean. Humoring the idea for a moment though: isn't anyone that
writes a high volume of code also going to create a (proportional) high volume
of bugs as collateral? If someone has written twice as much of a system as
others on the team, it wouldnt be weird if they were responsible for twice as
many bugs.

~~~
partycoder
Productivity is not writing more code, but rather finishing more work, and
while there's an overlap, they're substantially different things.

If you are taking less time than the rest, there are a couple of
possibilities:

\- You are a legit virtuoso of software. <\- this is possible, but less
likely.

\- You are cutting corners and leaving work for others to do. <\- this is much
more likely

In the first case there's no problem. In the second case you are not truly
finishing your work and the team has a legitimate reason to ask you to finish
your leftover work.

If everyone starts contributing code leaving left-overs to inflate their
productivity, it quickly becomes a race to the bottom: technical bankruptcy.

If you are not able to explain what your code does word by word that means for
a start that you did not read the documentation, you repurposed code you don't
really understand. Therefore your time savings are at the expense of
compromising the quality.

If you didn't handle errors, if you didn't write tests, if you hardcoded magic
numbers and strings, if you didn't test your code, if you didn't stick to the
coding standard, if your identifiers don't reflect the code they represent, if
you coupled unrelated code and performed actions at a distance... you are also
saving time at the expense of the product quality because you cheated to
finish earlier. All those problems add up to technical debt.

------
kough
An example of in the middle: realize things have flaws, but work to improve
them. Realize that perfection cannot be achieved, so work with the
stakeholders to come up with something acceptable. Programming here is just
one other set of tasks that has to be done. Check out
[http://meaningness.com](http://meaningness.com) for deeper insight on the
philosophical side.

~~~
kerkeslager
That's basically the optimist view in the article, I think. Optimism in this
case isn't about pretending the thing is good, it's about believing it _can_
be good.

~~~
lomnakkus
It's not even that, I think. It's just a... "Trade-offs exist: Deal with it."
type thing?

If I can offer an anecdote which is tangential: I like to say that I'm
actually an Optimist, but it's just that I've been disappointed so many times
that I may _sound_ like a Pessimist.

Honestly, I think it requires a certain amount of optimism/hope for the future
to keep working in this industry. The people are usually great, but the
_systems_ (both technological _and_ organizational) are mostly just awful.
Awful, awful, awful. I take a little solace in the fact that I can (most of
the time) fix the technical systems.

------
Jach
> The nihilist programmer starts from these axioms and then decides what to
> do. What to do? The least amount of change possible.

I don't think there's a deductive chain from those axioms to that choice of
action. If you're a "nihilist programmer" (not a fan of this usage of
nihilist/optimist) in this sense, there's nothing in your ethos that says it
can't be better. Sure, it will always be crap, but you can make it better
crap. You can do that in small bits or big bits.

The analogy I use for legacy production software is that it's a tire fire, one
should endeavor not to make it worse (by unnecessarily adding more tires or
fanning the flames), and if possible make it better (spray water on the
thing), but it's never going to be an Eden even if you managed to put out the
fire since you've still got a stack of tires that could reignite at any
moment. If you start out with an Eden in the beginning, maybe you can preserve
that, but even if it's ever been done it's not done most of the time.

The best is the enemy of the good, but the good is the enemy of the better.
There are few things more irritating to someone with a "nihilistic programmer"
mindset as seeing some self-satisfied "optimistic programmer" with their Good
crap, that's still crap and could be made better. Not seeing any chance or
value of improvement from good is the inverse to seeing no chance or value of
improvement from broken, the problem with either view is that doing better
isn't tried.

------
wcummings
>What to do? The least amount of change possible. Limit exposure, limit
effect. Get to the next checkpoint.

If it ain't broke, don't fix it.

------
jasonkostempski
I'm either a nihilistic optimist, or an optimistic nihilist depending on what
and how much I consumed the day before.

------
z5h
We need both.

------
faragon
TL;DR: nihilist programmers should be fired as soon as possible.

