Thomas Cannon

Today I learned that legacy computational chemistry can sometimes be written in FORTRAN

1 month of Musora

After a long stint with Melodics, researching alternatives, and trying out Yousician, I ultimately settled on Musora; which is a vastly different service! It’s not a gamified app, but instead an immense library of learning resources.

The main reasons it won out for me are:

Teaching a man to fish

The emphasis on learning methodology; notably unlocking the skills for improv, reading theory, and mechanical skills.

Musora not being app-based a-la Rock Band (which I love and was a foundational part of my musical journey) forces you to actually learn the pieces and skills to work outside the app. It’s a subtle but importance difference!

If you’re playing a game, you’re learning the skills to complete levels (songs/lessons, in this case). But if it’s a traditional class structure with assignments done “at home”, you’re learning the skills to perform, read music, improv. And you’re building the systems for how you develop those skills.

In essence, along with the nuts & bolts, Musora subtly makes you decide how you want to approach music. How much time & effort you devote to it; what your goals are; where you’re going to focus.

The breadth of material!

There’s quite literally years of solid, valuable material to learn from. The price/value proposition is ridiculous. And not just songs or the guided course, small mini-lessons about techniques, physiology to improve posture and avoid pain, style lessons for different levels of experience.

Their songs approach works better than covers

Musora takes a great approach for building out a song library: they embed YouTube videos with backing-tracks alongside digital sheet music, with custom playback & practice controls.

This means that rather than the sheer scaling problems Melodics, Yousician, etc. face of filling out their libraries; Musora has less work and cost by transcribing their music and relying on the real tracks. It makes practice much more dynamic and fun; and again, you’re learning the skills to read sheet music & practice through it for contemporary music!

Control is such an uneven game, but I love it. The random spawns, checkpointing, and overall progression system are a mess, making it sections randomly infuriating; but then you get a random superpower and it all becomes worth it

Y’all, I think Spotify Wrapped is done, as a concept

A screenshot of an email, with the subject: “Your 2024 in Review: What Type of Loom Personality Are You?”

Turned this on mainly to have background noise that wasn’t football so Kira wouldn’t get riled up by the dogs next door, but turns out it’s just a great documentary youtu.be/yjpYzFtxf…

14-year-old-me is chuckling

A screenshot of the GitHub app, for Little CRM, with 1,337 commits

Y’all, I can’t believe this is finally happening.

Little CRM’s initial alpha is finally live!

blog.practical.computer/2024/11/1…

Little CRM’s early alpha is almost ready! The plan!:

  1. Get this alpha ready to ship
  2. Write a blog post explaining what’s in the early alpha currently, and how it works

That way folks can see what the ethos is, and talk about signing up! So far the reaction has been excitement

The form for adding someone important to your account is coming along! I've been trying hard to add realistic, fun placeholder values. Hopefully it'll guide to less transactional convos. I want people to actually think about the people most important to their endeavors, and view them as people first & foremost, not a resource to extract

A screenshot of a prototype of the People form for Little CRM, showing how handles and basic contact info can be saved. Titles & placeholders help ground it, such as: Grace Hopper as the placeholder name,  “So howʼd you meet?” as a notes section, realistic placeholder values for notes (such as "They were at a neighborhood cleanup and we talked about the music we've been listening to")

Look at this astounding header illustration that Wren made!! I’m floored, it’s perfect

One of the thing I’ve prioritized with Practical Computer is making sure things look great. It’s important, because we have these displays that can truly show off beautiful work. That polish & care pushes you to make better stuff.

That’s why I work with Wren, who consistently knocks it out of the park! Truly some of the best investments my business has made.

A colorful illustration of a lab, with the text “Technical Writeup” on a chalkboard in the center on the left: Buffy, a white dog, is looking at a bug under a microscope. A vest on Buffy reads “bug inspector.” To the right, a man frantically tries to explain a technical concept to a herding dog, Kira. There is a mishmash of technical ideas strewn about the cork board next to the man (who is holding a cigarette), most of which is hastily scribbled in.

More proof of CableReady’s resilience

Mrujs and CableReady are so great together. After using Turbo 7 on both serious and hobby projects since it was released, I’m more and more finding out that it creates a lot more problems than it solves for me. Especially frames, which encourages bad controllers (imo), but drive too.

I haven’t used streams much, but from what I can gather I can recreate the features I want more elegantly with CableReady. I haven’t tried Turbo 8, but I don’t see the point as long as this combo exists. Mrujs has all I want, and the CableCar 🚡 integration is chef’s kiss.”

I saw this and dropped my networking stack guide, obviously.

thomascannon.me/guides/fi…

It’s funny, I’d researched if CableReady and mrujs would make a good stack for my project, and I’d just started when your post happened to came along the same day, as if by divine providence. I took the fact that someone who, unlike me, seems to know what the hell he’s doing chose the same stack as a sign that I was on the right track. I’ve read your post twice since then, thanks so much for writing it! ❤️

I’m so glad that I’ve maintained being a stickler about:

  • Doing the work to systematize things, especially design assets
  • Adhering to using Mac-ass Mac Apps unless absolutely necessary

 

I broke my wrist during Helene cleanup, so I’ve needed to get a Stream Deck to make up for lost time due to one-handed typing. Elgato’s default icon sets are very minimal, making it hard to get something readable quickly.

Buuuut because I’m using Sketch and I did all the work to make a design system around Wren’s branding work for Practical Computer, I was able to:

  1. Open a new sketch document
  2. Use the design system’s library
  3. Make a 96x96 icon artboard
  4. Plop a Sketch symbol in there
  5. Use overrides + Font Awesome’s local fonts to quickly churn out icons

 

They’re not perfect, bad even! But they’re readable, and it was a trivial amount of time, and shows the power of systematizing.

Nanoc continues to be one of the best tools I’ve ever learned. I built out a whole chain for Postmark template emails (mustache) using:

  • Cerberus
  • plain ol ERB for templates & layouts
  • premailer to prep the pages for Emails, and generating plaintext versions
  • unlimited previews using static JSON files, rendering the results for each variant

All with like, maybe 200 lines of code?

This gives me "checking the blinking lights on my Linksys router back when they still had the blue front face" nostalgia, thank you

I'm trying my best to make systems understandable. Years ago I read about how macOS (and software writ large) got rid of status bars, syncing/activity windows, and it stuck with me. So for Little CRM, I’m adding status lights to show if JS appears to be working, and if the Web Sockets connection was successful.

Every day is further proof that we simply need to use UTC across the board. No more timezones.

They have played us for absolute fools

I’ll have more to show and a proper writeup soon, but it’s extremely cool that LittleCRM has replies & threading, with realtime updates. And because it’s CableReady/mrujs, I was able to reuse a ton of code & keep the cognitive load to a minimum

css-tricks.com/callbacks…

JavaScript provides developers with a way to emit custom events that developers can listen for with the Element.addEventListener() method.

We can use custom events to let developers hook into the code that we write and run more code in response to when things happen. They provide a really flexible way to extend the functionality of a library or code base.

Another example of why UJS is so powerful: you start thinking in events.

Fixing the Rails networking stack is published

I just published ~3K words + diagrams + code samples + demo videos on the frontend networking stack I’m choosing for Little CRM, and all my apps going forward.

You can read it here!

I know that’s a ton to dig into, but I believe this is a very strong path forward for resilient and maintainable web apps.

The idea of throwing out Turbo & going to CableReady + Mrujs might feel like it’s a step “backward," less tested, or that you’re forging your own path by not sticking with what Rails ships with.

But I’d argue the exact opposite. It uses what the browser gives us! The concepts & protocols are universal, not a bespoke framework! And it tees up your app to be resilient by default.

I am honestly worried about the cargo-culting around Turbo and how that’ll cause this to either be ratioed or downright dismissed. 🫣 I think there should be multiple options. I have philosophical disagreements with Turbo & see clear technical shortcomings that are hard to work around. But I’m also human, so I know I’m fallible.

I want a frontend stack for our community that can ultimately grow the ecosystem at large, help us attract & keep new blood, and build significantly better apps. From my perspective, this approach accomplishes all of that. I don’t need everyone to adopt it (I want that, because I believe in it 😜), but the overcorrection to “don’t do anything outside of what the framework provides” worries me. Especially on the frontend, given Rails’s history of jettisoning multiple iterations while never having sat down and truly thought out how the code lives on the client side.

I’m not saying this is the option, but it is an option. And it’s my strongly recommended option—the one I believe to be the most robust and easy to use.

Give it a read, chew on it, and let me know your thoughts 😄

Cat's a bit out of the bag on this one it seems 😅

I'm working on a detailed breakdown of Little CRM's networking stack, complete with real code samples and everyone's favorite: diagrams!

 

Turbo relies heavily on DOM morphing, a core tenant being "write your server-rendered pages, and let turbo morph the DOM & browser history API for SPA-like responsiveness. That introduces major & frustrating points of failure for 2 of the most foundational parts of a web browser.
Trying to muck around with how the browser handles large-scale page rewrites and browser history using morphing and heavily mucking with the History API introduces a ton of gotchas.
When you factor in browser caching, HTTP2/3, network speeds, and the complexity of browser engines; I think it's better to have your standard request/ response flow where it loads an entirely new page in reaction to a form submission or link click, than trying to programmatically diff the changes and morph the page to match what has changed and change the browser's history
It's the same class of problems as a virtual
DOM. Even if you're using something like morphdom, the principle of how it's operating is the same.

While you can opt out of these behaviors, you have to explicitly do so with a boatload of meta tags, configuration, and
remembering to do so. Turbo wants to do all this work, it thinks this is the way to handle behavior. Which I disagree with, because most of the conversations around Turbo I see outside of codepens & simple examples are seasoned programmers asking why it's not working as expected.
And if the default behavior of a framework as critical as your frontend stack causes that, maybe its approach is fundamentally flawed.
CableReady does have DOM Morphing and browser history manipulation; but they are opt-in. It's very clear when those behaviors occur, because you choose to enable them.
And you only write code for the behaviors you want, not to rip out the behaviors that cause problems.
Turbo Streams are not an easily grokable/ adjustable API & format
Turbo Streams are how Turbo allows you to send incremental changes as part of remote form submissions, but they're hard to use outside of the very basic cases.

We don’t talk about technical ideas that have good aspects, but we don’t fully agree with. Everything is so focused on finding The One True Way. We love to talk “it depends” in our dayjob, but not our posts. Ultimately, it stifles creativity.

Jay Harris “I swear if you say ‘we have forgotten the old ways’ one more time [with regard to building sites that work without JS]”

Me: “this sounds more like a collective ‘we’ problem than a ‘me’ problem”

Y’all couldn’t put any sort of weighted algorithm on this? Like, I know almost all of these are rude in some capacity, but this just feels like a footgun waiting to happen

A photo of Github’s emoji autocompleter; where typing :finger returns the first result of a middle finger emoji

Little CRM is underway

After over a year of planning, chipping away at the problem, and designing the foundation for reuse; I’m finally starting on Little CRM.

The thing I’ve learned is that every time I decide the right thing engineering-wise, even if it’s just the bare-minimum version, I’m better off that it’s done.

A git commit message with the following details:
<p>Run of app template
302 files changed
10,974 additions and 39 deletions" width=“599” height=“276” border=“0” /></p></p>

      </div>
    </p>
  </div>

  <div class=

I have found it; the saddest, unintentionally funniest podcast ad of all time

Blue Ridge Ruby 2024

I went to Blue Ridge Ruby, and it was an excellent time! I'm extremely grateful there's a regional Ruby conference (only a 90-minute drive away!) with great speakers and great company to boot.

My apprentice, Josh O'Halloran, got a sponsorship ticket and was immediately welcomed by the community. After 12+ years as a Rubyist, I had forgotten just how quickly & warmly we embrace newcomers. It's something we should continually practice.

Also, we need to make weird projects again! Talking about _why, Tenderlove, conference talks of yore, and other watershed moments in the early days of Ruby made me realize that we've been so focused on legitimizing, optimizing, and working with Ruby that we've stopped making dumb, silly things. If there's one critical thing I took away from my time in Asheville among folks that use the language I love every day, it's that we are better when we're collectively goofing off.

That, and root beer taught me the importance of B2B sales.

A photo of 3 different bottles of the same root beer

A photo of myself and Josh O'Halloran post-conference

A photo of a conference slide, with the text

A photo of a conference slide, with the text

A photo from a coffee shop and record store, with hanging plants, mid-century railings, and a green/grey color palette