Welcome to DevChat #10!
So... I've given up on clever salutations. But hey, that means more time for CONTENT.
Here's what's we've got for today:
- ♾ Moar emoji
- ❄ Seasonal Affect 😭
- ⏱ Work hours philosophy
♾ Moar emoji
I admit, as an Elderly Millennial, I've been a curmudgeon when it comes to emojis. I've avoided using them at all costs, and as they crept more and more into my technical life I leaned deeper into my distaste for them.
But... why? One of my core principles is to let people like what they like. People like emojis. Why am I being such a butt about it?
Last week I saw a pull request in GitHub that was 💧dripping💧 with emoji. It had 🤩personality🤩, and ✨pizazz✨, and it didn't take itself too seriously. I loved it. So I guess it's time for me to stop being such a 🍑 and learn to love the emoji. The problem is that now I don't know how to use them, so it's all fellow-kids territory from here.
Lucky you. 🎲🎲🎲
I'll try not to let it get TOO out of hand...
Pro tip: On Windows, you can use
Win . to pull up an emoji window!
(I originally told my teammates about this by writing
Win + ., but then they tried hitting the plus key, which pulls up the screen magnifier.)
❄Seasonal Affect 😭
In the early issues I talked a lot about my (fortunately mild) depression and (less mild) ADHD. After the initial high from getting pharmacological treatment for the latter, I have found myself swinging back into frequent lows. It isn't constant like before, at least. But weirdly the fact that it comes and goes somehow makes it harder, since I get to spend some time reacquainted with feeling pretty good.
So that's lame.
It's possible that I'll need to throw a dash of anti-depressant into the mix to mitigate this, but the fact that it isn't constant is interesting to me. My low mood originally started a couple of winters ago, and my best guess was that it was Seasonal Affect Disorder (the aptly-named "SAD") that just sorta didn't go away. We're at the start of spring, so about half of all days are cloudy and rainy. Those also seem to be the days that I just feel out of sorts.
How stupid is it that something as mundane as the weather can throw your brain chemistry out of balance?
I think that there's also some stuff going on that I do have control over, so I've started some experiments.
The first thing is that I've realized I'm noise-sensitive when my ADHD is untreated (right after waking up), and that this sensitivity sets me on edge. The second thing is that I generally feel like I have no control over my time. Fortunately, both of these can be addressed by experimenting with the workday.
And that brings us to...
⏱ Work hours philosophy
I truly love my work and my team at Bscotch. But I also must do the work and, more importantly, I have to do it in a way that makes sense for the broader team and our goals. There's something about the work being required, and me not having control over the how that puts a damper on it. This is dumb, since if it wasn't strictly required I'd happily do it anyway.
Emotions are aggravating.
But it's not just the fact that work is required, it's also that it isn't structured specifically for me. As a team we need to be able to count on each other, and we need to all be confident that we're fulfilling our obligations to each other. The easiest way to hit both of those at once is by using time. Total time spent, assuming that time is well-used, is an okay metric for contribution given that there's a strong social belief in this being fair. And if we're all working at the same time, reliably, then we all know that if we need something from a teammate we can get it. Finally, we can build group rituals and mechanics into the workday, such as book-ending with stand-ups and stand-downs.
And so we end up with a standard workday: between 9am and 5pm, everyone shows up at the same time, focuses on the work, and then goes home to do home stuff. We take that hourly work commitment and compress it all into a single block of hours. The morning starts with scrambling to get ready for that workday. The workday consists of scrambling to get the work done, and then to get back to work after breaks. And then the workday ends with scrambling to get done in time to get home (if not working from home), make dinner, have family time, and do house chores.
Everything is batched. Everything is compressed. Work and home aren't allowed to mix. There is no slack anywhere. Just racing from one task to the next while constantly being drained of energy. A Sisyphean nightmare.
After all that, it's no wonder I'm exhausted.
But hey, then it's the weekend! Except I didn't get to take care of most home chores during the week, because I was at work when all the other businesses were open, and I was too drained every evening to chip away at chores when I had the time. Now the weekend becomes all about either doing chores or feeling guilty about not doing them.
Here's the thing, though. I love my work, and I love my home. Sure, not the chores related to home. Though even then, why not? Why shouldn't I enjoy taking care of my space? Every evening I have 4-5 hours in which to have dinner, socialize, do housework, and hobbies. That's actually a pretty solid amount of time. So I have time. I enjoy what I do. I love my home life. Why is this difficult?
Last weekend I was discussing this with my wife, Jen, and we worked together to fully articulate all of this and think about what we could do about it. One of my core beliefs, developed through our experiences running Butterscotch, is that problems are almost always structural. People are usually doing their best, and the things that make "their best" so often "not good enough" or even actively bad are usually the fault of the structures not enabling them.
Structure is always the first place to start. The obvious structure at play here was how my time was arranged. The question, then, was how could I rearrange it?
Jen and I came up with the first experimental schedule and talked through all the whys of its design. This required us to also think through the whys of our home-life schedule. The most surprising realization was that we needed to change how we thought about dinner. Yes, that seems mundane. That's why the problem was so insidious.
Dinner is classically presented as the event where any socially-healthy co-habitating group gathers around a table and chats about their day over some elaborate meal. All customs are intended to solve some problem or create some benefit. However, customs are general solutions. Over time their practice diverges from their purpose. They begin to exist for their own sake, and the whole thing about customs is that they mostly go unquestioned because "that's how we've always done it."
What is the every-evening-group-dinner custom meant to solve? My best guess is that this custom is for the following use case:
- The members of a co-habitating unit are usually geographically scattered during the day (at work or at school), so evenings are the only time when they can all gather.
- Everyone needs to eat, and meals are costly. Batching the process and dividing the labor makes it more efficient for everyone.
- Group members have diverse interests and goals, and need some sort of commonality to ground and sustain their relationships. Food provides an excellent commonality.
Jen and I both work from home, and both have significant control over our schedules. We're also into each other's stuff, and have video games as a common hobby. We don't have kids, so we only have to worry about maintaining a meaningful relationship with each other.
In other words, classic evening-group-dinners do not satisfy our use case. When you use a solution for a problem you don't have then, well, it's likely you're actually creating problems instead!
Group dinners are costly and mentally taxing due to their planning, setup, and teardown. Jen and I both have ADHD, so our capacity to do mentally taxing stuff that we aren't able to hyperfocus on diminishes dramatically throughout the day. Plus, I end nearly every workday hyperfocused on a programming problem that I want to keep working on. The end result is that dinners feel interruptive, the work feels like chores, and neither of us are in our best mental states for positive socializing.
But we do still need to eat, and we do still want to make time to socialize.
We figured that by having the costs of food management happen during the middle of the day, instead of the end of the day, we could get all the benefits but without so much of the cost. Plus we get to follow lunch with getting right back to stuff we can hyperfocus on, so that we no longer have to interrupt that work for dinner later.
With all that in mind we put together a schedule. The constraints were straightforward: my schedule had to compatible with Bscotch's schedule and my wife's (fortunately my wife controls her own schedule, we both work from home, and the Bscotch team is all about experiments). The goals were also straightforward: be able to feel more in control of my life, create slack to make home chores manageable, feel less frantic, ensure quality family time, and work with my emotional needs and how my brain works.
We ran the experiment last week. Here's what the schedule looked like and why:
- Morning Slack: Woke up an hour earlier to reduce the feeling of rushing around in the morning.
- Controlled Momentum: Had the first things I did be to make coffee, sit down at my computer, and do some reading, study, or admin tasks that I just felt like doing. Maybe some work stuff, maybe some home stuff. Nothing that had to be done right then, though (unless I also wanted to do that thing). The goal was to make the start of my day something that I felt control over, while also kicking things off with the momentum of accomplishment. (Side note: Jen and I realized that we both have noise sensitivity in the mornings (thanks ADHD!) and have thus been accidentally annoying the crap out of each other during our morning routines. By having the first hour of our day consist of separate activities we avoided that.)
- Morning Chores: After that hour of getting my brain online, building momentum, and feeling like I was in control, I took care of things I had to do. Feeding the cats, all that personal hygiene stuff, etc.
- Pre-Work Slack: The workday starts at 9am sharp with a stand-up. To avoid feeling rushed I needed to make sure that all the prior stuff left a nice window of time where nothing specifically had to happen. This allowed for catching up with Jen and talking about our plans for the day, time to play with the cats (instead of just doing chores related to them), and getting settled into my workstation without any sense of urgency.
- Morning Work: Regular old workday, until lunch at noon sharp. (The "sharp" part was meant to ensure that I would be guaranteed to make room for the next bits.)
- Lunch Slack: A long lunch break from 12pm-2pm. Previously lunch was a random event that my wife and I both shortened as much as possible in order to get back to work, and dinner was when we put time and effort into food. As discussed above, that didn't match our use case. So during the lunch break we made food and had quality family time.
- Afternoon Chores: That 2hr lunch window is long enough that we usually had time to handle some household chores and decisions after eating. Importantly, we could handle them together. Plus, it would typically be from ~1pm to 2pm, which is the perfect time to be able to call or even visit other businesses (since many offices are hard to reach between 12pm and 1pm). Finally, since this was a daily occurrence I didn't have to shove all housework into the weekend, or assume I'd have to take a day off sometime to handle chores that have to happen on weekdays (like dealing with banks).
- Afternoon Work: Regular old workday, until stand-down.
- Evening Slack: After stand-down, keep on going for as long as I want, now that there's no dinner pressure. This let me get the production benefits, and the mental health benefits, of allowing my hyperfocused state to roam free.
- Controlled Cooldown: By this point, there was nothing else I had to do, and no particular time pressure (barring social and other evening events, but those aren't daily). So I got to choose how to wind down my day.
It's only been a week, but that one week already felt a lot better. We'll see if it continues that way, or if additional tweaks are needed.
I think the takeaways here are that:
- Customs are arbitrary and are not designed for your use case. Everything you do because "that's how it's done" is probably doing more harm than good, and is worth evaluating against your specific situation.
- The standard workday is built around the goal of compressing all work hours into the tightest window of consecutive hours. This makes a lot of sense when many people need to be working at the exact same time, especially when they all must go to a central location to do it. As soon as both of those things are false that structure is arbitrary. In all cases, it's not a design pattern meant to fit with how you do your best work, your particular mental properties, nor the structure of your home life and time.
- Work-life balance is not minimizing one in favor of the other. It's about finding structural ways to achieve your goals within each category, given the constraints created by each.
Have you found ways to design your home and work life around your specific reality? Tell me about them!
I've gotten into the habit of looking over external source code before importing it, especially for small modules, to get a better sense of what it's doing and how complicated it is. When the amount of code is small and I'm not interested in new features/fixes that the maintainer might add, I typically jam the source right into my project.
In the process, I had to deal with a dependency for that code that was somehow extremely popular but also un-typed (most popular open-source modules on npm have Typescript types created by the community). I had two options: provide those types, or also port that code to Typescript.
That dependency is mpath. I dug into the code and saw that there wasn't a huge amount of it. And I was already outside the normal workday in my new Evening Slack time, so I decided to do it the fun way. I ported it to Typescript, with the module built using ECMAScript modules instead of CommonJS (don't worry about that if you don't know what it means), and published it to npm as @bsotch/mpath.
The process was extremely educational.
The first step was to get the environment all properly set up. I hadn't had to do this for a while, since I've mostly been working on existing projects and had previously created a template for new Typescript projects. But I also had never published an ESM module, so my template wasn't quite right anyway. I already learned a bunch of stuff just in trying to get all my configurations correct.
The next step was to simply rename all the
.js files to
.ts, and put them into a new root folder as the "source" since Typescript requires a compilation step.
After that was the game of trying to get the code sufficiently typed so that those types would be helpful, all while trying to understand what the code was even doing. The neat thing was that Typescript became a tool to assist in its own porting.
Understanding code is all about building context and assumptions, and then seeing if those assumptions hold true as you read more code and run tests. Typescript is a way of declaring assumptions about code. As a tool, Typescript's job is to tell you when one part of your code violates the assumptions you stated in some other part of your code.
As I read the code I added types based on how I thought it worked. Then Typescript would reveal downstream errors because I was wrong in some way. That led me directly to the code that would be the most helpful in helping me fix my incorrect assumptions!
Once I got the thing fully typed without any remaining Typescript errors, meaning that it was internally consistent, I then went to the test suite that the original authors had created. It was riddled with Typescript errors. Once I fixed those that had nothing to do with the code being tested, I was again left with a collection of errors that directly revealed incorrect assumptions I had made. That allowed me to tweak the types, which would sometimes result in new errors in the original code!
By bouncing back and forth between Typescript errors in the code and its tests, I was able to eventually get everything to be fully consistent. Once it was fully consistent, the surprisingly-complex API provided by that code had become fully understandable.
Well, mostly understandable. It's doing a lot of undocumented stuff that I think is meant to be internal, but it's hard to tell.
The biggest benefit of the port was that the functions provided by the
mpath module were easy to use incorrectly because they allowed you to pass arguments in several different ways and had no built-in error-checking. By using Typescript to fully annotate this (using overloads any consumer of the API can discover if they're using it wrong while editing.
If you're already a Typescript convert, I'd love to hear about what the deciding factor was for you.
Until next time
That wraps DevChat #10!
I've been having a great time hearing from readers. If you haven't said hello, please do!
Share with others by forwarding, or link directly to the archived post.
Have a great week!
Get early access to new Dev Chat content with our newsletter!