ugly images and type driven design

đź”— posted 2020-11-23

đź”™ back to index

What I’m listening to

Steve Roach — TOMORROW

cover of tomorrow, a pastel painted desert landscape

Rhythmic ambient, great “let’s ease into this week” music. When I’m programming I can listen to pretty much anything and not have it take focus, but I’m doing a lot of writing at work this week.

I don’t get into the flow of writing as easily as programming these days so I’m more particular about the music I listen to; I need something that goes down smooth but also don’t pull attention. This rules out music with lyrics in a language I can understand.

I found out about this album from a Bandcamp newsletter. I’ve built enough of a collection that their recommendations are getting pretty good, and they recommended this a few weeks ago tagged with the label “drone”.

Aside: Cryo Chamber is a record label focused on dark ambient and everything they put out is right up my alley. I’ve got a stack of records in my queue from them I’m looking forward to getting next Bandcamp friday, top of the list being Advent by Randal Collier-Ford

Keeping images one notch above ugly

Jake Archibald wrote a great piece about AVIF and one line in there has stuck with me:

If a user looks at the image in the context of the page, and it strikes them as ugly due to compression, then that level of compression is not acceptable. But, one tiny notch above that boundary is fine.

I’m trying to keep payloads as small as possible for this site. I’m motivated by economics: I don’t make any money from this content, and I am on the hook for outgoing bandwidth, but also there could be folks reading this metered network connections who are paying for the bytes I’m sending them. Not that I’m particularly mobile at the moment (thanks 2020), but my mobile data plan is metered and I get annoyed when I visit sites that send huge images for no good reason.

C’mon, Apple!

Jake’s post got me jazzed up about AVIF, but as expected it’s not well supported yet. Alright, fine, but WebP is pretty good too, how about defaulting my images to that?

Turns out, nope, desktop Safari only supports it on Big Sur!

But what about the <picture> element?

Yeah, that’s probably what I’m going to do going forward. I was hoping I could get away with just using one format because these posts are composed in Markdown and it’s nice be able to use ![alt](path), which translates to a straight up <img> element and does not support multiple sources.

I already have some preprocessing to deal with code blocks, so I’m considering tacking on another parser to do some fancy stuff with multiple image sourcing.

Once my brain gets rolling on this stuff I have to be careful to reign it in—the very next thing I thought was “if I’m gonna write a parser to work with image references, why not make something that does WebP and AVIF encoding automatically from a source image referenced in the markdown!” but no, stop it brain that’s a bad idea.

Why that’s a bad idea goes back to the <h2> at the top of this section. Having an automated pipeline for image compression would be benefit for developer experience but a worse experience for my readers because there’s no way for me to know if I’m nailing the “one notch” measurement, which means either sending larger payloads than strictly necessary, or images that so compressed they offend the senses. When I manually compress images using something like squoosh.app, there is a tight visual feedback loop for me to push an image to the point where it’s looking too rough, then pull it back one notch.

Placeholders in type driven design

I was reading “What’s in a rainbow table” by Amos and saw he was using the Rust todo! macro and it reminded me I had some thoughts about these types of placeholders. Eventually I might want to write a whole post about it, but in the meantime I’ll get down some thoughts!

I love todo! in Rust, ??? in Scala, undefined in Haskell—things that return the bottom type of the type system and blow up at runtime but otherwise make the typecheck happy so you can model how your program fits together without implementing stuff. In languages that don’t have one these predefined, like TypeScript, I’d find myself making one and using it all over the place while designing:

const unimplemented = (name: string): never => {
  throw new Error(`${name}: needs implementation`)
}

Aside: It’s a bummer those { } are necessary, but throw is a statement so it can’t appear alone as the body of an arrow function! There was a proposal for throw expressions but it looks like it’s stuck in stage 2 and hasn’t been presented to TC39 since January 2018.

For an interesting read, check out this old thread of Martin Odersky propsing adding ??? to Scala’s Predef. It was a lot more controversial than I expected! Some people straight up oppposed to including it in Predef, but a lot of people voting for TODO as the name instead. I don’t mind ??? but would have liked an optional name parameter, like todo! has, so I don’t have to dissect the Java stack figure out where it’s coming from. Of course, I can always write my own! Maybe ??!("fn").

Also some of the commenters were right: search engines really don’t know what you’re going for when you search “scala ???”.