PurelyFunctional.tv Newsletter 398: semantics over syntax

Sign up for weekly Clojure tips, software design, and a Clojure coding challenge.

Issue 398 - October 05, 2020 · Archives · Subscribe

Clojure Tip 💡

semantics over syntax

I have a friend, Ryan, who gave a talk at a local meetup (similar to this one --- same speaker and same talk, different venue) about a JavaScript wrapper for ffmpeg. I use ffmpeg a little for video processing, so I'm familiar with how obtuse the command-line options can feel. I had been on the lookout for something better than command-line switches for running some ffmpeg commands, but hadn't found anything.

Ryan's talk showed how a wrapper should be done. The talk was a great description of the conceptual model of ffmpeg and how those correspond to command-line options. They are a linearization of a highly structured video and audio processing pipeline. And Ryan's team's JavaScript library (Fessonia) manages to capture the structure perfectly. At the end, I was so curious how they were able to target just the right abstraction when so many other wrappers had missed. I was hoping to get right at heart of how good software design can clarify a model and how to do that.

He said that they would have rather use an existing library, but in their research, they felt that no library managed to target the right layer. There were libraries a layer below the command-line tool, which give you lots of control, yet require you to become the pipeline yourself. Your code is low-level byte-marshalling instructions, handling interrupts when new frames of audio are ready to move to the next step in the pipeline.

On the other side, the existing wrapper libraries just gave the ffmpeg command-line tools a different linearization. Instead of writing arrays of strings for your command-line options, you got to use method chaining. It's still linear, just slightly easier to type in JavaScript.

It took a lot of work from Ryan and his team to research the actual model that ffmpeg uses internally. It's quite a rich model, but it's readily accessible only to those who use ffmpeg a lot. They then went through and experimented with representations of that internal model. They found one that seemed to maximize ease of use while maintaining high accuracy. Then they devised a way to serialize the model down to linear ffmpeg command-line options.

Takeaways from the story

  • Understand the model You've got to understand the thing your are modeling very well in order to write a good representation of it. This seems obvious, but I don't think people practice as much as the obviousness says they should. Ryan was lucky that the model was created by people and documented. Many phenomena in the world are not yet modeled and so you have to play scientist to model them.

  • Iterate Good software design, like any kind of design, is about exploring a design space. It's very hard to know ahead of time how software will feel to use before you've written it. We don't allow ourselves enough time to try different implementations and throw most of them away.

  • Semantics, not syntax Notice that Ryan's team aimed to model the correct meaning of the command-line arguments. He didn't just focus on making the syntax more convenient. Most programmers would say that the reason ffmpeg's options are hard to understand is because of the syntax. That's part of the truth. But it's not because they're highly abbreviated. It's because they don't reveal the semantics like some other syntax---a diagram, for instance---would. Focus on the meaning and the a nice syntactic representation may reveal itself.

Conclusion

Fessonia is a great example of good software design making programming easier. They understood the domain and iterated toward a solution. But more importantly, they sought to accurately represent the meaning first, with a convenient syntax second. Too much software design advice is basically a style guide---constraints on the syntax. It doesn't focus on capturing meaning, and iterating on what meaning to capture.

Our industry's current discussion of good design is way too heavily focused on style over substance. It's a bit like people giving advice about sentence structure and word choice but totally missing character development and theme exploration. Rhyme and meter vs imagery and meaning. They're all important, but we're focused to much on the stylistic elements.

Quarantine update 😷

I know a lot of people are going through tougher times than I am. If you, for any reason, can't afford my courses, and you think the courses will help you, please hit reply and I will set you up. It's a small gesture I can make, but it might help.

I don't want to shame you or anybody that we should be using this time to work on our skills. The number one priority is your health and safety. I know I haven't been able to work very much, let alone learn some new skill. But if learning Clojure is important to you, and you can't afford it, just hit reply and I'll set you up. Keeping busy can keep us sane.

Also, if you just want to subscribe for a paid membership, I have opened them back up for the moment. Register here.

Stay healthy. Wash your hands. Stay at home. Wear a mask. Take care of loved ones.

Get ready to vote 🇺🇸

If you're a US citizen, one of the most important things you can do is vote in the upcoming election. The lovely Clojurists at TurboVote have instructions for registering in every state. Today is the last day to register in many states, so follow their easy-to-use instructions and they'll set you up. They also send you reminders tailored to you to learn where you are supposed to vote, what documentation you might need, and the dates of upcoming elections. It's a great service! And it's running on Clojure :)

Who you vote for is a personal choice. I don't think this is a good channel for advertising any particular candidate. If you want more personal commentary from me (including more political stuff), you can check out my Twitter feed.

Clojure Challenge 🤔

Last week's challenge

Issue 397

Please do participate in the discussion at the submission links above. It's active and it's a great way to get comments on your code.

This week's challenge

Big change: Please submit your solutions as comments on the gist linked below.

The well-tempered ergodox

This week, we're going to learn some guitar. Write a function that takes the string number and fret number and returns the note you get when plucking it. You can use the chart linked to at the bottom of this page as a guide.

;; third string, second fret
(note 3 2) => :A
;; first string, sixth fret
(note 1 6) => :A#

Open strings (no fret) are represented by 0.

You can represent sharps with a # and flats with a lowercase b.

There are obviously different ways to represent it. Try to find one that captures the underlying model of frets and intervals.

Thanks to this site for the challenge idea where it is considered Very Hard level in JavaScript.

Please submit your solutions as comments to this gist. Discussion is welcome.

Big change: Please submit your solutions as comments on the gist linked above.

Rock on!
Eric Normand