By Drew LeSueur @drewlesueur repository
This site is for documenting the things I've learned as a computer programmer working on teams to create software for people.
Below is a list of concepts or technologies and my thoughts on them.
Much of this is my personal opinion and I value ideas that are different than these.
The best software is used by people and it helps them.
It works!
It's extremely satisfying to create something useful.
I enjoy working with the end-user to create software.
What's the essence of what you are making? Does your software do that well?
I love working with a team when creating software.
I love helping and learning from a team.
I have learned so much from my teammates.
I value diversity and inclusion.
I try to be sensitive and understanding to others.
Personality differences are totally overcomable with a unified cause or purpose.
—Ryan LeSueur
Software development is all about problem solving.
A good software developer is a good problem solver.
I think skill in a specific language or technology is not as important as general problem-solving skills.
Languages and technologies can be learned if it's required to solve a problem.
I like when there is a simple solution to a problem and many times there is.
Simplicity is one of the most important considerations when writing code and designing systems.
Simple code and systems have fewer bugs, are more secure, are easier to change later.
Simple code is easy to read and understand.
Simple systems can fit in your head.
Not everything can be simple, and there are tradeoffs that require more complex code, but as much as reasonable, I prefer simple code.
If something is out of the norm or confusing, make sure to add clear comments to explain what's going on.
In general, I think of simple code and systems as having few levels of indirection, few nodes in a diagram, and generally linear.
What can I remove?
Less is better. And if it's not better, at least there's not as much of it.
—Unknown
Web-based software has the benefit (and drawback) of being able to be changed frequently.
It allows software developers to release software in small increments.
Users can get incremental benefit along the way.
Without the drive to release, I've seen software projects spin too long in development mode.
What's the most important thing we can work on in order to release quickly?
It's natural for me to love coding and releasing software,
and not spend as much time on other important things related to software.
Make time for other tasks like Cleanup, Testing, Documentation, and Monitoring
If these are neglected, you'll feel burdened by technical debt.
Code and systems develop organically over time.
Things are added, changed, removed.
After time, artifacts of change exist that are unintended, but natural.
Code will have left-over parts that aren't used.
Or systems will be too complex.
It's important to take time to analyze code and systems, and identify ways to clean and simplify them.
It's much easier to do this when there are tests, especially integration-style tests.
I have benefitted hugely from having automated tests that prevent bugs.
I generally prefer integration-style tests over unit tests, but I still see value in unit tests.
Integration-style tests allow me to test a system as a whole, and allow me to refactor
without changing too many tests.
I generally prefer not to mock in tests, except for mocking third-party services if necessary.
I'd rather spin up a dependent test database or internal service instead of adding mocks.
I think it's easy for things to break at the seams and integration-style tests test the seams too.
I think integration-style tests can be made to run in all environments—development, test, and even in production.
Tests help with documentation, but they don't always answer, "Why?"
Add documentation for users, other developers, or yourself later.
It takes time.
Software is more than just code, it's a living system.
It's important to monitor the health of the system.
Track things like latency, throughput, request lifecycles, error rates.
It's frustrating but also somewhat reassuring that there will always be bugs.
Plan on bugs existing (because they will), and write code that is easy to debug (because you will have to).
Add tests and review code to limit bugs, but know that even with tests, code review, QA, bugs will exist.
I like to be empathetic to customers who report bugs—I feel the same frustration when I encounter bugs—
and I feel bad about all the bugs that aren't reported.
I've learned to not argue over what's a bug and what's not. If it doesn't work the way the user expects, I consider it a bug.
A quick bug checklist:
Code is read much more that it is written.
Code should be able to be removed and edited easily.
There is beauty and simplicity in abstraction in general,
but sometimes the cost of learning or remembering
the abstraction is not worth the duplication that the abstraction removes.
I will sometimes duplicate code if I think it will make it clearer and easier to understand and change later.
When a heavy abstraction is beneficial, I like providing an "abstraction escape-hatch" so you can break out of the abstraction when needed.
duplication is far cheaper than the wrong abstraction
—Sandi Metz
A little copying is better than a little dependency.
I love the idea of tradeoffs. Two opposing decisions might both be right, as long as the deciders are happy with the tradeoffs involved.
Many decisions come down to personal preference. I don't believe that there is always one universal, correct way to solve a problem.
I've really enjoyed seeing "best practices" change over the years.
It reminds me that I should have confidence in the tradeoff decisions I have made,
but also respect others for their decisions.
If you are making software, and you have a simple solution that works, don't feel bad if it seems to go against current "best practices."
I like automating tasks.
When automating, it's important to allow for "manual overrides" so a human can do what a computer can't.
I really enjoy pair programming.
I enjoy the knowledge transfer and focus that pair programming provides.
I think that there doesn't need to be a formal way of doing pair programming.
It should be natural.
Both people in the pair provide value even if one isn't touching the keyboard.
I love learning technologies and practices. I love experimenting with things.
Even if I don't need it yet, one day I might.
When I am with other developers, I think it's better to ask, "What can I learn?" instead of, "How do I prove how smart I am?"
I enjoy thinking through and working on optimization problems.
Sometimes optimization means changing the way the system works rather than optimizing existing code.
It's frustrating to not be able to find code.
I value things like onclick=
in html.
And 'greppable' identifiers in code.
If a specific feature spans multiple files in code,
I like to be able to grep for a single word or tag and find all places in code that relate to that feature.
Sometimes solving problems (like fixing bugs) takes a lot of effort and repetition.
Keep trying.
Focus is a form of simplicity and minimalism.
You can only do so much, what is the most important thing?
Creating software requires a good flow.
There is always an implicit request when software is asked for—it needs to be done quickly.
It is sometimes valuable to negotiate scope in order to satisfy the request for speed.
I value tools with a simple interface—like command-line-based tools.
Sometimes it's great to use existing tools to solve a problem,
and sometimes you need to write your own tools.
I also value "dumb" tools.
Many times a tool will try to be "smart" (like adding “smart quotes”, spell-check),
but it ends up not being what I want.
Git is a very useful tool for developing software.
I like that I can be in the middle of something, but revert back to do hotfixes.
I like that it helps teams work together on the same codebase.
I love the simplicity of Redis.
The conceptual interface is extremely simple—commands with arguments that set state of data structures shared over a network
The simplicity exists in the underlying RESP protocol too.
Even the configuration file is simple—no JSON, no YAML, no TOML—just key value
and # comments
Its simplicity is so refreshing.
I really enjoy writing Go—especially for networked services.
It's clunkier to write than more dynamic languages, but it really pays off when going back to read Go code.
I like that Go intentionally leaves out features like inheritance and exceptions.
Some things are harder to abstract in Go, but this can lead to clearer code.
I also value the idea that Go doesn't meet all needs and that other languages can be more appropriate or preferred.
The more I use bash/shell, the more I like it.
I think of it as the glue of operating system features.
And I like glueing together text streams for quickly automating tasks.
I also like how easy it is to do multi-threaded scripts in shell if needed.
I gravitate toward simple uses of JavaScript like using <script src="app.js"></script>
with hand-written JavaScript.
Lately I've used the Preact library for more complex user interfaces.
I like Preact because it's small and I can use it with plain html and JavaScript—I don't need a compile step.
I used to use JavaScript on the backend with Node.js, but I now use Go.
I use Vim as my text editor.
I usually use it with no plugins and a small .vimrc.
I enjoy programming with syntax highlighting turned off.
I usually program while ssh'd into a remote machine.
I like that I can be productive on any computer with an internet connection.
I only use one monitor.
I'd love to see more software creating tools done for mobile.
In high school I loved programming on my TI-83 Plus graphing calculator.
Here are links to other thoughts on software (or things that can apply to software) that I value:
A Philosophy of Software Design
Ten Principles for Good Design
Zen of Python
Agile Maxims
Redis Manifesto
The Rise of ``Worse is Better''
Rob Pike's 5 Rules of Programming
Amazon's Leadership Principles