Why are Script Editor .scpt files not saved as plain text files?

Solution 1:

William R. Cook's paper contains an excellent history and insight from those involved with AppleScript in 1989.

What follows is fun and speculative.

Conservation of Space and Processing

AppleScript was written at a time when every byte and bit was valuable. OS X's lazy encoding as property list formats would be wasteful in the eyes' of those early developers.

The binary format provided a pre-parsed form that avoided duplicating the complex, error prone, and time consuming parsing process with each load from disk. Better to load directly into memory and run.

Adaptive

Saving in a binary format allowed AppleScripts to be tied to the underlying AppleEvent codes rather that their dictionary of long form terminology.

This would allow an AppleScript written and saved against one version of an application to automatically update to terminology changes between versions of the targeted applications.

An integer object might be called 'integer' in the script but saved as the four character code 'int ' in the binary representation. The four character code coming from the AppleScript dictionary provided by the operating system.

If a future AppleScript terminology decided to alter the user facing word for integer, the binary representation could map to the newer name.

A flip side to this is possible to see today. Write an AppleScript against an application's dictionary. Then remove the application entirely from your Mac. What do you see in Script Editor upon opening the script?

At least in recent versions, AppleScript Editor showed chevrons surrounding the four character code. The code has been remembered and highlighted. Not the user facing terminology.

This is probably not the primary benefit but a possible benefit.

Modern Bias

It is worth acknowledging our modern bias for text documents. Experience has taught many of us that storing valuable content in a binary format carries risk. Binary formats are often poorly documented, opaque to the end user, and difficult to open when the owning software is not maintained.

When AppleScript and it's binary format were created, this bias was not yet formed. Storage and computational limits were very real and every kilobyte or thousands of cycles saved were worthwhile.

History and Origins

The stories of AppleScript's origin are wonderful but difficult to track down these days. AppleScript tried to be a friendly, English language like, language and was breath taking in its vision; the actual implementation was harder to get right!

  • AppleScript by William R. Cook
  • AppleScript - a story worth telling

Solution 2:

In short, .scpt allows backward compatibility. Plus, applescript/javascript (etc) can saved with the same extension, given that Script Editor now supports javascript.

To decompile .scpt in shell:

https://github.com/rupa/applescript/blob/master/decompile.sh

The most relevant part:

osadecompile

Textmate is a third-party editor that can read .scpt:

https://github.com/textmate/textmate/blob/master/Applications/decompile_as/src/decompile_as.mm

The most relevant part:

[[OSAScript alloc] initWithCompiledData:];

This function comes from OSAScript.h, apart of OS X SDK. In OSAScript.h, there is this lengthy comment:

Given a URL that locates a compiled script, script application, or script source, create and return an autoreleased script data descriptor with its contents. You may use the descriptor to create a script with -[OSAScript initWithScriptDataDescriptor:...]. This enables you to create a script with a specific OSALanguageInstance. You may use +[OSALanguage languageForScriptDataDescriptor:] to get the language for the script data, which may then be used to create or select an appropriate language instance for an OSAScript. Script source data may be compiled by -[OSAScript initWithScriptDataDescriptor:...], or you can coerce the descriptor to a string (using NSAppleEventDescriptor methods) and explicitly create an OSAScript with the source. + (NSAppleEventDescriptor *)scriptDataDescriptorWithContentsOfURL:(NSURL *)url AVAILABLE_MAC_OS_X_VERSION_10_6_AND_LATER;

Basically, when saved .scpt, an OSALanguageInstance descriptor is also saved in the file.

If a file is saved as .applescript/text, the system will compile it with lastest version of applescript language. A script, for example, written for an older version of OS X may not work on a new version because some functions have become obsolete. With .scpt, the system/app have pick out what version of applescipt it's meant for.

From 10.10, javascript can be saved in .scpt and be executed correctly.

Solution 3:

After seeing the decompile command shared by Fartheraway I discovered the solution. If you want the applescript (.scpt) file to not be binary.

@fartheraway also mentions it in the bottom of his answer.

simply do all development with .applescript extension.

The Script Editor will be able to run the code and it will not save it in a compiled format.