Platform Thinking

Effective email is either a pointer or notification

Email is the only decentralized communication platform that has widespread usage. And this is more amazing considering it was invented in 1971. Email is an amazing technology and has stood the test of time.

However, there are challenges with email:

  1. It can be difficult to find information in emails at a later date.
  2. Visibility is limited to the recipes of the email.
  3. Discussions often don’t happen in the context of the work being done.
  4. Information is not organized very well.

I follow a few rules regarding email:

  • Whenever possible, don’t send information in email, but rather point people to information in a more permanent location (Git repo, Wiki, Discourse forum, etc.). If the information does not exist, create it, and then send the email.
  • Keep project-related discussions in Git pull requests, issues, forums, etc.
  • For transient discussions, use chat tools like Discourse chat, Signal, Discord, Slack, etc. This is more fun, and keeps email from clogging up with chatty stuff.
    This keeps the information accessible to everyone involved. It is also way more efficient as discussions and information are stored in the context of the work.

It is still very useful to receive email notifications when a piece of information or a discussion is updated. This is quick to process and gives everyone interested the opportunity to watch the stream of activity as it flows by. Most systems give you options for tuning how many email notifications you receive based on your time/interest.

Accessibility and context – the keys to effective communication and information.

envsetup.sh – a very useful automation technique

During a Android development stint, I learned about the envsetup.sh concept. This is a script that contains numerous functions get populated in a shell envrionment when the script is sourced. There two ways to source the file – you can type:

source envsetup.sh

Or use a β€˜.’ for a shortcut for source and type:

. envsetup.sh

Most of my projects and Git repos now contain a envsetup.sh file (examples: Simple IoT, Yoe, TMPDIR Podcast). Typically all of the functions in the file have a common prefix. This gives them a namespace and allows you to see all the functions quickly in your terminal by typing <prefix><tab><tab>.

Why shell functions instead of something like Make, Earthly, Nix, Task, Mage, Pants, Bazel, Python …? Shell script is about the simplest abstraction on top of typing commands. Thus, if mostly what you need to do is execute a sequence of terminal commands, then shell functions are very efficient at doing this. A shell function is often the best documentation for how to do something – it is almost like a powerful checklist. There are no dependencies – every Linux and MacOS system comes with a shell built-in. envsetup.sh functions can often be used directly in CI/CD and other build systems (like Yocto/Bitbake tasks).

There are some common objections …

Shell is not cross-platform to Windows. That is unfortunate, but I rarely use Windows, and most developers I interact with use either Linux or MacOS systems. However, this may change with Zephyr as MCU developers traditionally have used Windows.

Why not use something more powerful like Make? With modern programming languages and build systems like Go, Rust, and Yocto, the is no need for yet another build system. The complex issues like dependencies are already handled. Thus, all you need to do is remember how to kick it off.

Why not use Python – everyone uses Python for everything – it is the most popular programming language ever! Python is great if you need to do something more complex, but it is a more complex programming abstraction. And mostly what you need to do is record a sequence of commands, any abstraction costs you more than benefits.

Why not a shell script that you execute instead of sourcing a script that populates functions? I’m not sure – the sourcing just seems more ergonomic to me and simpler. If you need to run a script to execute a command, then you need to process command line arguments, etc. You are now programming, and programming is what we are trying to avoid in envsetup.sh. Also, the functions are not as discoverable as when they are populated in your environment.

Shell scripting is not without its tradeoffs – when you do need to program something in shell, it can be very painful and errors can be subtle and hard to catch. However, AI tools are very effective at writing shell script, so this can be a big help. Linters and formatters are also very good at catching problems early and making your scripts more readable (more on this later).

In summary, think of your envsetup.sh file primarily as documentation. Create one in every project and instead of documentation how to do something, create a shell function. Your future self will thank you.

Thinking, Designing, Developing, Engineering …

If we are thinking without writing, are we really thinking?

If we are designing without sketching/drawing, are we really designing?

If we are developing software without iterations/testing, are we really developing?

If we are engineering without building prototypes, are we really engineering?

Something happens when our work is implemented in an external form that is staring back at us. It speaks to us, exposes the flaws, and shows us where improvements are possible. When our work is good, we can recognize it and find motivation for the next phase.

Yes, it is possible to do some things without shipping, but when we ship our work in the form of writing, drawing, prototyping, and iterating, a world opens up that we could never see before. New connections are made.

Optimize your habits/processes for shipping something – your work will get better.