“There are only two kinds of languages: the ones people complain about and the ones nobody uses” — common quote
This is a fun statement if you think about it. Because the languages everyone complains about are obviously better than the ones nobody uses. It seems controversial but a simple thought example shows why it has to be this way.
Imagine a world where the mainstream languages were worse than the niche languages like Haskell or Crystal. In this world Haskell has a clear 2x productivity advantage over Java. Since Haskell is clearly better than Java most projects that use Haskell will execute roughly twice as fast. Double productivity is enough that companies using Haskell will be able to achieve the same results with less money spent on developers and thus achieve higher profits. We should see companies that don’t use Haskell going out of business. Eventually we would expect all greenfield development to happen in Haskell.
You might say well, “Haskell isn’t really twice as good as Java, it is only 20% more productive overall”. Well, 20% averaged out over hundreds of thousands of software engineers is a huge amount of money. My employer would very happily take a 20% increase in productivity if it were on the table.
There has never been a consensus moment in the industry around niche functional languages. Instead people say they wish they could use them while making actual money writing Java code.
Personally, I would really like to use a better language than Java. Unfortunately, we don’t seem to live in that world.
Becoming a ‘Senior’ engineer in three years is a ridiculous concept. Programming is a complex enough endeavor that you can’t learn the basics of most areas in 3 years of work experience. By the 3 year mark great programmers will have achieved a high level of expertise in one programming domain. For example 3 years might be enough time to master web development with Django. But web development with Django is just one of many domains within computer programming. Mastering Django does not require a software engineer to learn anything about operating systems, low latency computing or graphics computing. In some environments web developers might not have any involvement with DNS or how their software is made available to users as deployment is handled by a infrastructure as code team.
In my case I was promoted to ‘Technical Architect’ and team lead in under three years at my first job. I was really good at my job and worked well in the consulting business. At that point in my career I knew a lot of stuff application development, frontend development, automated testing, devops, etc. But I felt under qualified and wanted more money so I ended up taking a demotion to move to FAANG.
Why can people get promoted to ‘Senior’ Engineer so quickly in the software industry? The main reason is the expansion of the workforce. With double digit employment growth each year, there are a lot of inexperienced programmers in the workforce. Having three years of experience is a big deal in an environment where a large portion of working programmers have under three years experience.
The issue is that three years is not really enough time to master software development. Honestly, in three years you are more of a ‘journeyman’ programmer than a senior one. You wouldn’t expect a three year senior to be able to bootstrap a new engineering team or to set the engineering culture at a new company or division. There is simply too much to learn about how software works.
In my particular case, I felt that my ability to deliver projects was great. But when it came to designing software abstractions or building software architecture, I felt like I didn’t know enough to do a good job. I had read books like ‘Domain Driven Design’ on software design patterns, but knowing patterns and actually designing software are not the same thing. In my opinion software agency work is not the best place to learn software architecture design. You simply don’t stay embedded on projects long enough to see the longterm costs and evolution of your designs.
How do you hash out architecture and design at a remote only company? Slack chats and phone calls are a slow way to communicate with an entire team. And miscommunication with people 1000s of miles away can cost you the time and money you were hoping to save by working remotely.
The Design Document workflow
Some companies have a design document centric workflow. At the beginning of a project instead of writing Jira tickets or tasking out stories, an engineer will spend some time writing a 3-10 page document which describe the plan of attack for the project. This doc will include assumptions, design decisions and constraints, as well as a summary of the changes to be made. The document is not an exhaustive specification, but can include proposed interface or library changes. Then the team will have a review session to read and ask questions about the design. Next after some revisions, and possibly a follow up session, development will begin.
Google Docs or any other shared document tool is sufficient to support the document review process. If you want to make the process truly asynchronous you could rely only on document comments and skip the meeting all together.
Typically, a design document should be required both embarking on any significant project or feature addition. Adding a new button to a web form would not need a document, but building a new web service or adding a major feature would.
When I worked in a distributed consulting company we used this workflow for proposals and Level of Effort estimates. But software design was usually handled by discussion and whiteboarding followed by implementation with half-hearted documentation occurring at the end of the project. A design document process would have helped share design between the east and west coasts keeping more of our projects on the same page.
Voice assistants are wide software. In the industry we call it the ‘long tail’ of functionality. There are hundreds of ‘tasks’ that your Alexa or Google assistant can perform for you. You probably don’t know that most of them even exist. But not knowing that these tasks exist costs you nothing. The fact that you can buy pizzas via Alexa has no impact on your ability to get news briefs. You can do either without ever engaging with the other.
This ‘long tail’ attribute makes voice assistants extremely wide software. Alexa can do hundreds of things which could be stand alone applications. But the trade off is that voice assistants are extremely vast and don’t do anything particularly well. Over the time the ‘main’ functionalities will be refined and optimized. But Voice assistants will always suffer from the ‘long tail’ problem in that they have extremely wide feature sets.
Wide software spreads across multiple domains. More domains means leaky abstractions and mapping software.
Deep software focuses on a single domain. Perhaps it is an order book or a workflow execution engine. Deep software has a clear purpose and domain. Wide software does e everything.
Over time deep software converges on clean abstractions and easy to understand code. Wide software on the other hand is never finished. Wide software is naturally expansive. There is always a reason to add a new functionality to a voice assistant. And in fact there is no real barrier to entry. Adding a new functionality to a voice assistant is a net positive to the system as a whole. The negatives of adding a new domain are already baked in and many customer will enjoy the new functionality.
Deep software can be finished. It can solve a problem in one domain and be done. Hadoop is an example. No one has heard about miraculous developments in HDFS this decade. Hadoop is essentially feature complete and in maintenance mode. In reality development continues, but is it really new stuff or refinements?
Wide software cannot be ‘finished’. Wide software is an infinite sinkhole. Adding more code makes the sinkhole more valuable so more code keeps getting added. There is no real way to ‘solve’ the problems of wide software. You can partition wide software such that each domain exists separately. But if you allow one domain to reference another, now you are back into the pit.
Software Leviathans which I’ve discussed in another post (https://www.sledgeworx.io/software-leviathans/) are wide software. Supporting more domains typically increases the value of the leviathan as a whole. A voice assistant which can order dry cleaning is better than an assistant that can’t order dry cleaning. Overall there isn’t a trade off between the two. One has an additional ‘ability’ with no downside to adding that ability. You would have to make a voice assistant that only handled one domain to escape this constraint.
Wide Software isn’t magical. Wide software does too many things to be incredible at any of them. Since there are countless features the team has to spend a lot of time making sure they don’t break anything. In software leviathans not breaking things is particularly difficult because nobody actually knows what all the features are.
Since wide software is always being pushed to add something new. Energy and design focus are constantly shifted towards new features and problem domains. New domains expect old domains to support new features.
Wide software suffers another problem which is that even if some domains in the project are invested in continually say music for example. Even if music functionality is iterated on again and again. That particular domain being awesome doesn’t change the flavor of the beast. It is still a ball of mud, dirt, rocks, etc.
My belief is that most tech startups going forward will be 100% remote. Setting up an office for a company that might not last isn’t a great idea. And after 2020 spending your runway on an office is basically wasting money.
The complication is that remote work requires more discipline from the team than office based approaches. If you have unmotivated employees, managers, management skills, or outdated processes you will not be as productive as a remote company. Going forward there will be a dichotomy between startups that try to succeed with the colocation approach and startups that commit to remote work. My belief is that overtime collocated startups will consistently fail against remote startups. The reasons remote startups pull ahead are lower fixed office costs, easier access to talent at lower prices and that remote work requires more disciplined processes.
Fixed office costs
Offices being expensive is an obvious fact for most people. Offices are lowest common denominator environments with constant pressure to cut costs. Workers consistently complain about noise and distractions in ‘open plan’ offices but they have stuck around because they are cheap.
Remote work allows everyone to setup their own ‘dream’ office space. You can get whichever chair you want. Any combination of monitors and other peripherals. You can play loud music or install noise canceling tiles to ensure silence. Workers also save hours each day compared to commuting, not to mention the environmental benefits.
Easier access to talent
Access to talent is a major problem for startups. Before achieving profitability startups have limited time to find software engineers and limited money to pay them. Hiring remotely allows startups to access a large number of employees who live in low cost of living areas. This can either be lower cost of living cities, cheap small towns or even other countries.
For example entry level software engineers typically make over 100k in ‘major’ software areas like Seattle, San Fransisco, San Jose and New York City. But those same engineers will typically make 60-70k in second tier cities despite having comparable amounts of skill and experience.
Higher Process Bar
A remote first company requires better processes and more motivated employees than the typical office micromanagement scenario. Failing to set up good processes in a remote environment will result in unmotivated employees that don’t do any work. You can’t just assume communication will happen in a remote environment. In the office employees gossiping can make up for a lot of bad communication processes. Whereas in a remote environment employees need to go out of their way to setup a zoom call.
Companies with good remote work processes will experience higher average productivity than was ever achieved in classical ‘open office’ environments.
In a remote work environment you are forced to invest more in onboarding, training and cross team coordination. In the office you can simply walk over to the frontend team’s section and introduce yourself to the new team member. But working remotely without a process to include the new guy, he could just sit in the figurative corner for weeks without interacting with anyone.
There isn’t any way for new hires to ‘overhear’ conversations about services or context that they don’t know about when working remotely. So those thing have to be documented and included in the formal onboarding process. Which means you actually have to document your software for real.
Meetings need to be orchestrated better when done remotely. You need to have an agenda and focus on solving the problem.
One meeting that works very well remotely is the architectural document review. A 60 minute meeting would go as follows.
20 minutes to read and comment on the document in google docs
Short discussion of each text comment made in google docs starting from the top of the doc
Discussion of action items and any other final comments
What happens next?
The pandemic caused a massive shift in software engineering working conditions. We went from maybe 5% remote to 95% remote work during the crisis. Now that things are normalizing I expect a gradual shift back towards 90-10 or 80-20 split of hours worked in office vs remote. The fact of that matter is that a lot of people like working in an office. And many bosses think micromanaging is necessary.
Going forward there will be a lot of demand for remote software engineering jobs and many companies will jump on the chance to acquire programming talent at competitive prices.
The in-office premium.
Going forward I expect to be paid more to work in an office than to work remotely. Working in an office costs me more in time and transportation costs. It also limits my freedom during the day. To make up for the inconvenience of needing living within commuting distance of jobs I expect to be paid an additional 20-30% premium over what I would charge for remote work.
The legal burden for international remote work is way too high. Each country has different requirements and the company is essentially required to establish a corporate entity in every country they have employees in. Even if they do not actually do business in that country.
Even in the United States having a remote worker in New York city could require a company to start paying additional taxes to New York state due to establishing a ‘nexus’ in that state.
Over time I expect these legal hurdles to be simplified or simply ignored. Functionally, it doesn’t matter where code is written. Remote workers will push for legal accommodations. Nations will be forced to compete by providing supportive legal conditions for remote workers and employers.
One thing that I didn’t expect to come out of remote work is that annoying coworkers are a lot less annoying when they aren’t in your face. You can basically avoid all non-work related communication with people you don’t like. For example we have one guy on my team who goes on rants and never gives people a chance to cut in and steer the conversation back on topic. In the office I would end up listening to this guy talk for minutes at a time without getting a chance to talk. Now since I’m not sitting across from the guy I can avoid his negatives and appreciate his dedication and work more.
For example processes like 6 month RSU vesting are not tenable in a remote first world. You cannot afford for disgruntled employees to wait 6 months for a vest date before they quit.