“Design Concepts” could be a bit heavy for a first course in PLT. I’d look at it after you get into the material a bit further. It seems like a decent book, though. I have to sit down and get through it some time.

For me, the space-in-filenames issue is the main thing preventing me from using Make for everything. The limitations on pattern rules make scaling up Makefiles difficult, too.

I’ve long thought that a prolog-like DSL would be perfect; makefiles are basically already logical specifications—I just needed something that worked with spaces and could perform some sort of unification-like process for smarter pattern rules. I nearly started writing my own.

But then I discovered that someone already created such a tool: biomake. I’ve recently started using biomake to automate a large data science research project. It has been absolute bliss! Not only does it those two pain-points with using Make (and countless other pain-points), it features GridEngine integration out-of-the-box, and fantastic debugging information for when things don’t work as expected. I cannot see myself using any other tool.

This made me full of blood rage when I happened upon it a few months ago. I just want to have some well-named markdown files be automatically converted to HTML and also concatenated, converted to HTML, and that HTML converted to PDF. All with good-looking file names with spaces in them. Like how normal people named files.

For work, I now mostly write Pyret. I typically implement my side projects in either Rust or Racket, though! I have a strong preference towards data-oriented languages. The languages I use most (Pyret, Rust, Racket, Bash, MLs) all favor a data-oriented style of programming, so how I choose a language for a project tends to depend on the ‘shape’ of the data I’m working with.

What language features do you leverage from Rust, and how do they make those projects easier?

I reach for Rust when I need performance, sophisticated types (traits!), and well-defined structured data (ADTs!). It’s a thrill writing code at a high-level of abstraction and being confident that it will be performant. Cargo makes the entire ecosystem a joy to interact with and contribute to.

Why aren’t you using your non-Rust languages for that project?

There are a handful of projects for which I haven’t reached for Rust. Racket, though not tremendously performant, is tremendously expressive! When your data look like s-expressions, Racket is usually the best choice. I used Racket extensively for my encyclopedia remix project Liber Brunoniana, which involved processing lots of HTML.

What could Rust do to make your life easier?

I would love to use Rust for programming embedded devices, like Arduinos, and targeting browsers via WebAssembly.

check, where and examples blocks all exist to support the ‘examples’ and ‘testing’ phases of How to Design Program’s functional design recipe. The placeholder expression syntax (...) and doc blocks are other features that Pyret has to encourage the design recipe.

Testing statements are executed in the order they appear in the program alongside other top-level expressions. If you run:

I adore the simplicity of make as a declarative build tool, but for a build system whose operative principle is a close correspondence with the filesystem, the placement of additional, subtle restrictions on valid filenames are ridiculous. I’d happily trade away most of make’s features for a core that didn’t choke on spaces.