Signal adds a bunch of new calling features: a dedicated calls tab, call links, raise hand button, emoji reactions, and much more. https://signal.org/blog/call-links/
"If I say to myself 'I Am The Only User' of the software I am writing my productivity goes through the roof and I've actually started to complete projects. It has made programming out of work hours fun again." https://blubsblog.bearblog.dev/i-am-the-only-user/
Simple opinions tend to be wrong. For example, some people say things like, “PHP sucks!”…but PHP powers most of the internet, and modern PHP has a bunch of great features. People who are dogmatic about process, like TDD, tend to be right in some situations but wrong in others. I usually like working with programmers who use nuance and understand tradeoffs, and I try to be that programmer myself.
Everything is more complicated than you expect. I need to be careful not to trivialize someone’s work, because it’s probably a lot harder than I think. Building a prototype is a lot easier than building something production-grade.
The most important problems are non-technical. “Real world” issues tend to be the most important. Am I building something that helps people, or hurts them? Is my team healthy?
Different approaches for different tasks, teams, and projects. For example, it would be irresponsible to build a pacemaker with no automated tests; people could get hurt! But it would also be wrong to stress about automated tests during a weekend game jam. “Good code” means different things in different contexts, and I need to tailor my approach to the problem at hand.
Do a “spike”. Sometimes, I try implementing a feature in the smallest possible amount of time, with awful code, horrible hacks, and lots of TODOs. Once I have something working, I clean it up. I’ve found this to be a useful way to see where the challenges lie, and a pretty good way to build things quickly. See https://ntietz.com/blog/throw-away-your-first-draft/
Making useless stuff can be a great way to learn new things. Not everything needs to be productive, but sometimes it can be anyway! For example, I spent a bunch of time writing a custom PNG encoder for a side project. I never thought it’d be useful. But then a few months later, I needed to write some code to detect animated PNG data for work, and it was trivial to write because I knew exactly how to do it.
When presented with a difficult task, I ask myself: “what if I didn’t do this at all?”. Most of the time, this is a stupid question, and I have to do the thing. But ~5% of the time, I realize that I can completely skip some work.
It matters who I build for. Humanity is in trouble. An incomplete list of problems: climate change; war; authoritarianism; genocide; poverty; inequality; surveillance. I shouldn’t waste my time building software for people who are hurting people. I shouldn’t waste my time building software to make the boss rich, even if I’m the boss. There are a lot of jobs where I can use my skills to help people…I should work there if I can!
The distinction between “simple” and “easy” is important. Simple is the opposite of complex. Easy is something else; it’s familiar. Understanding this distinction has helped me develop simpler software (though I still have a ways to go on this front). See https://www.infoq.com/presentations/Simple-Made-Easy/
The functional programming people can be quite smug, but they’re often right. It’s harder to do a good job with object-oriented programming, and easier to do a good job with functions that operate on immutable data.
There are lots of ways to document my code. Some ideas: explicit documentation; good names for functions and variables; breaking up code sections into named functions; comments; log messages.