CJ Eller

Classical Guitar by Training, Software by Accident

I fixed a technical problem I was having at work. Sure, I'm relieved, but the most frustrating part of it all is that I didn't have the satisfaction of knowing what the problem was exactly. All I did was remove cruft to start back at square one. No idea what cruft was the culprit. It just works now.

Something I've been trying to get better at is accepting that sometimes you won't know why something is now working. Not from a lack of wanting to understand, but from an acknowledgement that, no matter how much you dig, you won't understand. And that's okay.

There's a part in the video I shared yesterday where MPJ says that his mantra as a software developer used to be:

It's my job to bang my head against problems until I succeed.

But he soon realized that success might not be the end point. Sometimes problems can't be solved, can't be understood, can't be grasped. It was only until he removed that “until I succeed” part did he reach a healthier relation to his craft.

It's my job to bang my head against problems.

I wonder if this also aligns with accepting the mystery of certain solutions, admitting to not fully understanding how something was fixed, taking credit for it like some ego-inflated developer. Perhaps that is part of that healthier relation to the craft of software & engineering that MPJ was talking about.

Have you ever clicked on a banana peel? You know, clicked “Delete” on something you didn't mean to delete? That was me today with some production resources. Poof. An entire AWS VPC gone. Thankfully this wasn't used by anyone, but it left me back at square one for a project I've been working on. Now I'm encountering bugs I never encountered before, having to push back deadlines, feeling stressed out. An unproductive day due to a single click. It's not even the grandest of gestures — just a muscle twitch of the index finger. But oh how much can go wrong with but a twitch.

Of course I feel like I am catastrophizing, but I am not experienced in the world of engineering and am taking it personally. I can't help but feel terrible. Perspective will let me grow from this experience though. There will be days like this.

I am reminded of a video I watched 2 years ago that resonate with this feeling more now than when I watched it initially. Maybe it will resonate with you too.

There's this neat software projected called Termible which creates terminal apps that you can add to your website. Just a little bit of JavaScript is all you need to get started. The application of such an application is quite fascinating:

[Termible allows users to] instantly interact with your product (a CLI tool, REST API, programming language, etc.) from the terminal without installation or even leaving the page.

A software terminal is already a bit of an abstraction. Scott Hanselman does a great job of explaining this:

The word Terminal comes from terminate, indicating that it's the terminating end or “terminal” end of a communications process. You'll often hear “dumb terminal” when referring to a text-based environment where the computer you are sitting next to is just taking input and showing text while the real work happens at the other end in a mainframe or large computer.

TTY or “teletypewriter” was the first kind of terminal. Rather than a screen you'd have a literal typewriter in front of you. When you type on it, you're seeing the text on a piece of paper AND inputing that text into a computer. When that computer replies, you'll see the typewriter automatically type on the same paper.

When we refer to a Terminal in the software sense, we're referring to a literal software version of a TTY or Terminal. The Windows Terminal is that. It's really good at displaying textual output. It can take input and pass it on. But the Terminal isn't smart. It doesn't actually process your input, it doesn't look at your files or think.

If a terminal displays textual output back, what's really doing the heavy lifting? As Hanselman further explains, it's the shell:

A shell is the program that the terminal sends user input to. The shell generates output and passes it back to the terminal for display.

How do I find out what shell my terminal is using? Apparently it's an environmental variable I can call upon.

echo $SHELL

If you run that above command on the Termible terminal on their home page, for example, it'll return that the terminal is using a bash shell. So we have a software terminal using a software shell.

And how does that terminal/shell pairing run on a browser in the first place? How does it become so easy that you can just add JavaScript to your site? Through the power of another abstraction called Docker. As Wikipedia explains (because I couldn't do it justice),

Docker is a set of platform as a service (PaaS) products that use OS-level virtualization to deliver software in packages called containers. Containers are isolated from one another and bundle their own software, libraries and configuration files; they can communicate with each other through well-defined channels. Because all of the containers share the services of a single operating system kernel, they use fewer resources than virtual machines.

And that abstraction is probably hosted by a cloud provider, yet another abstraction, so that one can add some JavaScript fairy dust (an abstraction) to have a virtual terminal sitting on their website.

These layers of nested abstractions never cease to leave me utterly dumbfounded in wonder. It's no wonder then that someone who likes to have his head in the clouds wants to engineer them as a profession.

I just gobbled up Jay Parini's beautiful coming-of-age travelogue memoir Borges and Me. The center of this book is Parini taking Argentinian writer Jorge Luis Borges on a road trip through Scotland. At this point in time Borges is blind, so along with leading Borges through the world, Parini has to describe the world to him. At the beginning of their road trip there's a great exchange as Parini attempts to describe the view.

“It's quite dark, the sea, in broad daylight,” I said, fumbling to describe what I saw. “There's a surf.”

“This is not specific enough,” Borges chided. “Talk about the running waves, the white horses on the water. Dark is not detailed. What are the colors? Find metaphors, images. I want to see what you see. Description is revelation! Words that create pictures. Like the cinema perhaps. Moving pictures!”

Borges constantly asks Parini his eyes. As the journey goes on, Parini gets better at describing the Highlands to Borges. This relationship between Parini and Borges struck me similar to how Zach Mandeville describes the relationship between a person and the terminal in “The Map is the Territory” (link)

The command line is pure language, and to exist in it is to practice all the reality-shifting and world manifesting power of metaphor and dialogue. This is a place of empowerment, tangible creativity, and mystic bewilderment. While it can be dangerous, it’s also exceedingly helpful if you know how to listen.


In the terminal, your main tools are eloquence and metaphor. You are constrained only by what you don’t know how to express. At the beginning this will be quite a lot. But language, like your heart, wants to expand, and as you spend more time here, a shared language will grow between you and the computer, spoken in a dialect entirely your own.

It pleases me to think of the terminal as a blind Borges, goading me to describe things better, every error ending with a beckoning to elucidate further.

“I want to see what you see. Description is revelation!”

The OS is becoming increasingly irrelevant as we near the end of a multi-decade shift from desktop to web apps. Now even applications you install (Slack, Notion, Figma, etc.) are often made with Electron, which is largely running the engine of a browser.

From the user's point of view, the browser is the operating system. That's where they spend their time and where apps run. Obviously operating systems will continue to exist, but they will shift into more of a background role.

That's from the blog of Mighty, a software company that is creating a version of Chrome that's streamed in the cloud. Of course that's a generalization. There are some fascinating implications that could come with such a cloud browser. As mentioned in the above blog post,

If most of the time people spend is in a browser and most of the processing and system resources are offloaded, their computer won’t feel slow as apps become more demanding.

You might not need the best computer specs if the other computer you're using is in the cloud. Therefore, we think prices will drop over time and computer lifetimes will lengthen encouraging manufacturers to focus on other differentiators: durability, weight, displays, design, and battery life.

To me, what Mighty is doing is one way to answer the question of the browser shifting to become the OS. There are many other ways people are interpreting this that are equally intriguing if implemented. One that I've written about a lot is TabFS. Here's creator Omar Rizwan discussing this “browser as OS” distinction:.

There are two 'operating systems' on my computer, the browser and Unix, and Unix is by far the more accessible and programmable and cohesive as a computing environment (it has concepts that compose! shell, processes, files), even though it's arguably the less important to my daily life. how can the browser take on more of the properties of Unix?

TabFS is Omar's answer to that question. If the browser is becoming more of an OS, let's subsume it into the OS as a file system.

Then there's the idea of bringing the ability to code beyond what's possible in the developer console. Glitch and Replit are great in this regard. If the browser is becoming more of the OS, than it should be an OS you can extensively create programs on. Tom Critchlow also has interesting thoughts about this in “Why can't I write code inside my browser” (link).

The implications of the browser as OS is a garden of forking paths. Perhaps they come out at the same end, perhaps at different parts. If one thing's for certain, it'll be a hell of a garden to explore.

I love trying out Python things with Glitch. It feels a bit rebellious for some reason. Why? Glitch caters more towards JavaScript-centric frameworks and static sites. Their most recent announcement, Remix a Whole New Glitch, emphasizes this. But the fact that Glitch cedes some of this wonderful playground to Python is awesome.

The way that most Python Glitch apps work is wonderfully hacky — a bash script that installs all of your packages before running the Python file. This bash script is invoked by the package.json file, which you usually associate with a JavaScript based project. I love the idea of smuggling in a language by way of a metadata file reserved for another language. It peters on the edge of “Should this even be possible?” (even though Glitch supports a lot of languages)

Another avenue of the “Should this even be possible?” route is testing to see which Python web frameworks even work with Glitch. I've cut my teeth on remixing a lot of tiny Glitch apps that use Flask. I've also seen some people use Django. These frameworks, however, were already tested out by others. Which ones weren't?

One I haven't seen implemented in Glitch yet is Falcon. Love how the docs describe it:

Falcon is a minimalist WSGI library for building speedy web APIs and app backends. We like to think of Falcon as the Dieter Rams of web frameworks.

When it comes to building HTTP APIs, other frameworks weigh you down with tons of dependencies and unnecessary abstractions. Falcon cuts to the chase with a clean design that embraces HTTP and the REST architectural style.

So a little different from Flask & Django, but hey — as long as I could invoke python3 server.app, I should be good to go right?

Turns out yes! I was able to successfully create an example app that uses some example code from the “Getting Started” portion of the Falcon docs. Now it's just a matter of building something with it. Curious to try building something more of the API/backend persuasion on Glitch.

I have a bad habit of throwing away ripe bananas. Every time I say I'll make some banana bread with them but never do. In the trash they go. This time, however, was different. I took the ripe banana we had lying around and made banana bread with a recipe that uses leftover pancake mix. Not too bad. Even if the bread tasted worse than it does, there's still that good feeling of finding use in something you're inclined to throw away.

That line of thought made me think about an old 2010 Macbook Pro I have collecting dust in storage. Sooner or later it too will go in the trash. Why not repurpose the laptop? Why not try to install some flavor of Linux on the thing? It's worth trying. The worse thing to happen is that installing Linux doesn't work. Well, there is something that might prove installing Linux on the Macbook a tad difficult — the USB ports are trashed. How? The story actually brings this whole post together...

One morning I packed my lunch in my backpack. I then proceeded to put my laptop in there. SQUISH! What was that? Pulled out my laptop to see that it squished the banana I had packed in laptop. Banana chunks everywhere. Cleaning out the ports was to no avail — USB ports ruined.

But hey, maybe Unetbootin could help.

I recorded a podcast with a friend the other night analyzing a short story. Both of us were responsible for recording our respective voices. Well, one of us was responsible. Spoiler — it wasn't me.

We had a riveting 90 minute conversation and I only found out the morning after that my recording app backfired on me. Nothing but dead air — I was floored. How to break it to my friend? “We'll record it again,” I said. “Next time we can do a little more research on the story and it'll be better. I am so sorry.” But my friend graciously declined. The conversation was lightning in a bottle, well worth having in and of itself. No need for a repetition. “Let's talk about a different story next time.”

This response made me pause for thought. I thought of things the other way around — what good was the conversation if the recording was ruined? In focusing on the artifact, I lost sight of the moment we shared in conversation about an author we both admire.

Does a conversation need a digital hyperlink to give it credibility? No. The analog hyperlinks shared between two people, connections between thoughts and ideas and history and literature and philosophy and religion, that's what counts. Not everything needs a digital hyperlink. That's tough for me to swallow, because I live by that digital coupling of verb & noun — to hyperlink and to click/create/share hyperlinks on the web. Life is not all about digital linkage though (as I publish these thoughts to a digital link). Perhaps part of it these days how to make analog and digital hyperlinks dance with each other.

I don't even know what I'm talking about here to be honest, but maybe that's what more digital hyperlinks are for — to document those analog hyperlinks.

You never know what happens when you admit you're starting to learn something in public...

In case you've not gotten this far, here's a bash script you might enjoy. But note I don't supply any of the text (.txt) files referenced. Change those names as you like, and put files with the names you've chosen under “dir” (whose value you'll likely change as well).

I haven't gotten very far, so this script is wonderful. Thanks Inquiry! I've decided to remix the script for use with TabFS. The cool thing about TabsFS is that your web browser becomes a file system, so every tab becomes a directory. Within that directory is a text file of the tab's content. What you can do then, is use Inquiry's bash script to open each tab's text file as a tmux vertical pane.



tabs=$(ls $dir)

for tab in $tabs
  tmux split-window -h less "$dir/$tab/text.txt"

tmux select-layout even-horizontal
tmux select-pane -t 0

That way you can look at all of your open tabs at once!

There are other applications and changes of the script that could be used to best use TabsFS. I can imagine grabbing the url.txt file of each tab, throwing it in nano, and editing the url on the fly if you want to switch to another site. Will have to just keep playing around with the script & tmux in general.

Reminds me of jamming with other musicians back in school. The common currency we shared were riffs. It could be a couple of notes. That's all it could take to lead to a fun improv session or a song we'd perform later on.

Perhaps this is why I've gravitated towards one-liners and smaller scripts. They're the riffs of programming, allowing you to easily iterate and create something more personal. You can simply change a variable or subsume them into a bigger program. Their portability and changeability create so many possibilities. Makes me think of Github's Gists, where I've discovered riffs aplenty that I've incorporated here & there. I should've thanked those folks. Might as well start now...

Thanks again Inquiry for the bash riff!

I am just now, ever so slowly, discovering how to use tmux. For reference via Wikipedia:

tmux is an open-source terminal multiplexer for Unix-like operating systems. It allows multiple terminal sessions to be accessed simultaneously in a single window. It is useful for running more than one command-line program at the same time.

Only been able to get the two panes working so far, barely scratching the surface of sessions in the background, but even that has been useful. Before I opted for opening tabs for each terminal session. I wonder if that springs from tabs being the defacto way I explore my computer, particularly the web. Didn't know anything else, so why not extend that approach to terminals? Tmux adds this other dimension.

Interestingly enough, tmux gives more context to the experiments I've seen with bringing panes to the web — there's a feature that's in Beaker Browser that does just thaat — here's a beta announcement that explains it. It also makes me think how TabsFS could actually bring panes to using the web by virtue of, well, bringing browser tabs to the terminal itself.

Curious to see what else is out there.