In college, I had planned on going to grad school for math, but then I found myself amazed at the impact sites like Reddit were having. Reddit was able to use the wisdom of crowds to surface great content that millions could enjoy. I knew I wanted to make an impact and although math is important, any impact I was going to have was most likely going to be indirect. I wanted to work on problems that were closer to the average person, so I decided to work on web apps. Eventually, I wanted to create apps with a focus on categorizing and solving large scale problems.
I had to take a few programming classes to get my degree, so I was already somewhat familiar with coding. Funny enough, my first language was Fortran since the focus was on mathematical programming. I then did research my senior year to work on algorithms for the three-body problem and general differential equations. From there, I had enough coding experience where I felt confident that I could learn how to be a developer.
My desk tends to be pretty clear and slightly messy.
I have one main monitor that I use and then I keep my laptop on a stand as the second monitor. Typically my laptop acts as the terminal monitor and then I do everything else on the main monitor.
My laptop setup is fairly simple. I spend most of my time in the terminal, VS Code, and Evernote clients.
Here are the pinned applications
My VSCode setup (shout out to Wes Bos for the Cobalt2 theme!)
Some of the VS Code extensions I use
I try to keep my phone fairly zen. Here is the home page.
The page to the left is for quick capture, quick utilities, and playing podcasts/music.
I use Todoist with GTD for todo tasks so the page to the right is completely dedicated to the Todoist widget.
If I were to start a new “Software as a Service” app today that needed the works, I would most likely go with: React and React-Native with a shared Redux layer for business logic
- Node.js (potentially with Express depending on Serverless)
- AWS for almost everything
- Terraform for managing infrastructure
This question could go a number of different ways, especially because it takes a dozen or so repos just get a front-end project off the ground. That being said, here are a few that stand out:
-React.js (https://github.com/facebook/react/): Not really a surprise, React is my go-to for front-end apps.
-Lodash (https://github.com/lodash/lodash): A lot of people like using Lodash for nearly everything, but I much prefer using native functions. However, Lodash out of the box gives you important functions like debounce, throttle, and memoize. Those functions become crucial for high-performance apps.
-Webpack (https://github.com/webpack/webpack): Webpack occasionally gets a bad rap for being complicated, but it’s a necessary evil for shipping performant web apps. They’ve also come a long way in trimming the complexity and learning how to work with Webpack can make a world of difference to your application.
-Redux (https://github.com/reduxjs/redux): Now that React context is getting a lot more popular, developers are no longer needing to use Redux as much. However, they are assuming that not using Redux “as much” is synonymous with not using Redux at all. Redux itself shines as a state manager and as a spot to put all of your core client business logic. You don’t need to put your modal state and your button toggle state into Redux, but database records that you just fetched work great inside of Redux.
I’m a big fan of serverless technologies and infrastructure-as-code. Over the next few years, I expect the standard to become some combination of serverless and Docker/Kubernetes. Infrastructure-as-code is promising (especially Terraform), but I think it might be a little farther away.
On the front-end, I’m excited for Webassembly. All of the amazing engineers that work with low-level programming languages (C++, Rust, etc.) can now work on the browser. This means we will see a lot of new, graphic intensive, number crunching programs coming to browsers.
I’ve also been using react hooks and I’m finding them helpful in organizing my thoughts for front-end apps. Creating a reusable “packet” of code helps lead to coherency in complex codebases. Once you get used to them, hooks do just that.
If I’m working on a new feature, I start by doing research. I typically create a note and start thinking about the feature from first principles. I’ll try to figure out why users and product managers want this feature to exist, what the goal is, what would the ideal feature look like given infinite resources, how could that ideal feature work in the current project, what are the time/effort constraints, and what are the obvious tasks that need to be completed. I’ll talk to other developers to talk through some of the contentious areas and try to dump all of the information I have into that note.
Once that is done, I try to break up each step into a modular chunk. Each chunk should be usable without the context of the entire feature. My goal initially is to get the smallest possible working solution, just to bridge the gap between nothing to something. During this time, I’m constantly thinking about ways to simplify the structure of the code and trying to further understand the core of what needs to be done. I’ll also experiment a lot and try out a few different solutions. You can plan all you want but you need to remain flexible.
Depending on the feature and what type of environment I’m working in, I may write the tests firsts. But regardless of the order, I like to have some tests as soon as it makes sense. You can often map the requirements of the feature directly to test cases and once all of your tests are green, you are freed up to try to refactor and simplify until it feels as simple and elegant as it could be.
After something is basically working and it’s been refactored, I begin a bout of paranoia and review my code frantically, trying to think about corner cases I may have missed. I also review any noteworthy decisions I made with the other developers or product managers to see if they want to raise any flags. I find that if the feature is big, the best thing you can do is have a good night’s sleep before completing because when you wake up, you will most likely think of a more elegant solution than the one you implemented.
Then, it’s just continuous tweaks, bug fixes followed by test cases that will fail when the bugs are active, and then it is shipped out to the world.
I’m learning new rich text editing technologies at work. I am also in a perpetual deep dive into low-level browser APIs. Outside of work, I’m learning a lot of infrastructure technologies (Serverless framework, Terraform) and Machine Learning with Tensorflow and Tensorflow.js.
Dark mode was a highly requested feature at Evernote. We had wanted to implement it, but making the note “dark” was incredibly difficult. How do you take arbitrary content and styles and make them look dark? Then, assuming you get that done, how do you make sure the note can be saved correctly as a “light” note. Then, if you somehow get that done, how can you ensure that editing the note won’t break the styles when you attempt to flip it back?
After a ton of effort, I was able to create a system that used statistical regression to flip note styles to their dark mode equivalent. Then, there were a few secret-sauce tricks to make sure we could flip the note back and that we could edit the note reliably while in dark mode. This system enabled Evernote to ship dark mode on multiple clients. I’m still surprised that it works and I’m proud of the solution we came up with.
Early on, there is often too much of an emphasis on object-oriented programming. Although classes and objects are important, the best repos I’ve been a part of keeping the object hierarchy almost completely flat. Functional programming mixed with a flat object hierarchy is, in my opinion, the best mix. Ideally, you would even write all of your business logic with pure functions.
I would also learn the difference between imperative and declarative programming. That difference is subtle and it’s hard to wrap your head around, but understanding that fundamental principle will clean up your code a ton. Trying to be declarative will help to derive a lot of the “clean code” principles. (I found this article helpful in explaining this https://tylermcginnis.com/imperative-vs-declarative-programming/)
However, every city is different and many cities across the globe are years behind. Don’t automatically assume the developers you know are right when they tell you to learn new technology. You need to do your own research since many developers get stuck in their ways and become dogmatic about the technologies they use.
Working on the note editor is incredibly challenging. At a fundamental level, Evernote attempts to aggregate unstructured, arbitrary content into a “note.” This content could be random HTML that was clipped or pasted, images, files, embeds from other sites (e.g. Google Drive), general text editing, tables, lists, todo lists, and a myriad of other content types. Our goal on the editor team is to make that content viewable and editable. Bringing order from that chaos is a tough battle, but we are making big strides in improving our current solutions.
Evernote is hiring! We are looking for engineers in:
- Redwood City, CA
- Austin, TX
- San Diego, CA
- Santiago, Chile
You can check open positions at https://evernote.com/careers#jobs