The web is no longer as programmable as it was, but there’s still hope for end-user software. And AI might bridge the gap.
Excel is one of the world’s most used pieces of software. It is the closest thing we have to customized end-user software before the age of AI. Most SaaS applications should just be a spreadsheet (and paradoxically, many spreadsheets should be a standalone SaaS).
Modular. A grid system, charts, and pivot tables go far enough to encompass a wide variety of use cases. It’s not infinitely customizable, but it can be modified by any computer-literate user. More advanced layouts are too difficult for most users to pick up — either they learn a bespoke markup language or become a full front-end developer.
Programmable. In the era of low-code, there was the term “citizen developer.” It might be someone who understand basic principles of calling functions and subroutines but doesn’t have the skills to put together a full program. The Excel formula language is the quintessential low-code languages. Just enough expressiveness to get the task done, but not a general programming language. Even Visual Basic doesn’t expose enough knobs to meet general programming languages.
While Excel has been experimenting with introducing general programming languages to the calculation graph, it’s hard from a product perspective — having users run code on their machines (or even in their browser) can be dangerous. The average user can’t (and won’t) validate the code in a spreadsheet they open isn’t malicious. Today, that’s ok, because there are guardrails around the formula language and Visual Basic. With something like Python — that becomes more complicated.
Systems today already have this customizability built in (somewhat). Apple has “Shortcuts”, which let you put together actions on your phone and call system “APIs” in a low-code sort of way (I use Shortcuts for meditation — turn focus to Do Not Disturb, then start a timer for the time specified, then log a meditation in Apple Health before finally turning off Do Not Disturb). Or AppleScript and Automator, which serve similar purposes but are domain-specific programming languages around macOS automation (I use AppleScripts to programmatically access and search my Apple Notes).
But it’s difficult to use these tools.
- Non-technical end-users can’t figure out how to use these systems. They are much more difficult to debug than regular software, and they don’t have clear or generic abstractions (hard to Google for, and bespoke interfaces to navigate).
- Developers don’t want to figure out how to use these systems. It’s not a pleasant type of programming. Most of the work is figuring out the syntax of the new language, diving into the odd behavior of the locked-down APIs and working with tools that are unfamiliar (and worse than their own environments).
AI might fix this. It can understand AppleScript (probably better than almost any developer, save the authors of the language). It will easily write you a script to do something interesting. I asked ChatGPT to give an interesting example. Here’s one that gets all of the running applications and then speaks them out loud using the built-in text-to-speech capability.
tell application "System Events"
set appList to name of every process where background only is false
end tell
set appNames to "Currently running applications are: " & my listToString(appList, ", ")
say appNames
on listToString(inputList, delimiter)
set outputString to ""
set itemCount to count of inputList
repeat with i from 1 to itemCount
set outputString to outputString & item i of inputList
if i is not itemCount then
set outputString to outputString & delimiter
end if
end repeat
return outputString
end listToString
And a one liner you can run in your terminal to exexcute it.
osascript -e 'tell application "System Events" to set appList to name of every process where background only is false' -e 'set appNames to "Currently running applications are: " & my listToString(appList, ", ")' -e 'say appNames' -e 'on listToString(inputList, delimiter)' -e 'set outputString to ""' -e 'set itemCount to count of inputList' -e 'repeat with i from 1 to itemCount' -e 'set outputString to outputString & item i of inputList' -e 'if i is not itemCount then' -e 'set outputString to outputString & delimiter' -e 'end if' -e 'end repeat' -e 'return outputString' -e 'end listToString'
And instead of the confusing UIs these customization frameworks require, AI might be able to come up just-in-time generative interfaces to simplify the task. That’s a bit hand wavy, but with a little effort and a little natural language input, we might be able to constrain the problem space enough to make the UIs accessible even to the most non-technical user.