Today I programmed a song with Strudel, a JavaScript DSL for making music. Here’s my first program, replicating the introduction to “Zero” by The Smashing Pumpkins. setcpm(60 / 4); const lead = "59 58 51 51 51 51 51 59@2 58 58 51 51 51 51 51"; $: note(lead).sound("sawtooth").gain(0.5); $: note(lead).transpose(-12).sound('sawtooth').gain(0.5); $: note("~ ~ ~ 82 79 75 ~ ~ ~ ~ ~ 82 79 75@2 ~") .transpose(12) .sound('sawtooth') .gain(0.5); $: s("bd ~ bd ~, ~ sd ~ sd, oh*4").fast(2).gain(0.6); $: s("<cr ~>").fast(2).gain(0.6); A couple of things I learned while writing this: ...
Alias a Function in JavaScript
While simple, today I used this trick to write the code I wanted. Variable assignment of a function is a valid, communicative way to alias a function in JavaScript. const clearFilters = () => setFilters({}); // Use the same behavior when starting a new search. const startNewSearch = clearFilters; // These create the same result. clearFilters(); startNewSearch(); In this case, calling clearFilters didn’t fit with a click handler on a button labeled “Start New Search.” With this technique, was able to call the function I wanted, abstracting its implementation.
Dash for Pairing
I’ve written about Kapeli Dash before: it’s a Mac program that lets you download sets of documentation to your computer. This week I discovered a killer use case: pair-programming. Recently I was pairing in a domain I didn’t know well. Before the session, I loaded Dash with every docset I thought I might need. So, for Python, think: Python, Django, and SaltStack, plus React and TailwindCSS for the frontend. When we needed docs, we could effortlessly explore these resources without Googling. Opening a browser while a pairing can be distracting (Banner ads! AI summary!), it can expose your personal information, and is a bit more clumsy when you know what you need. I can find React’s useMemo docs by typing useMemo into Dash and hitting enter— that’s it. There’s no path to that resource online that’s as direct as that. ...
Make Videos Play at Any Speed
When consuming educational materials, I often want to watch faster than the player permits. 2x seems to be an upper limit on many platforms, and that makes sense; 2x can be pretty fast. For material that’s review, I want to go even faster, like 2.5x. Here’s how I bypass this artificial constraint: open developer tools and ensure that the video HTML entity is in scope. You might have to scroll down to it, or highlight it with the element selector. Then, type this into the developer tools console: ...
Disabling Paste Doesn't Prevent Text Entry
This week I had a fascinating conversation about disabling paste into a text input. You might see this UX pattern when a form requires a user to type “confirm” before taking an action. I believe it’s a UX anti-pattern. It breaks an expected behavior of a web form without an obvious benefit. What I learned is that even if it were good practice, you can’t reliably enforce manual typing anyway. ...
Gradle Test Continuous
Running tests in a watch mode encourages test-first thinking and creates a virtuous cycle. Here’s the command to run a Gradle Wrapper (Java) test suite in watch mode: ./gradlew test --continuous Gradle calls this a “continuous build.” It runs when tests or files under test change. Continuous Builds – Gradle Docs
Dropping Images into Keynote
Today I uncovered a nice hack for building a product demo. I had a bunch of Cleanshot screenshots I wanted to present in a Keynote slideshow. If you select all your screenshots and drop them into the left-hand slide navbar on Mac Keynote, each one becomes its own slide in the deck. This let me create a polished presentation in about five total minutes of work, including collecting the screenshots.
Thoughts on Microsoft Teams
My comment on Is Teams really all that bad? – LinkedIn “When async chat tools work, they’re like a conference room where the dev team works through an outage. There’s a history of what’s been said. Specialists and management can step in and observe, without interrupting. Teams takes a more DM-like approach that silos communication. In high-stakes situations, it feels like you’re fighting the issue and the tool.” I’d caveat that my Teams experience all relates to fully-remote work.
Sudo is "Superuser Do"
I enjoy the etymology of technology words. Understanding it can be a handle into using the tool well. One example: sudo. sudo comes from “Superuser do”, allowing you to run a program with the security privileges of another user, usually the root superuser. Here’s an example from a terminal near you: $ <dangerous-command> dangerous-command: NOT super-user $ sudo <dangerous-command> Doing a dangerous thing... This is why programmers say “su DO” (pronouncing “do” like “do”) rather than the softer “sudo”. They aren’t (just) being pedantic; it’s the more correct way to pronounce the word. ...
Reloading Zsh
When I reconfigure my Zsh terminal, I want to see the changes immediately. A good way to do that on Mac is: exec zsh This uses the Zshbuiltin exec command to replace my login shell (Zsh) with another login shell (Zsh). Sourcing the Zsh config (source ~/.zshrc) is less reliable, as things like custom functions you’ve removed tend to stick around. Check out zshbuiltin for more.