The Antipattern Scripting Language
This is a little out of the normal for this newsletter but I had an idea that I just needed to get off my brain. This is going to be a little more free-association than the usual posts. There will be a normal newsletter on Monday.
So there are lots of antipatterns, right? God objects, balls of mud, global variables. Why are these things antipatterns? Because they're easy to do and common but cause headaches down the line. What kinds of headaches? They make changes harder, bugs sneakier, communication more difficult. This assumes a couple properties of the code:
- There is (or will be) lots of code
- The code is worked on by a group of people
- The code will be modified as needs arise
- The code will be maintained for a long time
- The code should be robust to errors and sad paths
- The code is itself an artifact we care about, we need support code (logging, tests, benchmarking)
The antipattern is an antipattern because it reduces code quality for code in this context. It's the context of most commercial, enterprise, or large open-source code. What would be a codebase with the opposite properties?
- Small code, two or three files at most
- Written by one person for their own use
- Solves a very specific problem
- If you want to solve a similar problem, you'll just start over nbd
- Just care about the happy path
- The code is just a means to solve the problem, we don't need support code
A lot of "scripts" falls in this category. Doing a single math calculation, writing a script to customize your editor, a database migration you need to run once, scraping a bunch of webpages for a data dump, a custom build pipeline for your personal website or whatever, munging text, the list goes on. In enterprise code, the primary goal is maintainability, reliability, performance. Here, the only thing that matters is how fast you can finish the script. It doesn't matter if you end up with a janky, fragile mess. Either you're gonna just be running it once or the cost of it crashing and you having to modify the code is so small that it's not worth building robustness in.
In this context the problems caused by antipatterns aren't actually problems to you. If the antipatterns help you finish the script faster then they become good ideas. If you can keep the entire program in your head, using global variables is easier than dependency injection. Implication: this context follows different "best practice" rules than "conventional" engineering. It's a different paradigm.
What would a language that exclusively has this use case look like? So a language which discourages maintaining codebases or large programs. Instead it would emphasize the process of hammering out quick scripts. Let's call it the AntiPattern Scripting Language, or APSL. I'll make a couple of assumptions about the userbase:
- It's okay if it takes some practice to use the language really well. Learning it is a one-off cost you pay for future time savings. The language can also be complicated, as long as the complications make development faster.
- Almost all code will be either libraries or scripts. Libraries are necessary to interface with other software systems, but there's no need for frameworks or shareable application or anything like that. If the dependency tree for a script is more than two packages deep then you're using the wrong language.
So some ideas for features:
- A good package manager and module system, but somehow done in a way that discourages using modules for large scripts. Goal is to make including libraries really easy and nothing more than that.
- A solid REPL, like Lisp or Smalltalk "solid".
- There Is More Than One Way To Do It, Perl/Ruby style. Let people pick the way that makes the most sense to them. Lots of functions that do similar things, so people can use whatever's most perfect for their job.
- Most people will code directly against production because that's more convenient than setting up tests or sandboxing. But it's also dangerous. Features that make this less dangerous? Maybe an easy way to make sandboxes, or robust runtime checks, or "undoable" side effects
- Huge standard library. Riffing on the "lots of libraries" thing, maybe also a first-classed "extended library". Third party packages not part of the core installation but "blessed" by the language, make downloading them really easy. Jqt does a cool thing here
- Goal of minimizing typing. 1-2 character aliases for common keywords and functions
- Features that are bad ideas in other programming languages because they don't scale, either performance- or complexity-wise
- PHP style global dicts?
- Monkeypatching core types and operator overloading, use
+
to merge dictionaries no problem - Multiple dispatch
- Runtime predicate types, existential operators
- Pragmas
-
Features with the sole purpose of making developing scripts faster
- Automatic side-effect logging
- CLI/GUI configuration as core language syntax, like Chapel's config keyword
-
Tie lines or blocks to CLI flags, to replace commenting/uncommenting lines. Like
Debug:T {foo; bar;} baz(Debug:T {1} {2}); Debug:F {qux;}
So if you pass in the
Debug
flag, it doesfoo; bar; baz(1)
, if you don't it doesbaz(2); qux
. -
Register "utility" files with the interpreter that are available to all scripts
- Features that make it really easy to serialize/deserialize binary data or program state
- AHK-level input parameters, like a core construct to kick open a file selector or copy-paste
- "Use last run's input" feature?
Doubtless some of these are bad ideas, but that's brainstorming for ya. The fascinating bit is that the design constraint of "write janky programs as fast as possible" leads to a PL that's very different from everything currently available. Nobody makes languages that truly target this use case. It's an underdeveloped field of programming!
(I bet some people are shouting "LISP" while others are shouting "SMALLTALK", but they don't feel this way to me? They're too good at large scale programming. Gotta think about that more.)
Okay that's all the thoughts I had on this. Normal update on Monday.
If you're reading this on the web, you can subscribe here. Updates are once a week. My main website is here.
My new book, Logic for Programmers, is now in early access! Get it here.