AppleScript

Dear jwz,

Next time you find yourself doing a thing requiring AppleScript, reconsider your life choices.

Love, jwz.

Previously.

Tags: , , , ,

17 Responses:

  1. has says:

    Nothing in AppleScript makes sense except in the light of simple first-class relational queries.

  2. Moofie says:

    I do use AppleScript for scripts that tie together Mac applications like Photoshop or Excel with Unix tools like curl and grep. AppleScript's ability to give users programs that they can run that with familiar UI features plus the ability to access Unix is much easier than the alternative solutions. AppleScript's core features have been around forever so I don't have to worry much about a persons particular setup. In publishing at least there is not a good alternative for my workflow.

  3. Dusk says:

    Tried working with JXA?

    The bad news is, it's Javascript. The good news is, that's still an improvement on Applescript syntax.

    • has says:

      Semi-broken Apple event implementation. Semi-broken OSA implementation. Crap documentation, zero support. JS is most popular language in the world, yet JXA can't muster more than a handful of users, half of whom end up going back to AppleScript in frustration.

  4. nooj says:

    It would be a damn sight better if they provided access to more functionality; and in error messages, they output a snippet of the offending code.

    • XuppdduX says:

      "... they output a snippet of the offending code" ... did an SDN search on jwz.org ... nada booshkca ... this site comments about code a lot ... so I'm contemplating an /astronaut-view/ of a SDN-NBI(via switch-fabric), this video - "Stanford Seminar - Software-Defined Networking at the Crossroads.mp4" - and you guys'comments(and LISP) make me think it can be done ... ha

      • MetaRZA says:

        I couldn't have put it better myself.

        • XuppdduX says:

          "provided access to more functionality" , "how much IPC protocol will be generated", comments like these make me believe the reply I got was a response to the comment above mine. the herp-derp I made coulda been said much better than I did myself ...

  5. tfb says:

    Any non-trivial task in AppleScript runs into the problem that the APIs that applications expose change sufficiently fast and AppleScript is so catastrophically slow that scripts need to be rewritten more than once for each time they are run. I am fairly sure that I can type commands faster than AppleScript can execute them in a loop. There must be something it is good for.

    • has says:

      AppleScript itself stinks for performance (list iteration is O(n*n), btw, unless you hack it). There's no fix for that, other than "don't use AppleScript where you can help it".

      The Apple Event Object Model also has an odd performance profile—it was designed for high-latency messaging (System 7 had appalling process switching overheads) so optimizes for sending fewer, complex commands that operate on multiple objects at once over the fine-grained 'dumb' messaging you get with DOM et al.

      In other words, don't do the DOM thing of iterating over a list of 'objects' to manipulate them one at a time if you can help it, because that is expensive. e.g.:

      SLOW (sends N*3+1 AEs):

      tell app "iTunes"
      set trackInfos to {}
      repeat with trackRef in every track
      set end of trackInfos to {name, artist, album} of trackRef
      end repeat
      end tell

      FAST (sends 3 AEs):

      tell app "iTunes"
      set {trackNames, artistNames, albumNames} to {name, artist, album} of trackRef
      end tell

      As noted above, nothing in AppleScript makes sense except in light of relational queries. AE IPC and the AEOM is related to SQL, not OOP/COM/SOAP/CORBA. I do very high-end artwork automation in Adobe Illustrator (using Python3+appscript) and can render a templated artwork in 20 seconds that would take an artworker 20 minutes to build by hand. Mostly it's knowing your tools and how to use them effectively—it's not that hard and really very elegant (when it works right)—the biggest problem by far being Apple's appalling failure to explain this stuff to anyone without lying about how it actually works.

      • jwz says:

        It's not just that it's impossible to tell how much IPC protocol will be generated from any given line of code -- that's horrible for design and performance reasons. But at least that class of problems is coherent.

        No, what's the worst is that you can't even tell what "set X to Y" will do. Does X get get a computed value put in it? Hey, sometimes! Does X turn into a token representing a saved query that will be evaluated later when X is next referenced? Sometimes! Maybe! Is that token closed over the environment when it was created? Sometimes! Or does it re-parse the query in some totally other context later? Ho ho ho wouldn't you like to know!

        • has says:

          It is possible to distinguish between local and remote operations; it just takes a really deep knowledge of the language and its inner workings, way beyond the average user’s time or patience. Rather ironic for a supposedly "easy to learn" language, but the road to obfuscation hell is paved with programmers’ excessively clever intentions.

          `set X to y` is particularly annoying as it's overloaded to perform either a local variable assignment or send a remote `set` command depending on whether X references a local variable or a remote property/element. Y is evaluated same as any expression in AS.

          Normal AS expression dictates that a reference to a remote object is automatically evaluated by sending a `get` command to the app and returning the result. The exception to that rule is where the expression appears as a command parameter or operand to `a reference to` operator, in which case it's passed as-is and it's up to the receiver to evaluate it as appropriate.

          e.g. `set myVar to name of every document of app "TextEdit"` will send a `get name of every document` command to TextEdit" and assign the resulting list of strings to variable `myVar`. OTOH, `set text of document 1 of app "TextEdit" to text of document 2 of app "TextEdit"` sends the `set` command to TextEdit and leaves it to resolve both specifiers.

          Like I say, really painful to figure out—it took me years to black-box reverse-engineer the bloody thing—but it can be done. Hence the need for AE bridges for other, programmer-friendly, languages like Python, Ruby JS, ObjC, and Swift, which provide the same quality of AE support minus all the obfuscatory bullshit.

          Alas, Apple's clueless answer to programmers' loathing of AS's obfuscatory bullshit has been to double-down on said obfuscatory bullshit, which is why their ScriptingBridge and JavaScript for Automation (JXA) bridges have won themselves even less fans than AS has. Appscript and SwiftAutomation remain the only AE bridges good enough to replace AS. I no longer provide support but feel free to give them a spin to see what AE IPC is like once you take AS out of the picture. It still has issues (inadequate specs, inadequate docs, higher cost of development), but nothing that couldn't be fixed if Apple and third-party developers got solidly behind it. Ironically, its very-high-level query-driven evaluation model could now be a terrific partner for Apple's new very-high-level query-driven UI, Siri, right at a time Apple desperately needs all the Echo- and Android-killing USPs it can lay hands on.

          Getting rid of the impotent Sal Soghoian was a small step in the right direction. Alas, I doubt there's anyone at Apple with either the vision or motive to do it right, when it's so much easier just to toss it out and start over from scratch with some fresh pile of half-baked amateur crap that serves no more than a pathetic fraction of Apple's half-billion users. There's never time to do it right, etc.

  6. JD says:

    Gave up on AppleScript in 1996. All these complaints look like the same ones I had with it back then. Did it ever improve????

    • Not that Jamie says:

      No.

      It is worse. Back then it was vaguely interesting; now it is barely an afterthought.

      These days when I'm filled with self-hatred, rather than reaching for Applescipt, I just take a cheese grater to my joints. Same general results, just more efficient.

    • Moofie says:

      The do shell script command lets AppleScript front shell scripts without having to install anything on someones computer. Apple also wrote some library like apps for AppleScript like System Events to get stuff done on MacOS X that were not part of AppleScript on Classic.