
I'm a good engineer but I suck at building stuff - lbarrow
http://lionelbarrow.com/2016/05/08/i-suck-at-building-stuff/
======
zer00eyz
There is a quote from Louis Nizer that applies here:

 _" He who works with his hands is a laborer. He who works with his hands and
his head is a craftsman. He who works with his hands and his head and his
heart is an artist."_

Its that last part that is hard to bridge for a lot of engineers. The thing
that did it for me was sitting through a LOT of formal usability studies.
Seeing folks actually use an application you made, where they make mistakes,
get stuck, will change your relationship with your code. Even if you work
purely on the back end building APIs, you have customers (other developers in
this case).

Focus on the what the code does, and why someone would use it, care about your
customer... the how only matters to your fellow engineer, and if it is that
bad they are going to give you grief for it and you can fix it.

~~~
peterclary
I started my career in a small software company that wrote Mac software (in
the System 6.5, System 7 days). We had no dedicated support staff, so support
calls were either handled by the sales staff or development. Talking directly
to customers, hearing where they were having trouble, and learning what they
wanted to do, was probably the single most valuable experience in my career.
My first thought with any work became "How can I completely eliminate the
possibility that I will end up having to support this?"

Of course, this backfired spectacularly a few years later at a different
company, when a customer stopped paying a lucrative support contract because
the software always "just works". I have decidedly mixed feelings about that!

~~~
monkeyprojects
That isn't such a problem nowadays as you could move the business model from
outright purchase plus support to a software as a service model with monthly
fees and minimal support costs.

------
daenz
> When I try to build something new, I find myself instantly criticizing my
> technique, to the point of paralysis. This function is hard to test; this
> object's dependencies need to be injected rather than initialized
> internally; that module needs an integration test; and so on and so forth.
> Even when writing spike or proof of concept code, I find myself revisiting
> the same lines over and over again, looking for the best, most natural
> expression of the ideas it contains -- obsessing, like Catt said, over my
> own construct, rather than on the thing my code does.

I used to be like this for the first few years of programming. And I knew a
guy at my last job who was exactly like this. The thing that helped me, when I
felt the indecision paralysis come on, is to just do _something_ and accept
that it may be wrong. You often don't know the best decision in the first
place because you lack experience. Doing it the right way by accident, or
making the mistake of picking the wrong way helps get you that experience. Be
deliberate about always doing something, and over time the paralysis will get
less and less as you gain more experience.

~~~
bitwize
No. It has to be clean, correct, and come with full unit test coverage the
first time. You have until the next sprint to implement it. Your workspace is
a Macintosh at a long desk where you'll be working shoulder to shoulder with
other devs working on other projects. If you can't manage even that, you're
just not a good fit for our company; we expected more of an engineer of your
experience level.

Based on a true story.

~~~
stuaxo
Awesome. I interviewed at one of these once, I knew I wasn't going to get it
when I saw the massive imacs and the square glasses... plus the guy couldn't
explain what it was they did at all.

~~~
bitwize
I should have known to gtfo when at new-employee orientation I heard a
presenter use the word "decisioning" with a completely straight face.

------
jrumbut
I feel like my experience is the opposite of this.

I've never understood something until it stood between me and building what I
needed to build.

This approach has been great professionally, but lately I'm becoming more
interested in theory intensive fields and struggling to find resources that
teach from the perspective of someone who wants to build something that
requires the knowledge involved, rather than someone who just wants that
knowledge.

~~~
JimboOmega
I'm always worried that it's _not_ great for me professionally. Because the
"cool kids" are always off learning the hot new thing, and I can do what I
need to in the "old" thing, and so I don't learn the hot new thing.

Aren't I, as an engineer, supposed to be constantly entranced by the bleeding
edge of technology? Whether it's the latest lisp Dialect, the latest
functional programming language, the latest NoSQL database, or whatever the
latest is?

Granted the nature of my work is such that I wind up using tons of new
technologies every new year, but I don't go out and experiment with them with
no particular use in mind.

~~~
morgante
You can build in the hot new thing though.

I'm also a very practical learner. It's hard for me to pick up anything
(whether it's a language, technique or a theory) without applying it. So to
pick up new technologies I constantly cycle them into new projects.

~~~
JimboOmega
I _can_ , but I won't build in the hot new thing for the sake of the hot new
thing alone.

What that tends to mean is that when I'm looking for a new job, my skills at
old company are in old thing, while everyone is excited about hot new thing.
This is typically most obvious with javascript libraries.

------
nanodano
Another thing I run in to a lot is people saying "I know how to program, but I
don't know what to build." There is an amount of creativity involved with
programminng.

It's like learning how to physically manipulate a guitar and play notes, but
saying "I don't know what to play." That happens a lot too, but musicians have
the repetoire of other composers to play if they do not want to write their
own music (many don't). With programming, recoding something is called
reinventing the wheel and that's frowned upon.

Ok, sometimes the analogies are forced, but I hope you get it! It's kind of
interesting though, because in order to progress we have to build something
new, or build on top of what we have, so the technology is forced to evolve.
Music can repeat over and over and people don't get tired of it and you could
argue pop music is working against the evolution of music.

For anyone who hasn't seen the four chord song...
[https://www.youtube.com/watch?v=oOlDewpCfZQ](https://www.youtube.com/watch?v=oOlDewpCfZQ)
Wait, what we were originally talking about now?

------
kstenerud
Learning the programming art is like learning any other art. You first learn
the rules (and even more importantly the REASON behind the rules). You then
build the discipline of applying the rules. And finally through experience you
learn where some of the rules just don't apply.

The usual progression is something like:

1\. Build your first major project as senior engineer. You make something that
works, but is brittle and soon becomes difficult to work with.

2\. Build your second major project. This time, you adhere to ALL established
best practices. The end product is difficult to configure because you've gone
too far in flexibility, and a major pain to maintain because the codebase is
3x larger than it needed to be, and filled to the brim with boilerplate code.
You also resist changes that threaten the precious architecture. Everything's
perfectly isolated and testable, though!

3\. Build your third major project with the minimum needed to get it to work
for your client, keeping a few of the best practices to keep it mostly
flexible enough for changing requirements. It will eventually grow in
unhealthy ways as requirements shift beyond fundamental architectural
assumptions, but you already knew this going in.

4\. Make the mistake of doing a "2.0" rewrite of your major project. Vow never
to do it again.

------
ThePhysicist
I think there is a lot of truth here. Recently I had to work with some old
code of mine that I wrote ten years ago as a (Physics) student, and looking at
the code I realized that while it was a bit ugly and "unconventional" it
worked quite well. If I would start the same project today (after five years
of intense software dev experience) I think I would be at a much higher risk
of "writer's block", simply because I think of so many aspects of the code
(testing, deployment, architecture, documentation, language, tooling,
framework) that were just unknown to me at the time and which therefore did
not distract me. So in a sense, ignorance really is a bliss.

Here's the code in case you're interested, it's for simulating superconducting
circuits:

[https://github.com/adewes/superconductor](https://github.com/adewes/superconductor)

------
ogreveins
Here's a priority list that you should typically follow for making anything.

1\. Make it work.

2\. Make it not break.

3\. Make it fast.

That's it really. Until the performance of something is blocking what you need
to do somewhere else leave it the hell alone.

~~~
rednab
Per (as far as I can tell) the original:
[http://c2.com/cgi/wiki?MakeItWorkMakeItRightMakeItFast](http://c2.com/cgi/wiki?MakeItWorkMakeItRightMakeItFast)

1\. Make it work.

2\. Make it right.

3\. Make it fast.

~~~
ogreveins
Wow, I honestly never read that. +1 for the link, I love old stuff like this.

~~~
nickpsecurity
c2 is a great wiki. Start googling languages and programming phrases with
site:c2.com at beginning. You'll find some good stuff. Unfortunately, its
commenting got shut down shortly after I discovered it. I think I read all the
debates and stuff. Too many haha.

Note: The debates over LISP, OOP, Cleanroom, Smalltalk, and so on are all
especially interesting.

------
elishacook
I can relate to this. You see it in a lot of domains. I see two concepts that
apply: Practice/Performance and Generation/Synthesis.

To be a musician you must practice, but you must also perform. These are two
different modes. When practicing, the goal is to improve a specific technical
skill. You don't concern yourself with expression at all. You will repeat the
same passages over and over and many exercises sound really terrible. When you
perform, you put your trust in your training and you access an intuitive part
of yourself to add feeling and nuance to your playing.

In design thinking, it is common to split activities into generation and
synthesis. When generating, you recklessly explore possiblities, tossing them
out, following blind alleys, making weird connections. Synthesis is the
process of evaluating the generated ideas against some framework, such as
goals or known models, finding patterns, simplifying and making coherent.

We need all of it: practice, performance, generation and synthesis. Experience
brings a sense of when each mode is appropriate or needed. Being explicit
about which mode you are working in removes the stress from attempting to
practice while you are generating or similar dissonant mixes.

More concretely, a user-centered process has brought a lot of this mental
framework to development for me. Step one is never setting up a test harness,
it's understanding the user and their goals, even if the user is yourself.

Everything else flows much more easily from this starting point. You can base
your decisions on how they will affect the user instead of on "best" practices
that may not have the best outcome in your situation. Things like precision,
speed, fidelity, automation, complexity, stability, even whether or not to
build something--all involve trade offs that affect the user in different
ways. You can experiment more freely knowing that you will evaluate your
experiments in terms of their utility for the user.

The art is in applying this left-brain-right-brain dance to trace a path
through all the complexity on behalf of the user.

------
abc_lisper
You just a need priority list. If you think something needs to be fixed, add
it to the list. Choose the next task with the highest priority when you are
done with the current one. At least you will know why you didn't fix
something. It would be most likely be because there are only so many hours in
a day, and your skill does not change overnight, despite obsessing over it.

------
vosbert
There's a couple modes of engineering mindsets I'm conscious of.

1) Being careful of every change and addition I make. Trying to figure out and
predict the effects, scalability, and maintainability of the code I produce. I
find that most engineering positions are looking for this, as most employers
already have an existing production code base and would not like wild things
like crashes and service disruptions to happen to their audience.

2) Occasionally, I get to start on something completely new. Not new as in
just a blank page, but new as in blank project, or even blank idea. As
exciting as this sounds, over 90% of the time, the idea will die as there is
some undiscovered flaw or expectation almost always external to an
exceptionally well thought out implementation. The only thing clear about this
is the urgency of the deadline, and the failure associated with missing it
(missed management expectations, no demo, no presentation... etc). Many know
this as building a Minimum Viable Product. In this case, all rules go out the
window. Choose expedient tools, create copious crap code and internal design,
as long as it works OKish in the end. Having it violently done tomorrow as
opposed to 3 days later, or a week later, or a month later, is key. If you're
lucky and it limps along (not canned as uninteresting), just change hats and
become the step (1) engineer.

Sounds like you desire some more experience with (2), but both types of people
are needed. You, yourself, will become more valuable if you can put on both
hats, but I wouldn't say that one hat is absolutely better than the other.

------
Jach
"Just do it, hack! I approach code like games, rush deep into room, trigger
all NPCs, die, after respawn I know where NPCs are."

[https://twitter.com/bkaradzic/status/494341136245211137](https://twitter.com/bkaradzic/status/494341136245211137)

------
pedalpete
Where you see your greatest weakness, I see your great strength.

I'm good at building stuff, but I'm not a great engineer (I'm ok, but others
on my team are way better).

Not to say I don't have my strengths. I'm good at figuring out what to build
and the general architecture of how to get it done quickly and working well.

But when it really comes time to scale and scale big, you don't want me
coding. You want me looking at the next features etc. etc.

If you love getting into the nitty-gritty of high quality beautifully
considered easy to work with code, why do you feel you should focus on
'building stuff'?

Personally, I think focusing on your strength (not to completely ignore
building stuff) can be a huge benefit.

------
groby_b
Meanwhile, I've seen way too much code from people who're good at building
things, but not engineering. And lost countless nights to keeping these
rickety structures alive long enough that we could fix the most egregious
issues.

Sure, build something, anything, to show it can be done. THEN MAKE SURE ITS
ACTUALLY STABLE.

And then realize that building stuff, and understanding how to build it well,
_both_ matter.

------
mkoble11
the critical self talk is normal. you should watch seth godin's talk "quieting
the lizard brain" [https://vimeo.com/5895898](https://vimeo.com/5895898)

i just had a similar conversation, but it dealt with music instead of code.
this person felt they couldn't improvise/ create.

the problem isn't with their abilities, it's that they were taught to follow
instructions - like the notes on sheet music. jazz musicians play off what
they _hear_ instead. however, they first internalized the rules and then
forgot them.

you've already got the rules down - so the next step is to "forget" them.

a time constraint like going to a hackathon is a good place to start. you're
pushing yourself to create in a short amount of time.

here, you'll focus on shipping...drowning out the critical voice in your head.

it's much like a muscle. the more you build and struggle through, the stronger
you'll get.

~~~
munchbunny
Very much this. If you force yourself to make lots of things at a fast pace,
whether by hackathon or something else, you will eventually get over your
hesitations, and you'll find yourself speeding up and building better things
too.

------
scottious
God I wish the rest of my team would read this... I feel like they're more
concerned with what stupid monad to use or how to create a really deeply
nested class hierarchy than making features and bug fixes that deliver value
to people who use the software

~~~
swanson
Why not link it to them and then discuss it over a team lunch?

~~~
scottious
That makes too much sense! Honestly though, the fact that that seemingly
obvious suggestion is actually quite difficult means there's something wrong
with me or our team culture... something to think about I guess.

------
dmarges
One thing that really threw me for a loop was back when I started learning
about TDD. I tried to apply it to literally everything I coded. This caused a
lot of paralysis because I was worried about whether I was testing the right
way. Over time I came to a compromise. Basically, if I have a good
understanding of the design and what I want to build and I know it is going
into Production I use TDD. If I'm not entirely sure what I am building or I'm
exploring an idea or spiking/prototyping something then I just write the code
with little regard for things like speed or design patterns.

------
agentultra
Good advice! If we really cared about the systems we create and the effect
they have on the world then the language it is programmed in and the
implementation of that system would only be one part of the process. The means
of effective reasoning about the design of software systems is formal. However
it seems to be outside the scope of any introduction to computer science or
programming course.

To quote _Friedrich Bauer_ :

"Software engineering is the part of computer science which is too difficult
for the computer scientist."

------
sjg007
Meh. It should meet the requirements. And at any rate the next dev to work on
your code will declare that it stinks and needs to be refactored at best or
completely rewritten.

------
cyberpanther
A lot of times as engineers we don't have to build anything. We only have to
fix, maintain, or tweak. Or maybe build just a very small piece of something.
So it's perfectly OK for most of us to suck at building stuff. But on a team
it's important someone fill that role. But most of us shouldn't or it would be
chaos.

------
phantom_package
Funny, I'm great at building stuff but I wouldn't consider myself an amazing
engineer.

------
jluxenberg
Slides from @cattsmall keynote mentioned in the article:
[http://www.slideshare.net/CattSmall/con-the-creative-
program...](http://www.slideshare.net/CattSmall/con-the-creative-programmer)

------
hyuuu
and it doesnt end there, after you build the stuff, you need to make sure that
the stuff solves a problem, which to me is a much more harder problem.

~~~
elihu
That's a good point. Also, in the process of solving one problem you may
discover a more interesting, more relevant, more general, or more universal
problem you could be solving instead.

------
rileymat2
I find this is a problem when I lack control over what I am building, so I
focus on the act of building it which is in my control.

------
horsecaptin
I have the opposite problem. I'm great a building stuff... but I suck at
passing job interviews.

------
dschiptsov
Whether or not one is good is for other people to decide by evaluating one's
deeds.

------
cagey_vet
the first step to curing your problem is realizing you have one.

------
thisisadumb
i am a good engineer but i am a bad engineer!?

------
chipsy
I like this post because it captures some way in which my perspective has
changed over time. Engineering was something I saw as a way to perhaps "cheat"
at product problems because if I made a good enough/fast enough/automated
enough/generic enough solution, I would be able to iterate on it really fast
and so somehow come out ahead of people who went directly towards the simple
solution. This mentality was clearly inspired by years of homework being a
task that would never go away and that I desperately wanted to get out of my
life as fast as possible in the way that consumer products advertise their
elimination of household tasks - ergo my goal as a student was to wish I could
automate away all aspects of my studies. I would look for any kind of secret
trick or forgotten technique that would get me closer to that goal at minimum
effort. All the while I would build very little that was finished and get lost
in maximizing my use of silver-bullet abstraction.

I've eventually come around to flipping this idea on its head, though. If I
design not just some kind of product or solution, but a whole process,
starting basically with how I want to run my life and then drilling into
specific details from there, the technical knowledge stands on more even
ground with other forms of knowledge, and with seeing life itself in a more
precious sense.

With that mindset, good scheduling of every day as an end in itself grows
vastly more important, and abstraction-for-its-own-sake falls away: All
programming problems start by assuming they are solved first with "code that
looks like breadboard wiring" [0] and then working up the abstraction ladder
from there. Automating the technical parts of the solution won't guarantee
that it's right in any other way, but it will ease the pain of changing the
specification. Acknowledging that the problem is messy, that breadboard coding
is messy, and that I won't know how to solve everything immediately and cannot
depend on a silver bullet, all constitute crucial first steps.

Now I always look for really basic groundwork to be laid out early on -
typically, transforming the breadboard code into something that uses a new
data structure, or generating the code flow from a stack or a list or a tree -
and that no shortcut is possible without compromising the ability of a
potential future abstraction - that it just takes a lot of layers to get where
I want to go. Breadboard code is assumed to be ideal until demonstrated
otherwise, while "x in y lines" hype is to be avoided under the assumption
that the solution is brittle and over-modeled towards the demo code. I cannot
assume that my valuable production code will need x or work in y lines. I
don't abstain from adding dependencies, but I will preference towards copy-
paste-own when I find a reason to reuse code.

[0] [http://www.instructables.com/id/How-to-Build-an-8-Bit-
Comput...](http://www.instructables.com/id/How-to-Build-an-8-Bit-Computer/)

------
bikamonki
What is a good engineer?

------
xyzzy4
"He who rests while other people work with their heads, hands, and hearts is a
capitalist".

~~~
6stringmerc
That quote certainly describes my view of the legacy of Steve Jobs at the
cold, pragmatic core.

~~~
mwfunk
Just because a CEO spends their day making high-level decisions because they
are literally delegating tasks to tens of thousands of people doesn't mean
that they are "resting".

