Translating HyperTalk to JavaScript

Samuel A. Rebelsky

So, you've decided to program in JavaScript, but all you know is a little HyperTalk. What do you do? A quick scan of much of the JavaScript documentation out there shows that it generally assumes that you already know how to program (in C, C++, or some other "real" language). You don't really want to start relearning to program from scratch. A "translator's" guide might be a good start (just as we sometimes start to learn a new language by using a "common translations" handbook).

This document summarizes some of the common translations between HyperTalk and JavaScript, from the basis of what a beginning-level HyperTalk programmer (e.g., an alum of Dartmouth's CS4) might know. While it is not necessarily possible to translate every HyperTalk object, function, property, and such into JavaScript, JavaScript does include many similar things. It is therefore possible to take what you know of HyperTalk and use it to figure out how to do things in JavaScript.

Note that, in general, JavaScript is more concise than HyperTalk (as most "real programmers" believe that verbose languages are bad :-). In many places, the syntax of JavaScript is similar to that of C, C++, and Java.

In the examples that follow, HyperTalk code will generally appear in a plain typewriter (monospace) face, while JavaScript and HTML code will appear in a bold typewriter (monospace) face. Portions of the code that you might modify (e.g., when you need to substitute the name of your own variable) will be in italics.

I am always happy to expand this document, so let me know if you have a general type of translation task you need help with (or even a particular translation task).

Note that this document is far from complete (there are many sections that read "to be written"). I'll work on it as fast as I can, but the questions you ask will help me choose sections to work on next.


Table of Contents


Basics

We begin with some of the basic things you need to know in order to program in any language: how to define and use variables, where your code goes, and how to add comments.

Variables

Yes, JavaScript has variables (both local variables and global variables). Good coding style in JavaScript suggests that you always declare your variables, using


var variableName

Variables declared within a function are local to that function. Variables declared outside all functions are global.

Assignment

In HyperTalk, we set the value of a variable using put, as in

put 3+4 into x

The general form in HyperTalk is

put expression into variable

In JavaScript, you use a single equal sign for assignment, as in


x = 3+4

Or, more generally,

variable = expression

Where to put code

In HyperTalk, you attached code to an object by editing the script of that object. In JavaScript, you generally attach code to an HTML document by writing it within your HTML, surrounded by the tags <SCRIPT language="JavaScript"> and <SCRIPT>

Good JavaScript style suggests that you do more than this. You should also "comment out" your script for browsers that don't understand the script tag (as the default action upon seeing a tag you don't know is to ignore it).

<script language="JavaScript"> <!-- Hide code from non-compliant browsers ... // Done hiding code --> </script>

In general, your function definitions and global variables go in the document head and your event handlers go in object definitions. For the occasional time that you need code to be executed at a particular point in your document, you put it at that point.

Comments

Good programming style (in any language) suggests that you comment your code. In HyperTalk, we used two dashes (--) to begin a comment (which then reaches to the end of the line). In JavaScript, we use two slashes (//) to begin a comment (which then reaches to the end of the line).

Simple output

All these correspondences aren't going to do us much good (or at least will become boring pretty damn quickly) if we don't at least know how to do something. Perhaps the simplest thing to do in JavaScript is to print something in the current document. You do this with


document.write(stuff-to-write)

Warning! I have had some calls to document.write() crash my Mac. I have not been able to trace the reason for this crash. However, most seem to work correctly.

A basic example

The following is a sample HTML document containing a JavaScript program. In the head, we declare a global variable and set its value. In the body, we print some text and then print the value of the variable. Note that there's a lot of HTML code for very little output. This is because we still need a lot to surround each piece of JavaScript, and our pieces of JavaScript are pretty small. You can see the results of our example here.

<html> <head> <title>A sample HTML document with JavaScript</title> <!-- Function and variable definitions --> <script language="JavaScript"> <!-- Hide code from non-compliant browsers // Variable to_be_printed contains the text we wish to print. // Note that I can declare the variable and set it at the same time. var to_be_printed = "javascript example" // That's all the code --> </script> </head> <body> <script language="JavaScript"> <!-- Hide code from non-compliant browsers document.write("I call this thing ") document.write(to_be_printed) // That's all the code --> </script> </body> </html>

Objects

The design of a HyperTalk program often involves the design and interaction of the objects in the HyperCard stack (or stacks) that are manipulated. These objects include cards, buttons, and fields. Similarly, JavaScript programs often pertain to the manipulation of objects, some of which are similar to HyperTalk/HyperCard objects.

Cards

The card is a fundamental part of HyperCard and therefore influences the design of HyperTalk scripts. There are, of course, no cards in HTML and JavaScript. The replacement in HTML/JavaScript depends, in part, on the intended use of the card in your program. Some cards are used only to group information, while others group information (in fields) and "features" (in buttons).

You can, of course, create a new document for each card (and you may want to do this if your primary goal is to group information). However, HTML also provides forms for grouping together buttons. As you might guess, you use a <form name="..."> tag to begin a form and a </form > tag to end a form.

The form tag (and body of the form) need not be within script tags.

Backgrounds

There is no object in JavaScript that truly corresponds to the background in HyperTalk.

Buttons

Buttons in JavaScript serve (more or less) the same function as buttons in HyperTalk -- they can be used to trigger actions. Just as HyperTalk buttons only appear on cards (or backgrounds), JavaScript buttons can only appear in forms.

JavaScript, like HyperCard, provides a number of types of buttons, including "normal" buttons, checkboxes, and radio buttons.

Standard buttons

Standard buttons are round things which you click on in order to trigger some action. You define such buttons in JavaScript/HTML with

<input
  type="button"
  name="button-name"
  value="text-that-appears-on-button"
  onClick="JavaScript code"
>

Note that while in HyperTalk, the name of the button is the same as the text that appears on the button, in JavaScript they may be different (and you need to set them separately).

Also note that this is primarily HTML -- you can define buttons without an onClick handler (although they won't do much then).

Checkboxes and radio buttons

You may recall that HyperCard provides two buttons with "state" (in that they can be on and off): checkboxes and radio buttons. They differ primarily in that while multiple checkboxes in a group may be on, in general only one radio button in a group may be on.

The HTML code for radio buttons and checkboxes differs only slightly from that for normal buttons. Instead of type="button", you use type="radio" or type="checkbox".

In radio buttons and checkboxes, you may also include a checked parameter that indicates that the radio button is selected.

Text fields

We use text fields as sources of information, as well as destinations of information.

Text fields are defined similarly to buttons, using type="text". Fields also have a size="NN" parameter that tells how wide the field is (in characters).

For example, to create a field named "username" with default contents "SamR" and width 20, I would use

<input type="text" name="username" value="SamR" size="30" >

You can put a value into a field by writing

document.formName.fieldName.value = expression

You can refer to the value in a field as

document.formName.fieldName.value

Scrolling fields

To be written.

Menus

To be written.

Windows

To be written.

JavaScript's object hierarchy

To be written.

Some examples

To be written.

A grid of buttons

To be written.


Output

JavaScript presents a number of ways to give output to the user. You can present output in dialog boxes (answer, not ask), in fields, and in the message bar at the bottom of the screen.

In a dialog box

You may recall that HyperTalk provides an answer command that gives you a dialog box with the selected text (and, optionally, buttons that may be specified by the programmer). HyperTalk also provides an ask command that prompts the user and gives space for entering values.

Unfortunately, JavaScript only provides something like the answer command, and then without the ability to set the names in buttons. JavaScript's command is

alert("to-be-displayed")

When you want more functionality, you'll need to build a form using buttons and fields.

In a field

To be written.

In the message box

To be written.

Using the status bar

To be written.

Using another window

To be written.


Events

A key issue in the design of your HyperTalk programs was events and reaction to events. Most HyperTalk programs take the form "when X happens do Y", where many of the events that happen are noticed and specified by the system. For example

idle

HyperTalk sends an idle message whenever nothing else is happening. Many HyperTalk programmers use this message to update their stack as time passes (e.g., incrementing a timer or clock, moving an object in an animation, etc.).

Unfortunately, JavaScript does not allow you to write handlers for the idle message, or for anything similar. However, you can tell JavaScript to execute a piece of code after some number of milliseconds, using the setTimeout(code,milliseconds) command. By having your code call setTimeout each time it executes, you can simulate the effects of idle. For example, to count down from 100 to 1 in a field, I might use something like the following
function startCountdown() { document.stuff.counter.value = 100 step() } // startCountdown function step() { document.stuff.counter.value = document.stuff.counter.value - 1 if (document.stuff.counter.value > 0) { } }

mouseDown and mouseUp

For buttons, we wrote handlers for the user pressing down on the button (mouseDown) and for lifting up (mouseUp). JavaScript provides only onClick, which is effectively a combination of the two.

mouseEnter

To be written.

mouseLeave

To be written.

openStack, openBackground, and openCard

To be written. (Use onLoad in the body tag.)

closeStack, closeBackground, and closeCard

To be written.

(Use onUnload in the body tag.)

Mathematics

To be written.

Expressions

To be written.

add xxx to yyy

To be written.

yyy += xxx

multiply xxx by yyy

To be written.

Random numbers

To be written. Not built in to the language, so we must provide


Containers/strings

HyperTalk provides us with a broad collection of commands for manipulating "containers" (which are basically just strings that may be in variables or in fields). In HyperTalk, we can join strings (concatenation), extract components (characters, words, lines, items), insert more text (before, after, or in the middle), and even do some pattern matching (is xxx in yyy?). JavaScript does not provide such a full collection of options, but we can simulate many of them.

One important thing to note about JavaScript strings: they begin indexing with 0, rather than with 1. For example, the initial character in a string is character 0, rather than character 1.

JavaScript also has a type of container called the array. JavaScript is better about manipulating arrays than strings.

While in HyperCard, all strings must be surrounded by double quotes ("") or single quotes (').

Concatenation

Surprisingly, you can use the addition symbol (+) to concatenate strings.

The length of a string

To be written.

char n of xxx

To be written.

Use something like

xxx.substring(n, m)

char n to m of xxx

To be written.

item n of xxx

To be written.

line n of xxx

To be written.

put xxx before yyy

To be written.

put xxx after yyy

To be written.

Pattern matching

To be written.

return

To be written.


Properties

To be written.

Syntax for the xxx of yyy

To be written.

Basic properties

To be written.

The value of a field

To be written.

The name of an object

To be written.

the number of xxx in yyy

To be written.


Control

Of course, we need to do more than define variables and assign values to them. We also need to control the order in which statements are executed.

Code blocks (begin...end)

To be written.

The left curly brace ({) opens a block of JavaScript code and the right curly brace (}) closes a block of JavaScript code.

If xxx then xxx else xxx

Other than sequencing (generally, the computer executes statements in order), the simplest form of control is the conditional or "if-then" statement. In HyperTalk

Repeat with

Recall that we had a repeat with structure in HyperTalk that let us repeatedly execute some code while counting the number of times we did the code. For example, one might compute the product of 1 through ten with

put 1 into product
repeat with i = 1 to 10
  put product*i into product
end repeat

Or, more generally,

repeat with variable = starting-value to ending-value
  ...
end repeat

In JavaScript, we instead use the for loop statement. For your purposes, it has the form


for(var=starting-value; var<=ending-value; ++var) {
  ...
}

Yes, you need those semicolons, curly braces, and double plus.

To redo our HyperTalk example in JavaScript, we would write


product = 1
for(i=1; i<=10; ++i) {
  product = product*i
}

This is not the only form that the for loop can have, but it should be sufficient for most of your purposes.

Repeat while

To be written.

Use something like

while (test) {
  stuff-to-do
}

Repeat until

To be written. Note that we need to convert it to a while loop.

Function calls

To be written.

Examples

To be written.


Functions

To be written.

Defining functions

To be written.

Use something like

function functionName(param1, ..., paramN)
{
  function-body
}

Function parameters

To be written.