As terrible as AppleScript is as a language, it's really nice that Apple even built a framework for apps to use to expose their functionality to external scripts -- I'm not sure today's Apple would have gone to the trouble. And now that you can use JavaScript instead of AppleScript, with a more or less standard way of translating calls between the two, scripting+automating macOS is really painless.
I do wonder why the Shortcuts app seems to be reinventing the wheel. You'd think the functionality an app exposed to AppleScript would've been automatically made available in Shortcuts, with Shortcuts being more or less a block-based interface to the same scripting environment that AppleScript uses, but that doesn't seem to be the case. Kind of an odd choice to not build off their existing work there.
I have plenty of shortcuts that work on iOS but don't work on macOS. It's fun when you use siri on the mac and it tells you it can't do something halfway through.
It’s also relatively easy to use the Scripting Bridge from any language that can integrate with the objective-c runtime. I’ve written a bunch of Mac automation in Common Lisp
I had to automate transforming some Excel data for a friend recently and I did it using AppleScript.
Turns out it’s not as bad as the prevailing HN narrative. It does require a change in mindset but once you get there, it’s actually quite nice, especially when using an app with a nicely designed dictionary.
Like a lot of Apple’s technology from the 90’s, it was a technology before its time. It certainly was pretty important during Apple’s near death experience in the late 90’s due to the publishing workflows that could only be done (at that time) using AppleScript and Quark XPress, etc.
Have a look at xlwings (I am the creator), it’s a Python wrapper around AppleScript that follows closely the original VBA object model, so won’t require a change in mindset.
Hi Felix! Sorry I’m a jerk who never responds to PRs, although I know py3-appscript* is in its best hands with you so just keep rolling as you see fit.
(*I am currently dragging nodeautomation back up to operational status so I can use it in new customer work, but that’s as much appscript-ing as my poor brain can cope with now.)
Hey has! I should have mentioned that xlwings is a wrapper around your excellent appscript package that does all the heavy lifting with AppleScript :) Thanks for reviving the project on GitHub :)
It's a "terrible language" in that it doesn't resemble most languages currently in use, but it resembles Hypercard's language Hypertalk a lot, so at the time it was created, this was a good idea. Hypercard/Hypertalk made GUI programming possible for non-technical people in a way that has not been possible since.
The other day I wanted to do something seemingly simple with Shortcuts - set my screen and my 3 external displays brightness to 100%.
I saw an action to set screen brightness, but figuring out how to apply it to a specific display is an exercise left to the reader ugh. Shortcuts so far seems like a very unpolished product.
Do you know if something like this is easily doable in AppleScript (and whether it’s even worth it vs writing these kinds of things in swift with apple libraries)
“And now that you can use JavaScript instead of AppleScript”
You really can’t. JXA is garbage, crippled, incompetent, and long since abandoned to pine for the fjords. Its only actual function is to impede any re-development of ES6 as a useful scripting platform within Apple, and probably hinders 3rd-party alternatives such as Scriptable and ScriptKit, because what 3rd-party dev wants to be pre-emptively Sherlocked by garbage like that?
Apple abandoned AppleScript and AppleEvent-based automation after they gave the Mac Automation team multiple opportunities to make it successful—and they failed every one. Thus Apple fairly concludes it is a failed product on a legacy platform, ceases work on it because what’s the point on throwing more good money after bad, and looks elsewere for something new and more promising to try next.
Hence Shortcuts, which started out as a 3rd-party iOS app, Workflow. As a technology it is at best mediocre; as a polished, well-presented, and properly-sold product it was already moving up on iOS with positive customer response. Instantly far more promising than the inept, lethargic, and generally couldn’t-sell-icecones-in-a-desert Mac Automation team, where the critical failure was never the technology itself but purely PEBKAC; but an organization the size of Apple doesn’t care about that distinction, only about its results.
Thus, not too long after finally shitcanning the Mac Automation team in 2016, Apple bought up @WorkflowHQ outright, and have been positioning Shortcuts, née Workflow, for its true purpose: to provide their Siri UI with a reasonably granular, accessible, plugin backend so that Siri can actually make itself useful.
…
Lesson here for y’all: It does not matter one whit how good (or not) your technology is. (Apple themselves taught me that.) What matters is how good you are at selling product, i.e. putting bums on seats, and keeping them there.
That’s why AppleEvent technology (which is in many ways far superior) now rots in history’s dustbin, while Apple gives the [Siri-backed and Siri-backing] Shortcuts its opportunity to prove itself a successful product and future of Apple Automation.
Could a successful merging of the two produce a product 100× better? Sure. But if you’re asking that and not understanding why most likely won’t/can’t happen, you’re not understanding how successful big business works. My personal work (github.com/hhas/) testifies to hard lessons learned. (Though if you wish to have a crack, fill your boots. Perhaps you’ll do a better job n’me.)
I implemented quick sort in AppleScript many years ago (to see if I could, not because this is a good idea), and it was excruciating. Very much the epitome of read only code :D
I wrote a fair bit of AppleScript. It always seemed like my code was right, but it was wrong just as often as any other programming language I use. It was just as inflexible and demanding. That was frustrating, since reading it made it look like it was easy and it didn't care how you wrote it.
But anyway, at least you could read the program and understand it afterwards, whether you wrote it or not, whether you understood all the things that had to be just so or not.
AppleScript might be one of the single most bizarre and arduous-to-write-in mainstream scripting/coding languages in history. I can’t say I’m a fan of such a literal interpretation of writing code.
That being said, before I got a solid grasp on Obj-C and the (at the time) OSX APIs like CoreImage, etc; it got me started on writing Mac applications whereas otherwise I’d have had a much rougher time with it.
Back when I’d made the switch from Windows to OSX in 2005 or so, I had written an AppleScript and accompanying Xcode app to auto-align desktop icons to the left, such as on the Windows desktop, as it drove me nuts that they auto-aligned to the right. (Now I prefer the right, lol…)
AppleScript is not much of a general purpose programming language (the syntax certainly takes a while to get used to), but for automating stuff, sorting files into folders, and the like, it is a nice tool. I have scripts that are indispensable to me, and combined with Folder Actions it ensures that there are things that Just Work.
I lament the modern dearth of natural-language scripts designed for normal people who have slightly higher engineering instinct than average but otherwise just want to use their computer. Different people notice the usefulness of such things in different places, but for me it was Minecraft server administration. You have thirteen year olds doing a 'banging on the keyboard' level of management for game servers for eleven year olds, and who do not know the first thing about programming and would take years to get up and running with Java, but who have added to the server dozens of commands and idiosyncratic game mechanics with Skript, because Skript's language is so fundamentally easy and approachable that just about anyone could make just about anything in it that they could conceptualize of the details for.
I really don't think AppleScript's primary application has vanished like many people seem to think it has. Desktop software may be on the decline, but that just means that something equivalent for web needs to exist. Every other day you hear about a business that had some major component, which finally broke, being a giant kludge of an Excel sheet. Those things don't start because they're the best tool for the job, they start because Excel's approachable for non-programmers who can figure out how to make an algorithm work as long as you don't call it an algorithm or force them to start with stdio. Flash had that property too, and the Internet is the lesser for its disappearance; it took so little effort for an animation to be turned into a game that so many animators decided to try. Nobody ever bothers making things like that anymore because everyone's internalized this idea that anything like programming is as hard and as not worth targeting towards normal people as general programming.
The experience is exactly programming with more keywords. There's still a rigid grammar and keywords have precise meanings. You still have to look up what keywords are available, what contexts to use them, what arguments they want, etc etc. It's programming. Harder even.
Ideally there's a bunch of real conversational NLP with common sense and context. This is really what you want:
find my firefox window
move it to the second workspace
on that desktop make slack to be the top window
close all finder windows
While we're not there for programming, I think we're getting close with things like Alexa.
I'm always surprised when I'm at a friends house and they'll ask Alexa to do something in a completely different syntax than I use, and it works flawlessly.
One thing I liked about my recent stint with AppleScript were the various synonyms I could use to express what I was doing, depending on what made the most sense.
"Koala utilizes a sloppy programming approach that interprets
pseudo-natural language instructions, as opposed to formal programming
language statements that must be syntactically correct. Each step in a
sloppy program is processed by an interpreter that tries to evaluate the
step in the context of a given web page’s content, elements, and
available actions. For instance, given the Google home page, and the
slop click search button, the interpreter would propose to
programmatically click the search button.
"We describe the algorithm in three basic steps[...]"
AppleScript is a screamingly conventional, traditional, conservative Algol-style language; which just happens to be dressed up with an app-extensible pool of keywords and lots of built-in homonyms and synonyms to make it look non-programmer friendly.
Not a bad idea from a sales POV, as the biggest barrier into end-user automation for end-users is how hard conventional programming makes itself look. But it failed, because it was a fake; a bait-n-switch. The road to Pedagogical Hell is paved with its ilk. Complexity, made to look simple, instead of just being made simple.
Thus AppleScript looks easy and inviting to non-programmers, but it’s every bit as complicated, convoluted, difficult, and utterly intolerant as every other Algol-descended scripting language (Python, Ruby, JavaScript, etc, etc); and worse, the “helpful” syntax goes deliberately obfuscates much of that complexity to pretend in its simple and uniform.
The most egregious instance of this “damned with good intentions” is AppleScript’s attempt to make the conceptual and behavioral mismatch between the language’s own local, procedural world and the remote, query-oriented worlds of “AppleScriptable” applications which is accessed via its embedded Apple event bridge.
Ironically, non-programmers aren’t bothered by this because they don’t understand it well enough to know any better. Whereas skilled professional programmers absolute hate it, because they actively misunderstand it: they know OOP, application scripting looks like OOP, therefore they assume it is OOP. And then, all that expert understanding and confident on how their scripts will work are completely smashed as “AppleScript” proceeds to behave in profoundly NON-OOP ways, utterly confounding those predictions and proving that something is wrong without ever explaining who or why. So in total absence of any better information, programmers conclude that it is AppleScript that is wrong, and file under Hated and Rubbish.
…
All this might not seem relevant to NLP, but if you don’t understand pedagogy and why previous attempts at end-user languages fail, you can you expect to do any better than they did? Throw enough magic AI pixie dust at it, maybe? I suppose it might be possible to brute-force a solution with sufficient barrel-loads; but then what do you do when that system behaves in ways that mismatch the user’s predictions?
Boom! And you’re right back to the problem AppleScript failed to recognize, never mind solve, 30 years earlier.
In fact, if you want to solve this one you need to look back 50 years, to Seymour Papert’s original work on Logo. The man proved you could build a complete, fully functional and trivial-to-learn language with just three parts:
1. This is a Word,
2. This is how you perform a Word, and
3. This is how you add Words of your own.
As I mentioned elsewhere, I was lead-author on the last edition of Apress’s AppleScript book; a 1000-page monster. Many would consider a thousand pages on the subject a great and impressive achievement.
To me, that doorstop was a disaster: a 1000 pages to explain a “simple, friendly, easy-to-learn language for ordinary users”? (Admittedly I only realized it myself around page 500; and every page after that was absolute hell. No wonder it was 10 months overdue when I finally, barely, wrapped it.) Yet even allowing for my awful verbosity, AppleScript’s baseline complexity is so high that even the best attempt to explain it clearly and completely cannot run less than a 100 pages long. A pedagogical instant “Fail”.
Again, Papert proved you can build a language more powerful than AppleScript and explain how to use it on the back of an envelope. To 8-year olds!
And his syntax does not look so dissimilar to yours: just words in a sequence.
…
So, forget NLP. The correct answer you seek is “Pidgin English”. (And feel f...
Those interested will dig into the OS, then find Automator, then find Apple Script, notice similarities to Minecraft servers, and ultimately choose their own adventure.
I wonder though, if these features were more forward, how would that shape what the “typical” user discovers? As Bradbury-esque as that may sound…
AppleScript was one of my first programming languages, way back in the day. I still have an AppleScript I wrote that I use every day on my MacBook. I'll say it was nice for a beginner that it didn't use a lot of fiddly punctuation, like dollar signs to start variable names, or semicolons to end statements. But the language is only natural-ish. The syntax is just as formal as python or anything else in how you must put it together. It looks easy, and maybe that is a virtue, but a week into it you are looping over an array and de-referencing the dictionary in each element. It's still loops, conditionals, operators, functions, typing, etc.
The problem is that when you try to make programming use natural language, it isn’t natural language, it’s an amalgamation with unnatural “natural” language syntax which is even more confusing than regular code.
Another issue is that when people create large programs with this software it becomes unwieldy, because the developers sacrificed scalability to try and improve accessibility. Even real languages like Python and JavaScript suffer from this.
I might be biased as a programmer, but i doubt non-programmers take any longer to learn code syntax than “natural” language syntax. I think a way to get non-programmers into language would be to adopt an existing language like Swift or Kotlin, and add support for block-based syntax (since you can recognize the syntactic constructs and remember how they work vs. having to remember and recall) and lots of other built-in support tools (like Copilot), especially for abstract concepts like variables, custom structures, and closures.
“I think a way to get non-programmers into language would be to adopt an existing language like Swift or Kotlin, and add support for block-based syntax”
LOL. So like learning and using MIT Scratch or Siri Shortcuts; only instead of stepping on a Duplo brick in the pitch black of night you’re walking across a solid carpet of Lego Technic, infinitely vast.
No mate, you cannot make a programming language simple, accessible, and massively appealing to non-programmers by hiding all its complexity behind brightly-colored bullshit. You do it by eliminating all that bullshit outright. And once you have, explain to your users how to operate what’s left, simply and concisely, using practical, purpose-driven, lay language that doesn’t require a CS degree to interpret it.
Extending around that core—using the best modern text, graphical, and verbal tools, from autosuggest and autocomplete, through to the latest AI- and human-backed “would you like some help with that?”—can improve its usability ten-fold. But if the core isn’t profoundly usable to begin with, then all you’ve done is take a lump of crap and hide its awfulness under ineffective bandaids on top.
Take the lesson from AppleScript’s history: Clever faking does NOT work. It just bites everyone’s ass.
…
So what will work? More history! Go read Seymour Papert’s Mindstorms, and form your end-user language with all the parsimony, clarity, and accessibility that Logo already realized over 50 years ago.
(Tip: Think “toy Lisp”, minus bloody parenthesis. And if it takes you more than a week to build this new end-user language, you’ve done it wrong.)
Learn a brief history of written language and see how much humanity has already successfully built with simple written words. And then, go take a business class, and learn some marketing and sales, so you can translate that vision to mass-market successful and not repeat Papert’s fatal error.
Seymour built his products for kids; and the kids who “got it”, loved it. Because Logo took all power and promise which technology held, and placed it in their young hands to do with as they will. He nailed that part of the problem; better than anyone before and since.
Seymour’s tragic mistake was in not realizing how to sell his product to The People in Power. i.e. Those who hold all the purse strings and solemnly decret what Shall be Learned by Children—and How. Smart guy; true visionary. Bit naive. And so he lived the rest of his life shaking his fist angrily at clouds, never realizing why he had failed so utterly in Changing the World. (So don’t bother reading The Children’s Machine, it’s bollocks.)
If only Bill Atkinson, or Cook and Harris, had done Logo 2.0 instead of warmed-over Algols. That was a mistake. Though as Keith Braithwaite painfully observes:
“It's a curious thing about our industry: not only do we not learn from our mistakes, we also don't learn from our successes.”
I’ve recently wrote some AppleScript for some window management and as someone with more experience with C-style languages I find it’s syntax deeply confusing.
It was more of a trial and error thing than anything else, tutorials online worked more or less.
I see that it is incredibly easy to read, also for non-programmers, but I find it really hard to write, at least as someone that is not very into it.
I'm surprised, since the dictionary has some apple music and icloud music library functionality. I expected it to expose "up next" as another type of playlist. I'm not sure if the same on desktop, but the iOS version of music allows you to control whats up next using Shortcuts. On the mac, you can control shortcuts with applescript using "Shortcuts Events", and shortcuts can run applescript.
Apple desperately needs to kill AppleScript. Every year or so for the past decade, I run into a problem and think, "Oh, I'll try AppleScript" and as the saying goes, it rarely ends well. [1]
We NEED the functionality of desktop apps and services exposing scriptable objects and methods. We do NOT need a "human language based scripting language". Programming in Python, Java and JavaScript have been taught at all levels of school for many years now, with countless resources online. Anyone who would ever have an interest in scripting their computer - the so-called Power Users - already have been exposed to traditional programming languages at some point in their lives and don't need or want to use a "simplified" language.
So not only is AppleScript a bewildering, barely documented, Through-the-Looking-Glass version of a programming language ("‘How do you know that I’m mad?’ said Alice. ‘You must be,’ said the Cat, ‘or you wouldn’t have come here.’”), but the impetus for using such a language has totally disappeared, even if it wasn't an unusable mess designed by autists on LSD.
You can use Javascript [0] or Objective-C (via ScriptingBridge) instead of Applescript. Any language that can bridge to Objective-C (like Swift, Python, or Ruby) can also use ScriptingBridge.
First of all, support and documentation is virtually non-existent for any of those options. Have you tried to use JS alone to automate anything? Eventually you'll end up on the GitHub wiki like the rest of us, trying to convert 15 year old AppleScript examples into JS. It's a nightmare.
This is related my point that AppleScript is an an anachronism. Apple must know that as well and don't want to spend any resources on the problem. So it's just sort of stuck.
Type an AppleScript command into ASTranslate[1] and run it, and you get its instant translation to Python/Ruby appscript syntax. Appscript users adored ASTranslate: it answered 95% of their “How do I…” questions at a tap of a button. Appscript was great tech—a genuine AppleScript replacement—but it was ASTranslate that sold it.
Back when I was enthusiastically supplying Sal Soghoian with 6 weeks of 100% free unpaid[2] JXA testing, feedback, and advice (up to and including writing a complete reference implementation of how a JavaScript OSA component should work for his team to learn/steal from), automatic AS-to-JS command translation I told him was THE Killer Feature Script Editor needed to make JXA a success.
And yes, I provided Sal a free reference implementation of this feature—see the JABDemo app[3] in the JavaScriptOSA zip file. (Still works!) Incredibly quick and simple too: just add a toggle switch to Script Editor’s existing Apple event logging pane, to choose which language to format outgoing Apple events in: AS or JXA. A couple hours’ work to implement and test; would’ve done more than a year’s user community support[4] to make JXA both instantly usable and popular AF.
Yep, I’d have done better advising a doorknob. #PEBKAC
--
[1][3] You’ll need to do the right-click-to-open shuffle to get them to run, as these are ancient apps that I’ve not updated with modern codesigning and notarization. But they still run, and they still rock at what they do.
[2] Again, an important lesson in business learned. Never do world-expert consultancy for less than three figures an hour. Because jerks like that appreciate it by exactly as much as they pay for it. Give to them it for free, they don’t give a shit.
[4] Which they didn’t do either. And after Soghoian ghosted me, and made it clear that JXA was going to be garbage that they simply didn’t care about themselves, damned if I was going to do it for them either. Which is a shame, because after lead-authoring Apress’s monster Learn AppleScript 3rd edition, I could’ve knocked out “Learn JXA” in 6 months and sold JXA for them.
You can certainly write automation code using JXA or SB.
Or you can just skip straight past the end where you `/dev/null` the lot in steaming frustration, and go back to using AppleScript because, as much as it stinks as a language, it’s the only nominally supported option that actually works.
Calling JXA and SB abandoned unsupported incompetent trash is, frankly, an insult to all the abandoned unsupported incompetent trash out there (I’m looking at you RN, npm).
The worst bit is, the Mac Automation team had absolutely zero excuse for botching SB and JXA. The first might be forgivable (because everyone screws up their first AppleEvent bridge—I certainly did), but to ruin two—and do so when this was already a solved problem. And Apple knew this was a solved problem, because they were also considering Python and Ruby appscript for inclusion in Mac OS X 10.5 at the same time as SB was being developed internally.
Alas, Peter Principle, Dunning-Kruger, and Not Invented Here won out[1]; Scripting Bridge shipped, sucked donkey gonads, and immediately sank without trace. Then a few years later JXA did it all over again.[2]
There is a reason why Apple finally fired the Mac Automation Product Manager and disbanded the whole damn team. The tragedy is, while AppleScript itself is a wonderful, awful failure in end-user language design, the underlying AppleEvent IPC infrastructure and the Apple Event Object Model that apps build atop it comes very close to true greatness: a high-level, highly consistent, query-driven UI/UX that for a time was damn near ubiquitous across every major productivity and recreational application.
That query-powered UI ought to be at the heart of Apple Siri today, as Siri’s entrypoint into 1000s of professional and consumer apps, not mouldering in a corner because not a single person left inside Apple even realizes what a treasure chest they sit on, even now. So it goes.
--
[1] a.k.a. Sal Fecking Soghoian. Though really this was my 100% fault: because I was a dumbass who thought “Mission Complete” when Apple approached me about appscript, not realizing that was only the foot in the door. What I immediately should’ve done was find out what dev was sponsoring it and asked what they needed in order to sell it internally to all the decision makers that count. Lesson belatedly learned.
Pro-tip to y’all: When an org like Apple comes knocking on your door, saying “We’re interested in your work…”, the correct answer is “YES! What do you need from me to help make this work?”, not “Oh neat. Wait a minute while I go tidy stuff up…” Because you will not get a second chance.
[2] Again, Sal Soghoian; a man incapable of learning from his own errors, never mind everyone else’s. If only Apple had hired Cal Simone, who actually knew what he was doing and how to sell it.
I remember showing my friend a few tricks with AppleScript when he started working as a genius. Apparently his manager got mad at him after a customer had complained about him writing a script as they thought he was "hacking" them. Turns out the manager had no idea what AppleScript was too.
It’s important to distinguish Apple script the language from the dictionaries of events that apps support. The language is fine. It’s a little different, and there are many features from modern languages like Python that it could use.
But the main issue is not the language, but the event dictionaries exposed by applications. I once spent most of a day finding out that a “page” was not an element of a “document”, but a “spread” was, and a “page” was an element of a “spread”. That might have been in adobe pagemaker.
When the dictionary is clear, everything is fine. When it’s opaque, that’s when things get sticky. To be clear, AppleScript and app dictionaries are awesome — just someone’s also painful.
I like the idea of AppleScript, but every, single, time, I try to use it I walk away frustrated. I can never accomplish the goal I set out to do. Instead I end up wasting hours and hours fiddling around with this language.
The syntax is just odd, since it has this conversational style ("tell app to do this") I constantly fall into the trap of trying to write out something that I think should work, but it does not. This happens all the time.
The other day I wanted to automate something on my new M1 Mac. SURPRISE! The latest version of the app I was trying to use no longer supports Apple Script!
Trying to automate stuff on Mac is so frustrating.
Don't even get me started on Automator!
I tried playing around with the new Shortcuts app, but that thing is also difficult.
A lot of open source software gains automatic trust by virtue of the fact you could check it out, read the source, and compile it yourself. This possibility stands in for the fact that you probably can't - you probably can't actually read the code, and if you could you can't possibly understand all the edge cases and implications, and you definitely don't have time, especially if you are to recurse into its dependency tree.
So for scripting, where you give a random piece of code access to your entire digital life, a language that is hard to write for even experienced developers but is easy to read and fully understand what is going to happen when they run it, for anyone who could read its licence agreement, is an inspired choice.
It should be very hard to make software that could hurt people. It should be obvious, to as many people as possible, when software could hurt people. If we all prioritised user safety over developer comfort we would have a very different industry.
Back in 2007 or so I wrote an AppleScript that would iterate through every email I had ever sent or received, find every properly formed email address, go to the Facebook website, and attempt to add that person as my friend.
At the time I was a publicist in the entertainment business so this was a lot of people. Was a fun way to kill an afternoon, and I still have about 5,000 “friends” on Facebook, many of whom I don’t know super well. So I’ve got that going for me.
Cook’s HOPL3 paper on the early history and motivations of AppleScript is a great read, full of insight and ambition, and it is a damn shame that early 90s Apple management pissed off Cook and Harris into walking out the door, effectively taking with them all of the institutional knowledge and experience that—after a few more rounds—could’ve made Mac Automation into a true game changer.
As presentations go, it not the best sales pitch; and it lacks the depth of the paper (which was written much later), but it’s just a joy to see two young UX innovators genuinely psyched and evangelizing their work.
Sadly Warren Harris passed, still young, a few years back; and William Cook late last year. Which probably leaves me as the last person who truly understands that work, and what it tried to achieve. (And still could, in the right hands, although I doubt those hands existin in Apple any more.)
(The nodeautomation bridge on npm is broken due to bitrot in NodObjC; there’s an active fork on my github which works, albeit slowly RN, as I bring it back into operation for new customer work.)
…
Python appscript was, and arguably still is, the single best piece of software I ever wrote. And it wiped the floor with AppleScript. To the scripters and programmers who used it, it was a revelation: 99.9% as good as AppleScript for automating Mac apps, in a language they already know and love.
Protip: Nothing in AppleScript makes sense except in light of relational queries.
Appscript was the first time anyone explained honestly to Mac OS X devs how Apple event automation actually works. Application Automation is not OOP (despite its misleading jargon and superficial appearance). It’s RPC plus simple first-class queries.
It’s most closely related to SQL and RDBMSes—except whereas SQL talks to a handful of virtually identical apps all doing the same thing, here’s a system that talks to hundreds of wildly heterogenous apps; and in a way that is, in principle, accessible to everyone from expert programmers to end users.
Once you know that, all the bafflement and confusion caused by the mismatch between you you think it works and what you see it actually doing evaporates. And not only is it clear, it is also logical and elegant AF. A really nice, thought-out, very-high-level UI/UX; a programmatic peer—and equal—to the Mac GUI.
Instant, irresistable catnip for geeks. Today it should have a technical audience millions strong, powering the heart and userlands of every Apple OS.
…
The first version of appscript (2003–2004) was a failure. It took years for me to fully understand the implications of “Not Object-Oriented, Query-Driven”. By the time Dr Cook was presenting his AppleScript paper at HOPL3, I had eventually figured it out for myself; even so, reading that paper a while later was hugely enlightening and confirmed I finally had a Mental Model that Is Not Wrong. I owe Cook and Harris a debt of gratitude for their work that am still grinding away to pay off.
Anyway…
Back in 2006/2007, Apple approached me expressing an interest in including Python and Ruby appscript in Mac OS X Leopard. Alas, due to my non-existent sales skills and the then-Mac Automation team’s terminal (literally) Not Invented Here Syndrome, that opportunity was lost. Apple shipped its garbage ScriptingBridge.framework, which immediately failed and sunk with barely a trace. (Yes, I was a dunce; but at least I wasn’t the dunce being paid six figures at Apple to utterly feck things up. That was Sal Soghoian’s job.)
By time 2012 rolled around, the bottom had dropped out the Mac Automation market and it was clear it was on its way out. That year I predicted AppleScript would be done within the next 5–10.
When JXA was surprise-announced at WWDC14 (no doubt pissing off the JavaScriptCore team after revealing their own alternative to AppleScript at WWDC13), I realized this was a unique opportunity to turn things around. The JavaScriptOSA component at the second line, I wrote in less than a month and sent it to the Mac Automation team to learn from/steal however they liked. I even had the book outline for “Learn JavaScript for Automation” worked out, and good chance of getting Apress to publish it.
I’d have done all the community building and support—everything needed to make JXA successful, because I adore what Mac Automation technology has empowered me to do as both an end user and as professional developer. I was desperate to see that power shared with other users, so those users could empower themselves too—even as the Zucks and the rest were doing their damndest to lock all us in their gilded cages and nice little dependent revenue str...
All of my own “amateur” end-userlanguage design work of the last 15 years is the result of coming up through AppleScript, simultaneously delighted at the power it gifted me while increasingly appalled at how much hard unforgiving graft I put in to master this supposedly “easy language for ordinary end users”. (Cook and Harris made me the the monster I am today!) Which got me thinking: I appreciate all that C&H tried to do in their own end-user-language work. But surely it could, should, and must be done much better.
And the answer is: YES! End-user programming can be made vastly quicker, simpler, easier, and accessible; and plain old written words—humanity’s greatest and most successful technology of the last 10,000 years are.
Aaaand, I’m still figuring out all the details [where the devil is]. But I’m further on.
So for those that are bravely curious: there are 3 experimental language proof-of-concepts on my GitHub that you are free to explore and do with as you will: entoli, the second one, and iris.
(The first two are somewhat interesting experiments. The third, could be viable. All technically “toy languages”. But so’s JavaScript—and it prolly has 10Bn seats and counting. “Toys” that solve problems = Cool Beans!)
Iris & friends are all “stealth Logos”; much as Logo itself is a “stealth Lisp”. Personally I’d argue Logo’s more Forth than Lisp; and in any case Lisp isn’t a good Lisp either, because Lisp, like AppleScript, BS-es its users by hiding complexity instead of eliminating it; in Lisp’s case pretending it is simple and perfectly uniform while being absolutely riddled with invisible special forms[1].
Lisp’s mistake: eager evaluation. Once you move decision-making as to how and when arguments are evaluated, from the command’s context to the handlers’, the number of special forms your language requires to do its job drops to zero. John Shutt’s Kernel language solved this, although couched in typically cryptic academic terms I don’t think many noticed or realized its significance.
I solved the same problem independently, though coming from the hacker’a “git it done” perspective. You can see how I did it in iris &co. Interpreted performance is inevitably slowed by the extra layer of abstraction. However, by completely separating handler implementation (just an ordinary Swift function) from handler interface (the novel iris↔Swift type bridging that converts arguments and results from one to other), it should be trivial to create an optimizing Iris compiler that traverses an Iris script (which, like Lisp, is composed of simple native data structures) and outputs a Swift program that links up those Swift functions directly.
And that’s relevant here too, because? Because I lifted that whole idea straight from AppleScript’s “application dictionaries”; and a helluva terrific idea those were too. (Even if they botched some of the implementation details, and then quit in anger before the developer documentation was done.)
High-level RESTful interfaces? Cook and Harris largely did it first, and arguably did it better too. And theirs was just as ubiquitously misinterpreted and rottenly implemented by 99% the rest of the world as HTTP is today. (But that’s a rant for elsewhere.)
…
Now if anyone is really really crazy and looking for something to amuse, #3, iris (its name is obvious wordplay) has one outstanding TODO: finish its library that allows it to speak Siri Shortcuts. Because Shortcuts’ awful XML workflow files, stripped right down to their essentials, are simple sequences of commands; exactly what Forth and Lisp and Logo and my own languages all speak. I am currently pursuing a different market, though if anyone else wishes to pick up and run with iris: be my guest.
Right now, Jellycuts is leading the field, having cracked the translation bit and put a nice, if unimaginatively conventional “UI” around it. (Although its increasingly solid Swift-like syntax ...
> Once you move decision-making as to how and when arguments are evaluated, from the command’s context to the handlers’, the number of special forms your language requires to do its job drops to zero
That's a gaping fallacy based on the idea that special forms do nothing but control argument evaluation.
For instance, oh, a pattern-matching construct is a "special form", and if you already don't have it, it won't materialize out of thin air just from the fact that function arguments are lazily evaluated.
It can work if functions receive raw, unevaluated syntax. But then you don't have zero special forms: you have de facto as many special forms as there are functions in your image. That whole can of worms is just literally a can of worms. Lisp had that; it was called fexprs.
“a pattern-matching construct is a "special form"”
What sort of pattern-matching are we talking about? You mean the sort of syntactic pattern matching we see in e.g. Ocaml’s `match…with…`
“It can work if functions receive raw, unevaluated syntax.”
In homoiconic languages such as Lisp, all operands are by their nature either “raw syntax” (ASTs) or a superset of it (AST + bindings to call site environment). The only variable [sic] is whether or not they’ve undergone any transformations since the time they were parsed. So passing “raw syntax” is a trivial ask in Lisps, where you already get it for free.
“Lisp had that; it was called fexprs.”
It still does: explicit thunks. But those just move the question of when to evaluate out of the function (which knows what it needs and can do it automatically) to the call site (user has to do it manually, and remember to do it each time). And then it has macros too.
Fexprs went out of fashion early on in Lisp. Multiple reasons for that, few if any of which mean that it has now is the better choice. Language design is all about picking a particular set of compromises that integrate well with each other. Fexprs, for instance, did not fit well with early Lisp’s dynamic scoping, which was a motivation for dropping them. Then Lisp dropped dynamic scoping as well, for other reasons. So are fexprs still a bad fit for Lisp now that it has lexical scoping? John Shutt didn’t think so. And, coming at the same question from an end-user usability POV, I am to date inclined to agree.
You can tie your self in knots over here, or you can tie yourself in knots over there. The fallacical thinking is assuming you aren’t living with a pile of pain and limitations today. The only difference is: as status quo, you’re so familiar with it you don’t even notice it any more.
…
Sure there are disadvantages to handler-side evaluation.
For instance, optimizing compiler engineers will hate John’s $vau, because it stops them blindly rewriting individual operands not knowing/caring about context. Instead, they have to read the entire program first, to find out what operand types each function takes. No peepholes for u? Big deal.
One word: Intellisense. Every modern code editor worth its salt already does this work; because knowing argument types in advance greatly increases users’ productivity: autosuggest, autocorrect, autocomplete, generated documentation, partial compilation strategies, and so on. And, much like network effects, the bigger our programs grow, the more benefit these tools provide.
Thus early Lisp’s choice to resolve its func-vs-fexpr inconsistency (and inconsistencies are bad) by throwing out the fexprs could have equally been resolved by throwing out the funcs and just making everything an fexpr. Had Lisp gone down that road to see where it leads, we might’ve gained these authoring tools 20 years sooner.
I’d also argue that handler-side evaluation of arguments helps to bring program size back down, consolidating not only evaluation time but also type checking, bounds checking, coercion, debugging hooks, rich generated documentation, and whatever else you might want to batch-perform on operands (within sensible limits, e.g. side-effect free).
…
My experimental iris language provides much of this in its Coercion objects, plus they act a native↔implementation type bridge/ffi that is miles ahead of Python/Ruby/JavaScript’s C/C++ extension APIs in terms of ease of use and speed of extension development (a big deal if you want to bootstrap a new scripting language quickly). And in completely decoupling bridging from behavior in a way those predecessors do not, its promises future optimizing compiliation opportunities those others can only dream of.
Iris is a “toy language” by any definition. Including that you can play around and try things you would never imagine doing in a Real Language Design; and not be embarrassed when an idea doesn’t work, and som...
FEXPR mostly went of fashion because they could not be compiled and their effects were hard to understand. Every FEXPR can do arbitrary computation with the forms they get passed. Thus each could do non-standard control flow and non-standard evaluation. A macro has the advantage that the generated code usually can be inspected and (for a compiled Lisp) the transformation is only done once. THE syntax of a macro form can already be checked at compile time. A FEXPR only showed usage errors at runtime.
50 comments
[ 2.7 ms ] story [ 112 ms ] threadI do wonder why the Shortcuts app seems to be reinventing the wheel. You'd think the functionality an app exposed to AppleScript would've been automatically made available in Shortcuts, with Shortcuts being more or less a block-based interface to the same scripting environment that AppleScript uses, but that doesn't seem to be the case. Kind of an odd choice to not build off their existing work there.
Shortcuts is cross-platform, and so designed from the ground up to work sanely under the limitations of both macOS and iOS.
Turns out it’s not as bad as the prevailing HN narrative. It does require a change in mindset but once you get there, it’s actually quite nice, especially when using an app with a nicely designed dictionary.
Like a lot of Apple’s technology from the 90’s, it was a technology before its time. It certainly was pretty important during Apple’s near death experience in the late 90’s due to the publishing workflows that could only be done (at that time) using AppleScript and Quark XPress, etc.
(*I am currently dragging nodeautomation back up to operational status so I can use it in new customer work, but that’s as much appscript-ing as my poor brain can cope with now.)
Not at all. Results are what matters, not the technical gubbins under the hood. I’m happy appscript helps you to empower your users.
The Shortcuts app is a third party app bought by Apple.
I saw an action to set screen brightness, but figuring out how to apply it to a specific display is an exercise left to the reader ugh. Shortcuts so far seems like a very unpolished product.
Do you know if something like this is easily doable in AppleScript (and whether it’s even worth it vs writing these kinds of things in swift with apple libraries)
You really can’t. JXA is garbage, crippled, incompetent, and long since abandoned to pine for the fjords. Its only actual function is to impede any re-development of ES6 as a useful scripting platform within Apple, and probably hinders 3rd-party alternatives such as Scriptable and ScriptKit, because what 3rd-party dev wants to be pre-emptively Sherlocked by garbage like that?
Apple abandoned AppleScript and AppleEvent-based automation after they gave the Mac Automation team multiple opportunities to make it successful—and they failed every one. Thus Apple fairly concludes it is a failed product on a legacy platform, ceases work on it because what’s the point on throwing more good money after bad, and looks elsewere for something new and more promising to try next.
Hence Shortcuts, which started out as a 3rd-party iOS app, Workflow. As a technology it is at best mediocre; as a polished, well-presented, and properly-sold product it was already moving up on iOS with positive customer response. Instantly far more promising than the inept, lethargic, and generally couldn’t-sell-icecones-in-a-desert Mac Automation team, where the critical failure was never the technology itself but purely PEBKAC; but an organization the size of Apple doesn’t care about that distinction, only about its results.
Thus, not too long after finally shitcanning the Mac Automation team in 2016, Apple bought up @WorkflowHQ outright, and have been positioning Shortcuts, née Workflow, for its true purpose: to provide their Siri UI with a reasonably granular, accessible, plugin backend so that Siri can actually make itself useful.
…
Lesson here for y’all: It does not matter one whit how good (or not) your technology is. (Apple themselves taught me that.) What matters is how good you are at selling product, i.e. putting bums on seats, and keeping them there.
That’s why AppleEvent technology (which is in many ways far superior) now rots in history’s dustbin, while Apple gives the [Siri-backed and Siri-backing] Shortcuts its opportunity to prove itself a successful product and future of Apple Automation.
Could a successful merging of the two produce a product 100× better? Sure. But if you’re asking that and not understanding why most likely won’t/can’t happen, you’re not understanding how successful big business works. My personal work (github.com/hhas/) testifies to hard lessons learned. (Though if you wish to have a crack, fill your boots. Perhaps you’ll do a better job n’me.)
But anyway, at least you could read the program and understand it afterwards, whether you wrote it or not, whether you understood all the things that had to be just so or not.
That being said, before I got a solid grasp on Obj-C and the (at the time) OSX APIs like CoreImage, etc; it got me started on writing Mac applications whereas otherwise I’d have had a much rougher time with it.
Back when I’d made the switch from Windows to OSX in 2005 or so, I had written an AppleScript and accompanying Xcode app to auto-align desktop icons to the left, such as on the Windows desktop, as it drove me nuts that they auto-aligned to the right. (Now I prefer the right, lol…)
I really don't think AppleScript's primary application has vanished like many people seem to think it has. Desktop software may be on the decline, but that just means that something equivalent for web needs to exist. Every other day you hear about a business that had some major component, which finally broke, being a giant kludge of an Excel sheet. Those things don't start because they're the best tool for the job, they start because Excel's approachable for non-programmers who can figure out how to make an algorithm work as long as you don't call it an algorithm or force them to start with stdio. Flash had that property too, and the Internet is the lesser for its disappearance; it took so little effort for an animation to be turned into a game that so many animators decided to try. Nobody ever bothers making things like that anymore because everyone's internalized this idea that anything like programming is as hard and as not worth targeting towards normal people as general programming.
I don't know how to end rants.
The experience is exactly programming with more keywords. There's still a rigid grammar and keywords have precise meanings. You still have to look up what keywords are available, what contexts to use them, what arguments they want, etc etc. It's programming. Harder even.
Ideally there's a bunch of real conversational NLP with common sense and context. This is really what you want:
we're not there yetI'm always surprised when I'm at a friends house and they'll ask Alexa to do something in a completely different syntax than I use, and it works flawlessly.
One thing I liked about my recent stint with AppleScript were the various synonyms I could use to express what I was doing, depending on what made the most sense.
"We describe the algorithm in three basic steps[...]"
https://ofb.net/~tlau/research/papers/koala-chi07.pdf
https://dspace.mit.edu/handle/1721.1/121718
Previously: https://news.ycombinator.com/item?id=29259897
It didn’t fail. It never was.
AppleScript is a screamingly conventional, traditional, conservative Algol-style language; which just happens to be dressed up with an app-extensible pool of keywords and lots of built-in homonyms and synonyms to make it look non-programmer friendly.
Not a bad idea from a sales POV, as the biggest barrier into end-user automation for end-users is how hard conventional programming makes itself look. But it failed, because it was a fake; a bait-n-switch. The road to Pedagogical Hell is paved with its ilk. Complexity, made to look simple, instead of just being made simple.
Thus AppleScript looks easy and inviting to non-programmers, but it’s every bit as complicated, convoluted, difficult, and utterly intolerant as every other Algol-descended scripting language (Python, Ruby, JavaScript, etc, etc); and worse, the “helpful” syntax goes deliberately obfuscates much of that complexity to pretend in its simple and uniform.
The most egregious instance of this “damned with good intentions” is AppleScript’s attempt to make the conceptual and behavioral mismatch between the language’s own local, procedural world and the remote, query-oriented worlds of “AppleScriptable” applications which is accessed via its embedded Apple event bridge.
Ironically, non-programmers aren’t bothered by this because they don’t understand it well enough to know any better. Whereas skilled professional programmers absolute hate it, because they actively misunderstand it: they know OOP, application scripting looks like OOP, therefore they assume it is OOP. And then, all that expert understanding and confident on how their scripts will work are completely smashed as “AppleScript” proceeds to behave in profoundly NON-OOP ways, utterly confounding those predictions and proving that something is wrong without ever explaining who or why. So in total absence of any better information, programmers conclude that it is AppleScript that is wrong, and file under Hated and Rubbish.
…
All this might not seem relevant to NLP, but if you don’t understand pedagogy and why previous attempts at end-user languages fail, you can you expect to do any better than they did? Throw enough magic AI pixie dust at it, maybe? I suppose it might be possible to brute-force a solution with sufficient barrel-loads; but then what do you do when that system behaves in ways that mismatch the user’s predictions?
Boom! And you’re right back to the problem AppleScript failed to recognize, never mind solve, 30 years earlier.
In fact, if you want to solve this one you need to look back 50 years, to Seymour Papert’s original work on Logo. The man proved you could build a complete, fully functional and trivial-to-learn language with just three parts:
1. This is a Word,
2. This is how you perform a Word, and
3. This is how you add Words of your own.
As I mentioned elsewhere, I was lead-author on the last edition of Apress’s AppleScript book; a 1000-page monster. Many would consider a thousand pages on the subject a great and impressive achievement.
To me, that doorstop was a disaster: a 1000 pages to explain a “simple, friendly, easy-to-learn language for ordinary users”? (Admittedly I only realized it myself around page 500; and every page after that was absolute hell. No wonder it was 10 months overdue when I finally, barely, wrapped it.) Yet even allowing for my awful verbosity, AppleScript’s baseline complexity is so high that even the best attempt to explain it clearly and completely cannot run less than a 100 pages long. A pedagogical instant “Fail”.
Again, Papert proved you can build a language more powerful than AppleScript and explain how to use it on the back of an envelope. To 8-year olds!
And his syntax does not look so dissimilar to yours: just words in a sequence.
…
So, forget NLP. The correct answer you seek is “Pidgin English”. (And feel f...
Those interested will dig into the OS, then find Automator, then find Apple Script, notice similarities to Minecraft servers, and ultimately choose their own adventure.
I wonder though, if these features were more forward, how would that shape what the “typical” user discovers? As Bradbury-esque as that may sound…
Another issue is that when people create large programs with this software it becomes unwieldy, because the developers sacrificed scalability to try and improve accessibility. Even real languages like Python and JavaScript suffer from this.
I might be biased as a programmer, but i doubt non-programmers take any longer to learn code syntax than “natural” language syntax. I think a way to get non-programmers into language would be to adopt an existing language like Swift or Kotlin, and add support for block-based syntax (since you can recognize the syntactic constructs and remember how they work vs. having to remember and recall) and lots of other built-in support tools (like Copilot), especially for abstract concepts like variables, custom structures, and closures.
“I think a way to get non-programmers into language would be to adopt an existing language like Swift or Kotlin, and add support for block-based syntax”
LOL. So like learning and using MIT Scratch or Siri Shortcuts; only instead of stepping on a Duplo brick in the pitch black of night you’re walking across a solid carpet of Lego Technic, infinitely vast.
No mate, you cannot make a programming language simple, accessible, and massively appealing to non-programmers by hiding all its complexity behind brightly-colored bullshit. You do it by eliminating all that bullshit outright. And once you have, explain to your users how to operate what’s left, simply and concisely, using practical, purpose-driven, lay language that doesn’t require a CS degree to interpret it.
Extending around that core—using the best modern text, graphical, and verbal tools, from autosuggest and autocomplete, through to the latest AI- and human-backed “would you like some help with that?”—can improve its usability ten-fold. But if the core isn’t profoundly usable to begin with, then all you’ve done is take a lump of crap and hide its awfulness under ineffective bandaids on top.
Take the lesson from AppleScript’s history: Clever faking does NOT work. It just bites everyone’s ass.
…
So what will work? More history! Go read Seymour Papert’s Mindstorms, and form your end-user language with all the parsimony, clarity, and accessibility that Logo already realized over 50 years ago.
(Tip: Think “toy Lisp”, minus bloody parenthesis. And if it takes you more than a week to build this new end-user language, you’ve done it wrong.)
Learn a brief history of written language and see how much humanity has already successfully built with simple written words. And then, go take a business class, and learn some marketing and sales, so you can translate that vision to mass-market successful and not repeat Papert’s fatal error.
Seymour built his products for kids; and the kids who “got it”, loved it. Because Logo took all power and promise which technology held, and placed it in their young hands to do with as they will. He nailed that part of the problem; better than anyone before and since.
Seymour’s tragic mistake was in not realizing how to sell his product to The People in Power. i.e. Those who hold all the purse strings and solemnly decret what Shall be Learned by Children—and How. Smart guy; true visionary. Bit naive. And so he lived the rest of his life shaking his fist angrily at clouds, never realizing why he had failed so utterly in Changing the World. (So don’t bother reading The Children’s Machine, it’s bollocks.)
If only Bill Atkinson, or Cook and Harris, had done Logo 2.0 instead of warmed-over Algols. That was a mistake. Though as Keith Braithwaite painfully observes:
“It's a curious thing about our industry: not only do we not learn from our mistakes, we also don't learn from our successes.”
So it goes.
It was more of a trial and error thing than anything else, tutorials online worked more or less.
I see that it is incredibly easy to read, also for non-programmers, but I find it really hard to write, at least as someone that is not very into it.
One app which does have surprisingly good AppleScript support is Music, which exposes the library as a fully featured OSA collection:
Unfortunately, the scripting dictionary is kind of old, and doesn't fully expose some newer features like "Up Next".https://sixcolors.com/post/2022/01/shortcuts-applescript-ter...
We NEED the functionality of desktop apps and services exposing scriptable objects and methods. We do NOT need a "human language based scripting language". Programming in Python, Java and JavaScript have been taught at all levels of school for many years now, with countless resources online. Anyone who would ever have an interest in scripting their computer - the so-called Power Users - already have been exposed to traditional programming languages at some point in their lives and don't need or want to use a "simplified" language.
So not only is AppleScript a bewildering, barely documented, Through-the-Looking-Glass version of a programming language ("‘How do you know that I’m mad?’ said Alice. ‘You must be,’ said the Cat, ‘or you wouldn’t have come here.’”), but the impetus for using such a language has totally disappeared, even if it wasn't an unusable mess designed by autists on LSD.
1. https://www.russellbeattie.com/blog/fun-with-the-os-x-finder...
[0] https://developer.apple.com/library/archive/releasenotes/Int...
This is related my point that AppleScript is an an anachronism. Apple must know that as well and don't want to spend any resources on the problem. So it's just sort of stuck.
Counterpoint:
https://sourceforge.net/projects/appscript/files/
Type an AppleScript command into ASTranslate[1] and run it, and you get its instant translation to Python/Ruby appscript syntax. Appscript users adored ASTranslate: it answered 95% of their “How do I…” questions at a tap of a button. Appscript was great tech—a genuine AppleScript replacement—but it was ASTranslate that sold it.
Back when I was enthusiastically supplying Sal Soghoian with 6 weeks of 100% free unpaid[2] JXA testing, feedback, and advice (up to and including writing a complete reference implementation of how a JavaScript OSA component should work for his team to learn/steal from), automatic AS-to-JS command translation I told him was THE Killer Feature Script Editor needed to make JXA a success.
And yes, I provided Sal a free reference implementation of this feature—see the JABDemo app[3] in the JavaScriptOSA zip file. (Still works!) Incredibly quick and simple too: just add a toggle switch to Script Editor’s existing Apple event logging pane, to choose which language to format outgoing Apple events in: AS or JXA. A couple hours’ work to implement and test; would’ve done more than a year’s user community support[4] to make JXA both instantly usable and popular AF.
Yep, I’d have done better advising a doorknob. #PEBKAC
--
[1][3] You’ll need to do the right-click-to-open shuffle to get them to run, as these are ancient apps that I’ve not updated with modern codesigning and notarization. But they still run, and they still rock at what they do.
[2] Again, an important lesson in business learned. Never do world-expert consultancy for less than three figures an hour. Because jerks like that appreciate it by exactly as much as they pay for it. Give to them it for free, they don’t give a shit.
[4] Which they didn’t do either. And after Soghoian ghosted me, and made it clear that JXA was going to be garbage that they simply didn’t care about themselves, damned if I was going to do it for them either. Which is a shame, because after lead-authoring Apress’s monster Learn AppleScript 3rd edition, I could’ve knocked out “Learn JXA” in 6 months and sold JXA for them.
Or you can just skip straight past the end where you `/dev/null` the lot in steaming frustration, and go back to using AppleScript because, as much as it stinks as a language, it’s the only nominally supported option that actually works.
Calling JXA and SB abandoned unsupported incompetent trash is, frankly, an insult to all the abandoned unsupported incompetent trash out there (I’m looking at you RN, npm).
The worst bit is, the Mac Automation team had absolutely zero excuse for botching SB and JXA. The first might be forgivable (because everyone screws up their first AppleEvent bridge—I certainly did), but to ruin two—and do so when this was already a solved problem. And Apple knew this was a solved problem, because they were also considering Python and Ruby appscript for inclusion in Mac OS X 10.5 at the same time as SB was being developed internally.
Alas, Peter Principle, Dunning-Kruger, and Not Invented Here won out[1]; Scripting Bridge shipped, sucked donkey gonads, and immediately sank without trace. Then a few years later JXA did it all over again.[2]
There is a reason why Apple finally fired the Mac Automation Product Manager and disbanded the whole damn team. The tragedy is, while AppleScript itself is a wonderful, awful failure in end-user language design, the underlying AppleEvent IPC infrastructure and the Apple Event Object Model that apps build atop it comes very close to true greatness: a high-level, highly consistent, query-driven UI/UX that for a time was damn near ubiquitous across every major productivity and recreational application.
That query-powered UI ought to be at the heart of Apple Siri today, as Siri’s entrypoint into 1000s of professional and consumer apps, not mouldering in a corner because not a single person left inside Apple even realizes what a treasure chest they sit on, even now. So it goes.
--
[1] a.k.a. Sal Fecking Soghoian. Though really this was my 100% fault: because I was a dumbass who thought “Mission Complete” when Apple approached me about appscript, not realizing that was only the foot in the door. What I immediately should’ve done was find out what dev was sponsoring it and asked what they needed in order to sell it internally to all the decision makers that count. Lesson belatedly learned.
Pro-tip to y’all: When an org like Apple comes knocking on your door, saying “We’re interested in your work…”, the correct answer is “YES! What do you need from me to help make this work?”, not “Oh neat. Wait a minute while I go tidy stuff up…” Because you will not get a second chance.
[2] Again, Sal Soghoian; a man incapable of learning from his own errors, never mind everyone else’s. If only Apple had hired Cal Simone, who actually knew what he was doing and how to sell it.
But the main issue is not the language, but the event dictionaries exposed by applications. I once spent most of a day finding out that a “page” was not an element of a “document”, but a “spread” was, and a “page” was an element of a “spread”. That might have been in adobe pagemaker.
When the dictionary is clear, everything is fine. When it’s opaque, that’s when things get sticky. To be clear, AppleScript and app dictionaries are awesome — just someone’s also painful.
The syntax is just odd, since it has this conversational style ("tell app to do this") I constantly fall into the trap of trying to write out something that I think should work, but it does not. This happens all the time.
The other day I wanted to automate something on my new M1 Mac. SURPRISE! The latest version of the app I was trying to use no longer supports Apple Script!
Trying to automate stuff on Mac is so frustrating.
Don't even get me started on Automator!
I tried playing around with the new Shortcuts app, but that thing is also difficult.
So for scripting, where you give a random piece of code access to your entire digital life, a language that is hard to write for even experienced developers but is easy to read and fully understand what is going to happen when they run it, for anyone who could read its licence agreement, is an inspired choice.
It should be very hard to make software that could hurt people. It should be obvious, to as many people as possible, when software could hurt people. If we all prioritised user safety over developer comfort we would have a very different industry.
At the time I was a publicist in the entertainment business so this was a lot of people. Was a fun way to kill an afternoon, and I still have about 5,000 “friends” on Facebook, many of whom I don’t know super well. So I’ve got that going for me.
AppleScript was cool.
I will also put this here:
https://www.youtube.com/watch?v=1MaHJ_mzrTU
As presentations go, it not the best sales pitch; and it lacks the depth of the paper (which was written much later), but it’s just a joy to see two young UX innovators genuinely psyched and evangelizing their work.
Sadly Warren Harris passed, still young, a few years back; and William Cook late last year. Which probably leaves me as the last person who truly understands that work, and what it tried to achieve. (And still could, in the right hands, although I doubt those hands existin in Apple any more.)
appscript.sourceforge.net
sourceforge.net/projects/appscript/files
github.com/hhas/SwiftAutomation
www.npmjs.com/package/nodeautomation
(The nodeautomation bridge on npm is broken due to bitrot in NodObjC; there’s an active fork on my github which works, albeit slowly RN, as I bring it back into operation for new customer work.)
…
Python appscript was, and arguably still is, the single best piece of software I ever wrote. And it wiped the floor with AppleScript. To the scripters and programmers who used it, it was a revelation: 99.9% as good as AppleScript for automating Mac apps, in a language they already know and love.
Protip: Nothing in AppleScript makes sense except in light of relational queries.
Appscript was the first time anyone explained honestly to Mac OS X devs how Apple event automation actually works. Application Automation is not OOP (despite its misleading jargon and superficial appearance). It’s RPC plus simple first-class queries.
It’s most closely related to SQL and RDBMSes—except whereas SQL talks to a handful of virtually identical apps all doing the same thing, here’s a system that talks to hundreds of wildly heterogenous apps; and in a way that is, in principle, accessible to everyone from expert programmers to end users.
Once you know that, all the bafflement and confusion caused by the mismatch between you you think it works and what you see it actually doing evaporates. And not only is it clear, it is also logical and elegant AF. A really nice, thought-out, very-high-level UI/UX; a programmatic peer—and equal—to the Mac GUI.
Instant, irresistable catnip for geeks. Today it should have a technical audience millions strong, powering the heart and userlands of every Apple OS.
…
The first version of appscript (2003–2004) was a failure. It took years for me to fully understand the implications of “Not Object-Oriented, Query-Driven”. By the time Dr Cook was presenting his AppleScript paper at HOPL3, I had eventually figured it out for myself; even so, reading that paper a while later was hugely enlightening and confirmed I finally had a Mental Model that Is Not Wrong. I owe Cook and Harris a debt of gratitude for their work that am still grinding away to pay off.
Anyway…
Back in 2006/2007, Apple approached me expressing an interest in including Python and Ruby appscript in Mac OS X Leopard. Alas, due to my non-existent sales skills and the then-Mac Automation team’s terminal (literally) Not Invented Here Syndrome, that opportunity was lost. Apple shipped its garbage ScriptingBridge.framework, which immediately failed and sunk with barely a trace. (Yes, I was a dunce; but at least I wasn’t the dunce being paid six figures at Apple to utterly feck things up. That was Sal Soghoian’s job.)
By time 2012 rolled around, the bottom had dropped out the Mac Automation market and it was clear it was on its way out. That year I predicted AppleScript would be done within the next 5–10.
When JXA was surprise-announced at WWDC14 (no doubt pissing off the JavaScriptCore team after revealing their own alternative to AppleScript at WWDC13), I realized this was a unique opportunity to turn things around. The JavaScriptOSA component at the second line, I wrote in less than a month and sent it to the Mac Automation team to learn from/steal however they liked. I even had the book outline for “Learn JavaScript for Automation” worked out, and good chance of getting Apress to publish it.
I’d have done all the community building and support—everything needed to make JXA successful, because I adore what Mac Automation technology has empowered me to do as both an end user and as professional developer. I was desperate to see that power shared with other users, so those users could empower themselves too—even as the Zucks and the rest were doing their damndest to lock all us in their gilded cages and nice little dependent revenue str...
All of my own “amateur” end-userlanguage design work of the last 15 years is the result of coming up through AppleScript, simultaneously delighted at the power it gifted me while increasingly appalled at how much hard unforgiving graft I put in to master this supposedly “easy language for ordinary end users”. (Cook and Harris made me the the monster I am today!) Which got me thinking: I appreciate all that C&H tried to do in their own end-user-language work. But surely it could, should, and must be done much better.
And the answer is: YES! End-user programming can be made vastly quicker, simpler, easier, and accessible; and plain old written words—humanity’s greatest and most successful technology of the last 10,000 years are.
Aaaand, I’m still figuring out all the details [where the devil is]. But I’m further on.
So for those that are bravely curious: there are 3 experimental language proof-of-concepts on my GitHub that you are free to explore and do with as you will: entoli, the second one, and iris.
(The first two are somewhat interesting experiments. The third, could be viable. All technically “toy languages”. But so’s JavaScript—and it prolly has 10Bn seats and counting. “Toys” that solve problems = Cool Beans!)
Iris & friends are all “stealth Logos”; much as Logo itself is a “stealth Lisp”. Personally I’d argue Logo’s more Forth than Lisp; and in any case Lisp isn’t a good Lisp either, because Lisp, like AppleScript, BS-es its users by hiding complexity instead of eliminating it; in Lisp’s case pretending it is simple and perfectly uniform while being absolutely riddled with invisible special forms[1].
Lisp’s mistake: eager evaluation. Once you move decision-making as to how and when arguments are evaluated, from the command’s context to the handlers’, the number of special forms your language requires to do its job drops to zero. John Shutt’s Kernel language solved this, although couched in typically cryptic academic terms I don’t think many noticed or realized its significance.
I solved the same problem independently, though coming from the hacker’a “git it done” perspective. You can see how I did it in iris &co. Interpreted performance is inevitably slowed by the extra layer of abstraction. However, by completely separating handler implementation (just an ordinary Swift function) from handler interface (the novel iris↔Swift type bridging that converts arguments and results from one to other), it should be trivial to create an optimizing Iris compiler that traverses an Iris script (which, like Lisp, is composed of simple native data structures) and outputs a Swift program that links up those Swift functions directly.
And that’s relevant here too, because? Because I lifted that whole idea straight from AppleScript’s “application dictionaries”; and a helluva terrific idea those were too. (Even if they botched some of the implementation details, and then quit in anger before the developer documentation was done.)
High-level RESTful interfaces? Cook and Harris largely did it first, and arguably did it better too. And theirs was just as ubiquitously misinterpreted and rottenly implemented by 99% the rest of the world as HTTP is today. (But that’s a rant for elsewhere.)
…
Now if anyone is really really crazy and looking for something to amuse, #3, iris (its name is obvious wordplay) has one outstanding TODO: finish its library that allows it to speak Siri Shortcuts. Because Shortcuts’ awful XML workflow files, stripped right down to their essentials, are simple sequences of commands; exactly what Forth and Lisp and Logo and my own languages all speak. I am currently pursuing a different market, though if anyone else wishes to pick up and run with iris: be my guest.
Right now, Jellycuts is leading the field, having cracked the translation bit and put a nice, if unimaginatively conventional “UI” around it. (Although its increasingly solid Swift-like syntax ...
That's a gaping fallacy based on the idea that special forms do nothing but control argument evaluation.
For instance, oh, a pattern-matching construct is a "special form", and if you already don't have it, it won't materialize out of thin air just from the fact that function arguments are lazily evaluated.
It can work if functions receive raw, unevaluated syntax. But then you don't have zero special forms: you have de facto as many special forms as there are functions in your image. That whole can of worms is just literally a can of worms. Lisp had that; it was called fexprs.
What sort of pattern-matching are we talking about? You mean the sort of syntactic pattern matching we see in e.g. Ocaml’s `match…with…`
“It can work if functions receive raw, unevaluated syntax.”
In homoiconic languages such as Lisp, all operands are by their nature either “raw syntax” (ASTs) or a superset of it (AST + bindings to call site environment). The only variable [sic] is whether or not they’ve undergone any transformations since the time they were parsed. So passing “raw syntax” is a trivial ask in Lisps, where you already get it for free.
“Lisp had that; it was called fexprs.”
It still does: explicit thunks. But those just move the question of when to evaluate out of the function (which knows what it needs and can do it automatically) to the call site (user has to do it manually, and remember to do it each time). And then it has macros too.
Fexprs went out of fashion early on in Lisp. Multiple reasons for that, few if any of which mean that it has now is the better choice. Language design is all about picking a particular set of compromises that integrate well with each other. Fexprs, for instance, did not fit well with early Lisp’s dynamic scoping, which was a motivation for dropping them. Then Lisp dropped dynamic scoping as well, for other reasons. So are fexprs still a bad fit for Lisp now that it has lexical scoping? John Shutt didn’t think so. And, coming at the same question from an end-user usability POV, I am to date inclined to agree.
You can tie your self in knots over here, or you can tie yourself in knots over there. The fallacical thinking is assuming you aren’t living with a pile of pain and limitations today. The only difference is: as status quo, you’re so familiar with it you don’t even notice it any more.
…
Sure there are disadvantages to handler-side evaluation.
For instance, optimizing compiler engineers will hate John’s $vau, because it stops them blindly rewriting individual operands not knowing/caring about context. Instead, they have to read the entire program first, to find out what operand types each function takes. No peepholes for u? Big deal.
One word: Intellisense. Every modern code editor worth its salt already does this work; because knowing argument types in advance greatly increases users’ productivity: autosuggest, autocorrect, autocomplete, generated documentation, partial compilation strategies, and so on. And, much like network effects, the bigger our programs grow, the more benefit these tools provide.
Thus early Lisp’s choice to resolve its func-vs-fexpr inconsistency (and inconsistencies are bad) by throwing out the fexprs could have equally been resolved by throwing out the funcs and just making everything an fexpr. Had Lisp gone down that road to see where it leads, we might’ve gained these authoring tools 20 years sooner.
I’d also argue that handler-side evaluation of arguments helps to bring program size back down, consolidating not only evaluation time but also type checking, bounds checking, coercion, debugging hooks, rich generated documentation, and whatever else you might want to batch-perform on operands (within sensible limits, e.g. side-effect free).
…
My experimental iris language provides much of this in its Coercion objects, plus they act a native↔implementation type bridge/ffi that is miles ahead of Python/Ruby/JavaScript’s C/C++ extension APIs in terms of ease of use and speed of extension development (a big deal if you want to bootstrap a new scripting language quickly). And in completely decoupling bridging from behavior in a way those predecessors do not, its promises future optimizing compiliation opportunities those others can only dream of.
Iris is a “toy language” by any definition. Including that you can play around and try things you would never imagine doing in a Real Language Design; and not be embarrassed when an idea doesn’t work, and som...