Update on my Racket exit

Updated Friday, Apr 25, 2025

Figure 1: Blasting off from planet Racket to other planets. Thanks ChatGPT.

Figure 1: Blasting off from planet Racket to other planets. Thanks ChatGPT.

It’s been almost two years since I took a public step away from the Racket diaspora. I’m writing this post to air out how my Racket projects have gone since then. I believe, as of now, I have zero Racket codebases to maintain — hooray!

It’s important to me to demonstrate how one should do with old codebases. Let’s reaffirm the importance of handing off inactive projects instead of holding on to them. Kill your darlings. Let your babies fly from the nest. Whatever you gotta say, it’s important to let things flourish without holding on unduly so. Embrace growth with at least a modicum chaos. That’s the path. Something beautiful will grow.

Steps to hand off a Racket project

In case anybody wanted to know what I do when I hand off here is my Racket migration checklist. Only step 4 is Racket specific.

  1. Find an interested future maintainer.
  2. Create a GitHub org and transfer the repository into the org.
  3. Add your future maintainer as a GitHub organization owner.
  4. Update pkgs.racket-lang.org entries with
    1. An additional author email linked to the future maintainer’s pkgs.racket-lang.org account
    2. Update the repository path because presumably, GitHub will eventually stop redirecting after a repository move.
  5. Communicate and clarify any further questions for the new maintainer as they arise. Or not and disappear. Long term projects success hinges on providing the easiest possible hand-off and continued support, as needed.

toml-racket was rehomed

It turned out my revival of Greg’s toml-racket1 was used by more than my lonesome. Go figure: TOML is sweet and simple. The revival codebase touts combined encoding and decoding support.

Thanks to Benjamin Yeung for adopting toml-racket. πŸ™‡

tinybasic.rkt was rehomed

Previously.

I was on the fence with archiving the tinybasic.rkt repository; given the 10+ stars for this boutique programming language that exists within a niche community, it seemed like a raw deal for these passionate individuals.

A random GitHub Pull Request appeared! I’m not set up anymore to QA and review Racket related patches so it made sense to offer up the project to interested users. I did what I believe every author should do in this situation: immediately make a ticket asking for volunteers to take on the project. Thankfully the s-expressions aligned and a maintainer appeared!

Big thanks to JΓΆrgen Brandt for taking on maintainership of tinybasic. πŸ™‡

Other Racket packages removed from pkgs.racket-lang.org

There were other packages with ostensibly no users (save for myself). Since I was no longer using the packages, I deleted them from the Racket Catalog and then archived the GitHub repositories.

The removed packages include (though, I can’t recollect if this list is exhaustive or not):

4chdl
4chan media downloader. 4chan is dead anyways so this is not useful to anyone, anymore.
ssh-hack
a way to play nethack online. I rewrote this tool in Python and it’s been easier to deploy.
tool
a logging and general purpose CLI utility framework thingy.

Admiring old darlings, experiences

It hit me how much stuff that I wrote in Racket. A lot. Loads of stuff.

The first Racket code that I can find is from circa 2015. It was a command line tool to upload text to the sprunge.us PasteBin website. It was already pretty decent code honestly. Passable as any beginner dev in the community.

And here’s a collection of my favorite Racket experiments:

  1. Language implementations - Subby, TinyBasic, brainfuck, a doctest language embedded in Markdown used to test API calls.
  2. Network protocol support to query Minecraft, ET:QW, RCON-enabled game servers, Mumble VoIP servers, so on
  3. Shredding the competition in coding competitions using Racket. It’s a fun party trick, but won’t land you a job, by the way.

It’s not exhaustive. I didn’t list off any GUI, Web, IRC, command line utility things, or anything with excessive macro use. Those activities were seldom fun — too tedious. Especially anything web related.

Bogdanp has been working diligently on streamlining the web story, so it’s been a lot nicer with his batteries-included Racket APIs.

Fin

Figure 2: On to the next thing. Thanks ChatGPT.

Figure 2: On to the next thing. Thanks ChatGPT.

It’s lovely to be done with these projects and redirecting focus to the next endeavor.

I’ve been writing a great deal of Python, Bash, Awk, Perl 5 for my own consumption and it’s kept my focus free for other activity such as biking or cooking.

For another time: let’s talk about incentives in software development. This is the cornerstone of anything coding, not the language. Onboard, encourage, and reward, or not, at your project’s peril.

If you don’t have community (including yourself) engaged, the code is effectively dead no matter the language.

The sky above the port was the color of television, turned to a dead channel.

— Opening paragraph from William Gibson’s Neuromancer.

So I thought to myself, why not write a screensaver for Emacs? Enter snowcrash.el. It’s not on MELPA or anything, but it does live on GitHub within my Emacs configuration repository.

M-x snowcrash RET looks like this:

It’s fun to look at or leave running as a screensaver!

Background

Figure 1: TV Noise, a.k.a. Snowcrash. Public Domain

Figure 1: TV Noise, a.k.a. Snowcrash. Public Domain

This is Snowcrash. The TV turns to random noise and if you have sound, the speakers produce a sharp hiss. Some people find it soothing. Some find it a bit much and upsetting.

Figure 2: Classic 10PRINT. scrus, CC-BY-SA-4.0

Figure 2: Classic 10PRINT. scrus, CC-BY-SA-4.0

10 PRINT CHR$(205.5+RND(1)); : GOTO 10

Now, This is 10PRINT. a simple toy program from Commodore 64 days (circa mid 80’s) that draws a textual labyrinthine pattern across the screen. Bonus, there’s a fun, free book about 10PRINT. Don’t miss out on the refreshing take of 10PRINT’s cultural impact.

The catch? Not everyone has a C64 emulator set up, however, probably everyone has Perl installed. Here is a 10PRINT version for Perl using ASCII characters:

Why? How?

Alright, with knowledge of 10print and snowcrash/TV noise, let’s talk more about snowcrash.el!

I wanted to see how difficult it might be to create a simple Snowcrash-y screensaver mode in Emacs. My initial attempt “snowcrash-ified” a normal buffer instead of creating a new major mode. This worked, but didn’t have an easy way to stop the timer (responsible for redrawing) on the buffer’s deletion. Plus, the modeline looked real confusing with the major mode indicated as “Fundamental mode” (the least specialized text editing mode).

Unlike “10print”, what I call “snowcrash” does not involve scrolling text. Instead, snowcrash.el rewrites the buffer every second. “10print” randomly selects forward slash (/) or backwards slash (\) for each character; snowcrash.el randomly selects a standard space (ASCII 0x20) or full block (Unicode 0x2588 β–ˆ), creating a satisfying noise effect like an old television.

I discovered the full block character using Emacs’s Unicode search functionality nestled within C-x 8 <RET> (insert-char). I typed *block in the minibuffer then perused through the match candidates. To prove how easy it is to enter unicode characters in Emacs, I’ll insert umbrella, brain, snowman emojis real quick here in a couple seconds: β˜‚πŸ§ β˜ƒ. Viola!

Other Emacs screensavers

By the way there are other cool Emacs goodies that can serve as screensavers. Here’s a short list. It is not exhaustive.

  1. M-x dark-souls - spam “You died” in the buffer (MELPA)
  2. M-x gameoflife-animate - Conway’s game of life (MELPA)
  3. M-x fireplace - cozy fire vibes (MELPA)

Possible iterations

Here are some ideas for further improvement generated while writing this major mode. Sorted from fun to boring.

  1. Add color!
  2. Ensure the snowcrash-mode works correctly with multiple snowcrash-mode buffers.
  3. Ensure snowcrash-mode removes the timer and hooks when the feature is unloaded or the in the case of the buffer’s major mode changing prior to deleting the buffer.

Elisp Footgun: (random) vs (random LIMIT)

I’ll conclude this post with a elisp quirk—an elisp footgun. The Elisp (random) function has several distinct behaviors depending on how it’s used. This makes for a funny API replete with oodles of legacy vibes.

  • (random) returns an integer between most-negative-fixnum and most-positive-fixnum inclusive. (random 4) returns a random integer from 0 to 3 inclusive (0, 1, 2 or 3).

So good so far. Function named random generates random numbers.

  • (random t) reinitializes the seed to a random value. (random "something") reinitializes the seed derived from "something".

Yep, if you pass a STRING or t to (random), the seed is changed. On the other hand, if you pass nothing (nil) or an INTEGER, (random) selects a random INTEGER. I’m sure there was well meaning intentions in overloading (random)’s behavior by dispatching on the argument’s type and value. It’s confusing as hell.

Compare with Python’s random module possessing a random.seed() and a random.randrange() separating out the APIs for easy access.

API Design Matters!

And a final quote reminding us that careful API design matters!

Always code as if the guy who ends up maintaining your code will be a violent psychopath who knows where you live. Code for readability.

John Woods

Figure 1: sudo plus emacs

Figure 1: sudo plus emacs

Emacs offers TRAMP as a way to edit files over ssh or as a different user. Combine with sudo-edit for easy superuser edits. VSCode has a feature reminiscent of TRAMP called Remote Development using SSH.

At the time, I didn’t know of M-x sudo-edit so I wrote my own implementation. It sucked, didn’t work on chained TRAMP connections (e.g. ssh then edit as root on the remote host). Also, it turned out non-standard file buffers (such as dired) require dedicated code paths that I’d have to troubleshoot and diagnose. It wasn’t easy to figure out how to write this interactive lisp function. And indeed, it’s not what I want at all.

Figure 2: sudo-edit in action

Figure 2: sudo-edit in action

No, what I actually want is sudo-edit with its quality, time-tested defuns. Besides, it’s easy to use:

  1. M-x package-install sudo-edit RET. (See sudo-edit on MELPA.)
  2. Next visit the file then run M-x sudo-edit RET.
  3. Finally, type in your sudo password and viola! You can now edit and save the buffer as root!

Read more about sudo-edit in C-h f sudo-edit RET or see the source code — embedded with commentary and documentation — here on GitHub.


sudo make me a sandwhich.

…By the way I had to figure out how to make decent gifs from a webm. Generate a color pallet then perform the transcode using that color data to ensure decent contrast. See this StackExchange answer.