HYPERTALK was a high-level, procedural programming language created
in 1987 by Dan Winkler and used in conjunction with Apple Computer 's
HyperTalk supported the basic control structures of procedural languages : repeat for/while/until, if/then/else, as well as function and message "handler" calls (a function handler was a subroutine and a message handler a procedure). Data types usually did not need to be specified by the programmer; conversion happened transparently in the background between strings and numbers. There were no classes or data structures in the traditional sense; in their place were special string literals , or "lists" of "items" delimited by commas (in later versions the "itemDelimiter" property allowed choosing an arbitrary character).
In the late 1980s Apple considered using
* 1 Description
* 1.1 Fundamental operations
* 1.2 Objects, containers and scripts
* 1.3 Referring to containers
* 1.4 Collections
* 1.5 Handling text
* 1.6 Lists and other collections
* 1.7 Messages and events
* 1.8 Controlling
For most basic operations including mathematical computations, HyperTalk favored natural-language ordering of predicates over the ordering used in mathematical notation. For example, in HyperTalk's put assignment command, the variable was placed at the end of the statement:
put 5 * 4 into theResult
whereas in the more traditional BASIC programming language (and most others), the same would be accomplished by writing:
theResult = 5 * 4
The HyperTalk code has the side-effect of creating the variable theResult on the fly. Scripts could assign any type or value to a variable using the put command, making HyperTalk very weakly typed . Conversions between variable types were invisible and automatic: the string "3" could be multiplied by the number 5 to produce the number 15, or the number 5 concatenated onto the string "3" to produce the string "35". HyperTalk would not complain unless the types could not be automatically converted.
Flow control and logic were generally similar to other common languages, using a if ... then ... else ... end if structure for conditionals and supporting loops based on a flexible repeat ... end repeat syntax. Comments were prefaced with two minus signs: -- this is a comment.
OBJECTS, CONTAINERS AND SCRIPTS
HyperCard's primary user interface concept was the card, a display system that emulated an index card . Cards were normally used to store information, similar to a record in a conventional flat-file database . The graphical layout of the card was created using the mouse by placing various elements on the card, such as text fields and buttons. A master layout "card" known as the background was shown behind the transparent areas of each card. Objects placed on the background, such as fields and buttons, would be shared as a common layout among several cards, but with card-specific content. The collection of cards, backgrounds and the associated data stored in them were stored in a single file known as the stack (of cards). Collectively, all of these data-containing objects are referred to as containers.
HyperTalk functions, or scripts, were normally stored within the script property available in many of the stack's containers. Scripts could access the properties of a container, corresponding to instance variables , using the get and set instructions. The script property held plain text and had no special properties; scripts could be placed in, and run from, any text container, including string variables (and thus indirectly text files), or imported from other stacks using the start using command. A script could even be user-provided text typed into an on-screen text field. Arbitrary text could be executed using the do command, in a manner similar to Dynamic SQL.
REFERRING TO CONTAINERS
A key concept in HyperTalk was the way it referred to containers through a navigational system based on the visual hierarchy of the stack. Every container in the stack was given a unique ID number when created and could also be given a name. Scripts could refer to objects by using either of these identifiers, along with an object type specified using the of operator. This operator used a natural language syntax making for easily readable, self-documenting code . For instance, a script stored in a button on a card might wish to take user-supplied text gathered using a text field and store the text in a variable called theValue:
put the value of card field "typehere" into theValue
Various contextual aspects of statements could be inferred by the interpreter. In the statement above, for example, because the script would be running in the context of a button on a specific card, the identifier card was understood to refer to the card the user was interacting with. In addition, "the value" (the text submitted by the user) was assumed to be the main property and to be the target of operations if not otherwise specified. Likewise, "card field" was assumed to be the target of the command, as opposed to the background field, so that information could also be omitted. Even container types had short forms that programmers could use to save typing. Thus the code above is equivalent to the shorter form:
put fld "typehere" into theValue
Objects within a given context—the card or background, for instance—were also given a runtime number based on their z-order on the screen. To assist in using their position for navigation, HyperTalk also included a variety of ordinal and cardinal referencing systems to simplify the syntax further. Assuming the field "typehere" is the only field on the card, the code above could also be written:
put the first card field into theValue
put card field 1 into theValue
The choice of addressing style was left to the programmer; often different styles were used in different statements in order to make the code more readable.
HyperTalk included the me container which acted in the same fashion as the self qualifier found in most object-oriented languages , allowing simple access to the current container object. Less common was the it variable, which held the value of the last operation for certain built-in operators. For example:
ask "What is the value?" put it into card field "display"
uses the ask command to display a dialog box capture text typed into an accompanying text field; when the dialog is completed by hitting Return or clicking OK, the value is assigned to the it pseudo-variable. The value is then copied into a card field using the put assignment operator.
Containers of a given type were also available as collections with a pluralized version of that container type as its name—the collection of the fields on a card was card fields. These collections were themselves containers with their own properties. Key among these was the number property which was widely used during iterations and similar tasks. For instance, if one wanted to hide all the fields on a card, this could be accomplished with this code:
repeat with i = 1 to the number of card fields hide field i end repeat
This code exposes another common feature of HyperTalk: that a
property might have several names and operators. In this case the hide
command, and the associated show, act by setting the value of the
container's visible property. Thus hide field i is exactly equivalent
to set the visible of field i to false. A similar example was the lock
screen command that stopped visual updating, which was a short form
for set the lockscreen to true, where lockscreen is a property of
A notable feature of the HyperTalk container model was its handling of text. Every collection of text, whether a literal string in a program or text typed into a text field, was itself considered a container with multiple collections of containers within it. This allowed scripts to parse text using the same navigational commands as any other container. For instance, while parsing a space-delimited data file, one might want to extract the third column, like this:
put the third word of theFilesText into colThree
This syntax allowed the script to "walk" down the text to find particular data, as in this example:
put the first character of the third word of line 5 of card field "sometext" into theChar
This process of treating text as a container was known as "chunking", and the functions as "chunk expressions". These same sorts of expressions were used to handle file manipulation, along with a set of file management functions. The following code opens a known file, reads from it, extracts data, and then closes the file:
on mouseDown answer file "Please select a text file to open." if it is empty then exit mouseDown put it into filePath if there is a file filePath then open file filePath read from file filePath until return put it into cd fld "some field" close file filePath set the textStyle of character 1 to 10 of card field "some field" to bold end if end mouseDown
HyperTalk also included functions for chunking strings using a substring-find operation using the in operator. The following code finds all examples of a given pattern using the in as part of the repeat loop, while offset finds the location of that pattern within the string:
function replaceStr pattern,newStr,inStr repeat while pattern is in inStr put offset(pattern,inStr) into pos put newStr into character pos to (pos +the length of pattern)-1 of inStr end repeat return inStr end replaceStr
LISTS AND OTHER COLLECTIONS
HyperTalk used the same chunking system to produce structures like arrays or lists. Such a structure would be created by placing multiple data items in a variable, separated by commas. Various types of data could be imported into a HyperTalk script using strings that would get parsed as required. For instance, the position of objects on the screen was defined by a pair of numbers representing the X and Y coordinates relative to the upper left corner. The following code creates a variable called pos that holds a coordinate pair, and then manipulates this to re-position all of the buttons on a card in a diagonal from top-left to bottom-right:
on mouseUp put "100,100" into pos repeat with x = 1 to the number of card buttons set the location of card button x to pos add 15 to item 1 of pos end repeat end mouseUp
The item chunking expression was originally based on a comma
delimiter , but later versions of
MESSAGES AND EVENTS
HyperTalk used an object-oriented concept for calling scripts, with objects in the stack sending "events" that would be processed by "handlers" that declared their interest in receiving the events using the on syntax. For instance, most GUI containers could send the mouseUp event when the mouse button was clicked down and then released on top of that container, and a script could capture these events like this:
on mouseUp -- place additional code here end mouseUp
The events were first sent to the script in the object that created
the event, for instance, if the user clicked on a button the mouseUp
event was first sent to that button. If the button's script object did
not have a mouseUp handler (or no script at all), it was then passed
to the card, the background, the stack, any stacks whose scripts had
been explicitly imported using the start using command, the "home
stack" (a user-selected always-open
For many simple events like mouse clicks on buttons the script would be placed directly within the object in question, the button itself. For instance, one might use the example code above within a button handler in this fashion:
on mouseUp repeat with i = 1 to the number of card fields hide field i end repeat end mouseUp
In the case where code was being called from multiple locations, or it was being used as a global handler for an event, the script could determine the original sender of the event using the target function. Likewise, scripts could send events to other containers using the send command and then using the navigational code to refer to the container holding that handlers code:
send "mouseUp" to card button "OK" of card "Veracity"
Combining HyperTalk's string processing with the do command allowed for the construction of interactive interpreters by placing a text field on a card and then placing this code in the field's script:
on mouseUp select the clickLine put word 2 of the clickLine into linenum do line linenum of cd fld 1 end mouseUp
clickLine is a global property that returns the name and line number
of the last field clicked, in a form like "line 10 of card field 4".
This code first selects all of the text on the clicked line, then
extracts the line number into a local variable, then uses do to run
the text as a
The mouseDown message was sent to a button when the user clicked it,
and mouseUp was sent when the user released the mouse inside it to
trigger its action. Similarly,
Unlike general rapid application development platforms, HyperCard stacks always looked like stacks - the menu bar was HyperCard's and not the programmer's (by default—scripting could add, delete and modify menus), the single window was a fixed size (in early versions), and in certain cases, commands that were central to the operation were part of the application itself, and not directly available in HyperTalk itself.
A good example of this was the creation of new cards, which was part of the application, not directly accessible from the HyperTalk language itself. A new card could only be created using the New Card menu item, which could be simulated in code usingdoMenu "New Card". While HyperTalk called into menu commands, menu commands also invoked handlers in HyperTalk. To run custom code when the Copy menu item was selected, one would place a script in the stack using the on doMenu itemName handler, and then examine itemName to see if it was "Copy".
HyperTalk also provided script control over the built-in drawing tools, simply by scripting the needed changes in paint tools and simulating mouse movements using the drag from start to end and the click at position commands.
HyperTalk language languished just like HyperCard
itself, it received a second lease on life through its plugin
protocol, so-called External Commands (XCMDs) and External Functions
(XFCNs), which were native code containers attached to stacks (as
Macintosh-specific resources ) with a single entry point and return
value. XCMDs and XFCNs could be called just like regular message and
function handlers from
HyperTalk scripts, and were also able to send
messages back to the
DESCENDANTS OF HYPERTALK
Various scripting languages have taken their cues from HyperTalk.
They are commonly regrouped in a loosely defined family named x
As well as second-level clones like:
These clones and dialects (commonly referred to under the moniker of