Pre-announcement: Yes, I've left Esri for the last time. I'll let you know where I wind up closer to my start date. I harbor no ill will toward my former Benevolent Corporate Overlord, I simply wish to grow as a developer (and developer was the only thing ever in the cards for me in that place).
I haven't written anything for public consumption aside from the occasional uncredited blog post in a few years. I should probably do something about that.
Over this past year I've learned (or had made explicit, or was reminded of) a few things:
Stagnation leads to swamps: This one is a constant, especially as a software developer. Anything that sits will start to rot and go sour.
I've always been an issue-driven developer, meaning the issues system/bug tracker/whatever the organization uses is my professional to-do list that is groomed and prioritized constantly. Letting issues linger as "nice to haves" or letting the pond of issues get too large is death. It causes a deflation of the value of an issue and an eventual feeling of helplessness when the swamp becomes too wide to cross. Scrum cleverly tries to work around this by hiding issues in "backlogs" and initially describing issues at a very high level which explode into sets of smaller issues in each iteration.
There's no substitute for doing it right away, though, nor is there any value in not doing housecleaning constantly. If a nice to have has been on your list of issues for over a month and you still haven't gotten around to it, make a yes or no decision. Do it or toss it, don't let that thing stick around.
Stagnation in another sense is poisonous to a software developer as well: we're a group of people who must always be learning and always be growing. If you find yourself on the same project and doing the same work over and over, you're no longer adding value to yourself or your employer's product. If anything, doing the same thing over and over is a kind of grey purgatory, something that eats your skillset and your sense of worth.
Falling in love with your work is sad: You can always write it better the next time around. Someone else could write it better right now. If you have your own ad-hoc "framework" or set of libraries you're in love with (and can do anything!!!!) you're halfway lost. Falling in love with code rather than the ability to express an idea in code is an ugly premise. Which leads me to:
Software is almost as much about deleting code as writing it: Always strive for smaller. A simple codepath with an opinionated set of defaults is easier to test and integrate than something where you have options for every possible situation you can think of but haven't actually run into yet. The younger the code, the easier it is to move around, refactor, delete, play with. The older the code, the less you should fear it.
If you keep code around because it works, you're pragmatic. If you keep it around because you don't understand it, that's an institutional failure. The understanding of whatever process that code represents exists only in code and not in peoples' brains. Code should be a reflection of what everyone knows in the group, it shouldn't be a mysterious and holy artifact. Less parchment, more whiteboard.
Can beats Did: It's surprising how much code gets rewritten over the years. Often I say it's unnecessary, but I'm often wrong. You might have nailed the algorithm in Python. Great. Now you're working on a .Net codebase. What are you going to do? Introduce a dependency on IronPython and a shim layer for datatype conversions so you can continue to use that code? Or do you understand the problem and your tools well enough that you can rewrite the algorithm in an appropriate language like C#/F# so your peers can read it and you don't add a bunch of tortured extra steps in your build system? Knowing how to solve for X today is as important as having solved for X yesterday and it keeps you from fetishizing code as an artifact over code as communication.
How do you become a "senior" developer? One day at a time: I never really liked titles. I thought adding "senior" to a title was a stupid office politics kind of thing and that results were the only thing that mattered. I now see "senior" not as a reward, but as a verbal shortcut to describe the depth of one's skillset. A senior developer has seen a lot of tech come and go and can recognize the common themes. A senior developer can do pattern matching faster as they have a larger mental bank of solved problems and know how to prioritize. A senior developer will write bad code, yes, but usually it's a calculated risk as there is a limited amount of time and resources to finish the product, and recognizes where a corner can safely be cut. "Senior developer" isn't a title to be lorded over developer peers, it's a signal to non-developers as to who should probably be in charge.
Software is nothing but moving parts, so make those parts small and easily machined: What I mean by this is the classic idea of composing software by small parts, preferably ones that can run in isolation without being provided too much state. As a small example, rather than this:
class UpperCaser(TextTransformer): self._handle = None def __init__(self, in_file): self._handle = open(in_file, 'r') def _transform_line(self, line): return line.upper() def tranform_to(self, out_file): try: if not self._handle: raise IOError("No input file specified") with open(out_file, 'w') as out_handle: for line in in_handle: out_handle.writeline(self._transform_line(line)) finally: self._handle.close() UpperCaser("in.txt").transform_to("out.txt")
I'd prefer to see something like this:
def upper_case_lines(in_handle): for line in in_handle: yield line.upper() def upper_case_file(in_file, out_file): with open(in_file, 'r') as in_handle, open(out_file, 'w') as out_handle: for line in upper_case_lines(in_file): out_handle.writeline(line) upper_case_file("in.txt", "out.txt")
The pieces are smaller and composable. You can use any stream of lines and upper-case them. The upper_case_file function is now more explicit in what it does rather than spreading its functionality all over the place. The process is communicated well and the pieces are small and testable. Object-orientation is a thing can be applied judiciously and not universally and the world will still hum along just fine.
Being conservative makes you more able to change than being open: By this I mean a willingness to add third-party dependencies and support various operating environments is a form of technical debt, and will hinder your progress in the future. I was surprised at how easy it was for me to port a large codebase to Python 3 from Python 2 when so many others lament at its difficulty. The reason it was easy was it was a handful of #defines and #ifdefs to swap out no-longer-supported parts of the CPython API (and our use of the CPython API's footprint was quite small, mostly building/reading strings), and a very small core of dependencies (basically numpy and matplotlib). Porting the average mid-size Django app to Python 3 is not something I'd recommend, ever. Every library you don't own that you choose to build your business on gives an unintended amount of power to an entirely uninterested library author.
Weddings aren't about the bride and groom: If the wedding were just about the bride and groom, they would be the only two people in attendance. Weddings are about everyone else: friends, family, coworkers, other invites. You're involving all the important people in your life by bribing them to come with food and dancing and the chance to catch up with one another and you're forcefully interweaving them into the fabric of your relationship. Now the marriage is everyone's business, which leads me to:
Weddings are society's way of preventing divorce: I never want to go through that process again, so I will do my best to make my marriage work so I won't have to.
My Spanish is just fine: We went to Barcelona in November of this year and my first day there I was paralyzed with fear when trying to speak to others, then in subsequent days I became more frustrated with myself because I was not able to communicate well or understand anyone speaking. Catalan's probably no problem for a native Spanish speaker, but it messes me up something fierce. Luckily Barcelona is quite touristy and English worked almost everywhere. Then we went to Madrid and it was like night and day. I could understand Castillan just fine, I could communicate back just fine, it was fantastic. I'd always known Catalan was different, but I never had it hit home just how different it was and assumed all my language skills were awful.
Being a linguist is usually only useful when you can sit down and think about the problem: Certainly sitting down I can make the connection between the phrase "si us plau" and "s'il vous plait," which I've heard before, and realize I'm hearing "please ____." That kind of connection/problem solving by comparison and observation isn't so useful when you're being barraged with a number of announcements on a train platform and try to figure out if they're saying the train on the platform leaving right now does go to the airport or doesn't go to the airport. However, that set of connection-making skills made reading Catalan super easy. I recognized a few fairly consistent spelling changes (namely, j becomes x and ch becomes tx) and I was able to navigate by signage just fine.
Making it 9 and a half years post college without moving to the Bay is fairly respectable: Ever since I attended a Y Combinator Startup School back in 2006 or so I've felt the pull of the Bay Area's gravity. It's where the interesting software work is, it's where many of my peers are. I've gotten a lot out of living in the exurbs of Los Angeles over my lifetime, but if I want to keep moving forward with new projects and new roles, I really need to head up to the Bay. So this year I finally am.