free web hosting | free website | Business Hosting Services | Free Website Submission | shopping cart | php hosting
 


Translating HyperTalk to JavaScript

Eric Engle  and Samuel A. Rebelsky

Table of Contents



Abstract:

This document is intended to help developers who know javascript or hypertalk to learn the other and to encourage development of a hypertalk to javascript parser. It summarizes some of the common translations between HyperTalk and JavaScript, from the basis of what a beginning-level HyperTalk programmer 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.

Conventions:
xCard refers to any of the "card" metaphor scripting integrated development environments, namely hyperCard, superCard, metaCard, Runtime Revolution.

xTalk to refer to the languages hyperTalk, metaTalk, transScript and Lingo. All these languages are supersets of hyperTalk and derived from Pascal. xTalk uses a pseudo english language that is close to ordinary English and is thus generally more accessible to non-programmers or debutante programmers.

In the examples that follow:
HyperTalk code will generally appear in a plain typewriter (monospace) face,
JavaScript and HTML code will appear in a bold typewriter (monospace) face.
variableNames will be in italics.
We will generally first discuss first the xTalk commands then their javaScript equivalents.


Introduction:

Note that, in general, JavaScript is more concise than HyperTalk as most "real programmers" believe that verbose languages are bad. This is a methodological bias which is bad for programming. By presuming that programs are and should only be understood by mathematicians, AI research is limited. In many respects hyperTalk is actually a good language for developping simple expert systems among "non programmers". A "non programmer" can look at an expert system developed in xTalk and basically follow the structure of the programm - especially if it is well commented. In contrast, the syntax of JavaScript is very similar to that of C, C++, and Java albeit "simplified" - and any expert system written in these languages would not be understood by a non programmer. The same is true of LISP and I presume PROLOG. While "get" and "put" are certainly ugly and unwieldy in math functions they are very helpful when dealing, for example, when assigning factors for decisions. Later versions of xTalk, such as metaTalk get around some of the limits of hyperTalk in terms of math processing - notably by including arrays and case statements. AI expert systems, at least in law, are still in their infancy. Though the expert system model of AI is in my opinion incomplete and certainly has proven unprofitable in some industrial applications, as an academic modelling and pedagogical device it is fascinating. This explains why a comparison of xTalk and javaScript merits at least academic attention.

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.

Basics

We begin with some of the basic things you need to know in order to program in any language. The first important distinction to note between hyperTalk and javaScript is that javaScript - unlike HTML or hyperTalk - is case sensitive. That means that:

anyTermOrValue is NOT equivalent to anytermorvalue  in javascript - even though the two terms would be the same in hypertalk!

AnyTermOrValue can of course be... a variable.

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

Variables

Like most languages, JavaScript has variables (both local variables and global variables) and constants. Good coding style in JavaScript suggests that you always declare your variables, using
var variableName
Strictly speaking var is not necessary. However if you later move to Java you will regret not having declared your variables explicitly.

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

Unlike more "advanced" languages - but just like hypertalk - javaScripts variables are "loosely typed". That means you do not have to declare a variable as a "boolean" (0 or 1) "string" (e.g. astring$) "long", "short", or whatever - unlike Java or Pascal. Both javaScript and hyperTalk allow you to treat strings (text character) as numbers and vice verse. However javascript does not have the reserved words "one", "two"... through "nine" - here hyperTalk is different from javaScriipt.

What this means in practice is that you won't have to be worried about "coercing" a string variable to a number or a boolean or vice verse.

Variables in hyperTalk do not need to be declared or initialised - but to avoid headaches I always declare my variables at the beginning of the document and initialize them to zero/false:

    put 0 into X

which is as close as you will get to an equivalent to var X = 0 a javascript equivalent.

Assignment

In HyperTalk, we set the value of a variable using put, as in
put 3+4 into x
Basic does this assignment function using the (sometimes optional) "let" command.

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
Strictly speaking in javaScript the VAR statement is optional: HOWEVER it is good programming style to always use it - you might run into a strange parser which requires the VAR statement, and it makes reading your program easier.

Where to put code

In HyperTalk, you attached code to an object by editing the script of that object. The "stack" (the equivalent of a series of web pages), a background (similar to a stylesheet in CSS) or the card (the equivalent of a web page) can have a script.

In JavaScript, you generally attach code to an HTML document by writing it within your HTML, surrounded by the tags

<script language="javascript> expressions </script>

You can place scripts anywhere in the document, though functions should go at the top of the document before the </head>tag.

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.

<a href="javascript:alert('yourtext')"> Your link here </a>

will call a javascript statement from a link.
 

Multiple line statements are possible using the semi-colon which seperates statements in javaScript - just like C or Pascal. Hypertalk does not use a seperator character but implicitly statements are seperated in hypertalk by the return key. Again since you might move on to Java where the semicolon ( ; ) is mandatory you should get in the habit of using it. It is permissible but bad style to use the return key as a line seperator. The return key is also the line seperator in hyperTalk - unlike Java and Pascal.
 

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). We can also use <!-- comment -->which is similar to the hyperTalk commentary but with the javaScript negation operator !
An easy memory trick "not a hypertalk comment" <!--your comment-->

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)

So, for example
document.write('This will write to your browser's window.')

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. This is probably fixed in later browsers though.

A basic example

The following is a sample HTML document containing a JavaScript program.

<!-- 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>

<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>



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.


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 page itself would be the corresponding concept. Each page corresponds, roughly, to a hypercard card, and a series of pages makes a web site just as a series of cards makes a stack. The replacement in HTML/JavaScript depends, in part, on the intended use of the card in your program. Sometimes a card is used only to group information, though more often a card will group information (in fields) and "features" (in buttons) - just like a web page.

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. Basically a form is one or more buttons (radio, check box or normal) and fields. 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. Using CSS you could create a style sheet to allow a standard personalized format for your web pages - but that is beyond the scope of this paper. Further most of the "standardization" you can get through CSS you can get just by using HTML - without having to learn _another arcane code _and without the risk of incompatability. HTML is rougher than DHTML/CSS etc. but is _reliable.

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="alert('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). Note that the buttons are ugly and square - if you want fancier buttons you might want to use a graphic as a link.

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, it is in general a good idea to have only one radio button in a group on at one time - that is stylistic but it is a convention and easier for your audience to use.

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 can 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. While you _could put all your information in fields, just like hypercard, this is generally not done. In HTML You have more control over the text and can make text do more if you included it in the main document. Fields do exist and have their uses though, generally as places to put "interactive" information and to get information from your audience.

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 size=30 value=SamR name=username  >

You can put a value into a field by writing
document.formName.fieldName.value = expression
This corresponds, roughly, to  get card field fieldName of card formName - i.e. the "dots" translate into "of"s - and you have to read the code backwards... See why I like hypertalk better than javascript?

You can also refer to the value in a field as

alert(document.formName.fieldName.value)
Which could correspond to the command:
 
"answer field 1"


The problem though is that while hypercard lets you pretty much "set" any property you can "get" a lot of javaScript properties are "read only". This will probably change as time passes though but in doubt presume that a property is read only - that will avoid frustration - look at "read/write" properties as "a bonus".

Scrolling fields

Fields in HTML have to be coded by hand (unless you are using an expensive tool). A field in html looks like this:

<form><textarea name="formName" cols="65" rows="5"></form>

To refer to this form in javascript you would say

document.formName.textAreaName.value

Menus

If you look at hypercard as a browser (or vice verse), in hyperTalk using doMenu you can access all the hypercard "browser" commands and script your "browser". Unfortunately you just cannot do that in javaScript. In fact hyperTalk generally is a lot more powerful than javaScript. You can get a "menu" like effect using DHTML or "drop" selection lists - but it is neither as easy or as powerful as hyperTalk using doMenu.

JavaScript can emulate hypercard's "do" command - at least sort of. The eval(); function in javaScript will evaluate a text and if it is a command do it, e.g.  eval(theString). If the string is valid javaScript it will run - otherwise you will get a javaScript error message.

Thus for example
eval('alert("Hi")')
Will send up an alert box "The Text" which you then have to click "ok" to get out of. Again, not as easy (at least to me) as

do(answer "Hi" with "Ok")

JavaScript commands use single quotes but concatated commands use double quotes.
 

Windows

To open a new window in javaScript you use the window.open('URL', 'NAME', 'width=X,height=Y)

For example:
window.open('newwin.html', 'wowWin', 'width=280,height=50')

Thus the optional parameters include

toolbar yes/no or 1/0  -- Display toolbar
status yes/no or 1/0  -- Display status bar at bottom of window
menubar yes/no or 1/0 -- Display menubar
scrollbars yes/no or 1/0 -- Display horizontal and vertical scrollbars
resizable yes/no or 1/0 -- Window can be resized
location yes/no or 1/0 -- Display location box
directories yes/no or 1/0 -- Display directory buttons
width # of pixels -- Exact width of new window
height # of pixels -- Exact height of new window

In hypercard this would be

hide/show menubar
open Stack yourStack

JavaScript's object hierarchy

JavaScripts object hierarchy can get really complex. That is bad for you and your program. Keep it simple. Just like you can have a dozen different backgrounds and confuse the he11 out of your hypercard stack so you can have zillions of frames etc. etc.

window.document.form.formtype.

Is the hierarchy you want to know about. Each of these elements in the chain has about a dozen properties

window.navigator.plugins[]
window.navigator.mimeTypes[]
window.frames[numberOfFrames] 
window.location
window.history
window.document.forms[]
window.document.forms.elements


window.document.anchors[]
window.document.links[]
window.document.images[]
window.document.applets[]
window.document.embeds[]


Source: tech.irt.org

Thus to refer to change the value (i.e. the contents) of the first field in your first form on your webpage:

document.forms[0].Text[0].value="myNewText"

or

document.forms[0].Textarea[0].value="myNewText"

since javaScript has two forms, one with only one line (text) and one with several (textarea). Notice that window is implicit.
 
 

hyperCard's object hierarchy

Hypercard's document object model (DOM) is actually much much simpler than that of javascript. You only have the following objects:

Stack
Background
Card
Button
Field

though you can of course have movies, pictures, sounds and other resources.

More importantly the way objects are related to each other is much more intuitive. First, rather than using a series of points to indicate hierarchy
e.g. var a=document.forms[0].text[0].value
hyperTalk uses the word "of".

Thus:

put the value of card field one of this stack into a
--the hypercard equivalent

Second, as is implied in the above, you can use "relative" terms like "this" and "it" to refer to objects. "It" refers to the most recently accessed object. This refers to the object itself. It has a near equivalent in javascript known as self. It has no near equivalent in javascript, though it is not a reserved word and can be used as a variable if you wish.


                    The hyperCard Document Object Model

you can also visualise hyperCards message passing as follows:

It is possible to pass and intercept messages in javascript. However different web pages cannot pass messages to each other. Further the message interception and transmission characteristics of message passing are browser specific. Finally javascript cannot easily save or modify files - if at all - except for cookies. These are the reasons why javascript can be considered "underpowered.

Examples:

Getting back to the object model

card field one of stack myStack

card field one of stack myStack

in hyperTalk is roughly equivalent to

window.document.formName.textName.value

Translating the hypertalk "of" into javaScript "." we could see a pseudo code representation of the hypertalk hierarchy...

Stack.Background.Field
Stack.Background.Button
Stack.card.field
Stack.card.button
--Not Valid HyperTalk syntax!
That is not valid hyperTalk syntax but is given so you get an idea of how the two languages "think".
 


Output

JavaScript presents a number of ways to give output to the user. You can present output in dialog boxes (answer and 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.

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

alert("to-be-displayed")
So for example:

alert('Bonjour\n'+
'this is an example\n'+
'which will put a carriage\n'+
'return into the text of the alert box.');

The hypertalk equivalent would be

answer "alert" with "ok"

The quotes are optional in hyperTalk. This is how you get a two valued alert box in javaScript

if (confirm('This tests if the user agrees')){
  alert('You bought it!');
} else {
  alert('You doubt it!');
}
Isn't that ugly and hard to read and less intuitive than hyperTalk? Worse there is no standard format for braces - or an autoformatter. So

if (confirm('This tests if the user agrees'))
    {
      alert('You bought it!');
    }
else
    {
      alert('You doubt it!');
    }

is just as correct. Will we ever get hyperTalk as a scripting language for the web?  In hypertalk...

answer "This tests" with "you bought", "you doubt"
if it is "you doubt" then
answer "You doubt!"
 

We can also ask for information from the reader. This is done in javascript with the "prompt" command and in hypercard with the "ask" command.

Thus

variable = prompt('Question', 'Suggested answer');

translates into

ask "Question" with "suggested answer"
put it into variable

There is also the alert box in javascript. The alert(); command is useful because it lets you test variables. Remember that javascript, unlike hypercard has no built in debugger. So you will have to debug your stuff by hand, using tricks like alert(aVariableToTest);
HyperTalk has no alert(); command because answer "buttonText" does the same function. I.e. hyperTalks "answer" is actually more flexible than javascript alert(); and prompt(); because you can specify the number of possible responses and their text.
 

In a field


To write to a field in hypertalk is easy:

put value after card field one
--puts a new value after whatever value is already stored in card field one
put value into card field one
--replaces the value of card field one

In javascript:

document.formName.textFieldName.value="your value here!"

is equal to "put into" - but put after is just not as easily available. Could  be done using the + symbol which is javaScript's equivalent to the & symbol and concetates two strings into one, maybe something like...

document.formName.textFieldName.value=
document.formName.textFieldName.value+"your value here!"

In the message box

There is no message box in javaScript. There is also no variable watcher, no debugger, and scripts are not automatically indented by the hypertalk/think pascal autoindenter. See why I think javaScript could also be called "yayaSuck"? Ugly, underpowered, unreliable, and potentially expensive... Must have the microSuck seal of approval... Maybe someone will be crazy and develop a hypertalk--> javascript parser... Uh huh. in my dreams.
You can use the following:

put "your text here" into msg

is similar to:

window.status='your text here';

Using the status bar

Far too much has already been written about animating the javascripts status bar. It is frankly cheezy to do so as the statusbar is small, grey and hard to read - so it will needlessly distract your audience. Just say 'no' to pointless animation.

Using another window

One of the reasons that javaScript is considered useful is that it lets you write documents 'on the fly' (<-- latest buzzSpeak...). Using

window.open(yourWindowName);
document.write(your HTML formatted text);
document.write(yourFunction);

you can write just about anything you want. Using the concatation symbol + and the escape character symbol \ you can write an entire web page depending on whatever your user has done. For example, this is how a search engine could compose a list of sites.

A similar function can be done in hypercard. You could

doMenu "New Card"
set the title of this card to yourTitle
doMenu "New Field"
put "YourText" into card field 1


Events

A key issue in the design of your HyperTalk programs is 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. Just like hypeTalk, javaScript is an "event driven" "object oriented" language. That means that the program reacts based on your actions and it reacts through hierarchically organized compartmentalized objects which "communicate" with each other.

The basic events in javaScript, listed in approximate order of their occurrence on a page and in order of importance and with associated object are:

onLoad <!-- Window, Document-->

onMouseOver <!--Link, Image, Layer-->
onMouseOut  <!--Link, Image, Layer-->
onMouseDown <!--Link, Image, Layer, Button-->
onMouseUp <!--Link, Image, Layer, Button-->
onClick <!--Link, Button-->
onDblClick <!--Link, Image, Layer, Button-->
onKeyPress
onKeyDown
onKeyUp
onChange <!--Selection, Fields-->
onBlur, onFocus <!--Window, form elements-->
onReset onSubmit <!--Forms-->
onError <!--Image, Window-->
onAbort <!--Image-->

onUnload <!--Window, Document-->

As you can see some of these handlers have hyperTalk equivalents: here is a correspondance table which shows their relations.

javaScript         hyperTalk
-------------------------------------------------------
onLoad, onUnload   on openStack, on closeStack
onMouseOver        on mouseEnter
onMouseOut         on mouseLeave
onMouseDown        on MouseDown
onMouseUp          on MouseUp
onKeyDown          on KeyDown
onKeyUp            on KeyUp
onClick
onDblClick         on mouseDoubleDown
                   on mouseDoubleUp

onKeyPress
onChange
onBlur, onFocus
onReset onSubmit
onError
onAbort
 
 
 
 
 

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 step()
{
  document.stuff.counter.value = document.stuff.counter.value - 1
  if (document.stuff.counter.value > 0) {
  }
}
function startCountdown()
{
  document.stuff.counter.value = 100
  step()
} // startCountdown
Or more simply:
setTimeout(alert('time\'s up'),1000);
<!--the \ allows use of the apostrophe-->

mouseDown and mouseUp

For buttons, we wrote handlers for the user pressing down on the button (on mouseDown) and for lifting up (on mouseUp). JavaScript provides onClick, which is essentially a combination of the two.
JavaScript also provides an onMouseDown event (one word and the lower/upper case counts!) as well as onMouseUp. onMouseOver and onMouseOut also exist but only apply to links and not to buttons.

mouseEnter

The equivalent to hyperTalk's on mouseEnter  would be onMouseOver for links. For fields the equivalent would onFocus.
 

mouseLeave

The equivalent to hypertalks on mouseLeave would be onMouseOut for links, onBlur for fields.

openStack, openBackground, and openCard

onLoad in the body tag has roughly the same effect as "on openStack"

<html><title></title>
<head>
<script language="javaScript">
function yourFunction()
     {
     document.write('this should work, if it doesn\'t sue me and hack on it')
     }
</script>
</head>
<body onload="yourFunction()">
</body></html>

closeStack, closeBackground, and closeCard

onUnload in the body tag has roughly the same effect as "on closeStack". 

Mathematical Functions and Operators

JavaScript offers all math functions in its Math object, one of its strengths. All basic trigonometric, arithmetic, and logical operators are provided for. This is also true of hyperTalk but these functions are supported differently.

Math in hypercard is in my opinion a weak point. The math functions were simplified to permit anyone to use the program but at the expense of some good basic math habits.

In hyperTalk you the instruction "add one and two" is valid and return "3" (or "three") - unlike javascript. However in hyperTalk the instruction "x = 1 + 2" is an invalid instruction and returns an error - also unlike javaScript, which would return "3" (and not "three").

Because hyperCard is intended to be both simple pedagogical it offers the user both words and numbers. Some persons might confuse "4" and "for" or "2" and "to", for example in an iteration loop

for I = 1 to 2

The javaScript math object, like hypercard,  lets you calculate arcs, cosines tangents and all that other math stuff.

add xx to yy

xx += yy should result in a valid addition of yy to xx in javaScript.
In hypercard it would just be add xx to yy.
But note that in hypercard - unlike javaScript the statement

xx = xx + yy

is not valid - which always gave me headaches since basic was my first language.

add xx to yy
--incorrect!

is much less logical to me than x = x + y - which is not available in hyperTalk but is available in javaScript.

multiply xxx by yyy

xxx = xxx * yyy

xxx*= yyy

Random numbers

Pascal has a built in ran(); function and a standard random() function in its libraries. Hyercard uses random(aNumber) which will return a random value of zero to the value of aNumber.

Math.random(); is the javaScript function. The question is what does math.random(); return ? It returns a decimal between 0 and 1.

You probably would prefer a digit, say 1 to 6 to simulate rolling dice.

Math.floor(Math.random()*6)

does that.
 

Advanced Functions

HyperCard and JavaScript both allow calculations of arcs, cosines, tangents, and logarithms. HyperTalk also allows calculation of annuities. Here we will list some of the more basica

Math.abs(x)
returns the absolute value of x (i.e. removes the - or + sign of the number)
abs(x) or the abs of are the hyperCard equivalents.

Math.ceil(x)
rounds up a number
Math.floor(x)
Rounds down a number
Its hyperTalk equivalent is round(x)

Math.min(a, b)
Compares a and b and returns the smaller valueof values a or b
Its hyperTalk equivalent is
min(a, b)

Math.round(x)
Rounds off x to the next higher or lower digit depending on the value of the decimal of x.

hyperTalk functions
trunc(aNumber)
will eliminate the decimal portion of aNumber regardless of the value of the decimal portion of aNumber.
 

Logical Operators

The basic logical functions are "and", "or" and "not". Not negates the value of an expression. And compares two values and if both are true returns true. Or compares two values and if either are true returns true.

&& And
||  Or
! Not

Those incidentally are the logical operators in hyperTalk. Thus if a is true and b is false:

!a
not a
-------------
will deliver: false

ab a && b
a and b
----------
00 false
01 false
10 false
11 true

ab a || b
a or b
---------
00 false
01 true
10 true
11 true


Containers/string manipulation

One of strength of xCard is its ability to manipulate text easily and in a language that is pseudo-English.

For example "get characters 1 to three of eric" will return "eri" in hypertalk.

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 xx in yy). JavaScript does not provide such a full collection of options, but we can build functions that do much the same thing. This again is why a real argument can be made for hyperTalk: easy advanced string search and manipulation.

It is important thing to remember that strings in JavaScript begin indexing with 0, rather than with 1. For example, the initial character in a string is character 0, rather than character 1. This is also true of javaScript arrays. The opposite is the case in xTalk - there the first character is character 1.

JavaScript also has a type of container called the array. JavaScript is better about manipulating arrays than strings. Hypercard does not use arrays, rather all containers (fields, strings)  in hyperCard act as arrays. Thus you can refer to "item one of container" "item 2 of continer" "item X of container". If I have a field myField which contains the following text "Eric Allen Engle, http://lexnet.bravepages.com"
and say "put item 1 of myField" the message box will display "Eric".
 

In HyperCard, all strings should be surrounded by double quotes. Unquoted strings can be used but you must be careful not to accidentally assign them a numerical value - that is uninitialized variables are treated as strings. It is definitely good style to always quote variables.

JavaScript lets you surround variables with either double quotes (") or single quotes ('). Both languages let you use unquoted variables as strings - which is a really bad idea since you will not be sure whether you assigned a value to the variable or not and may cause bugs.

Concatenation

Surprisingly, in javascript you simply use the addition symbol (+) to concatenate strings.

myvar=3;eval
alert("eric"+" "+"allen" +myvar)

will display an alert box which says "eric allen3"

The equivalent in hypertalk is the ampersand (and per-se and) && includes a space & includes no space and & just "jams" everything together.

Thus
put eric & allen && engle && myVar
will return ericallen engle myVar in the message box. If you have assigned a numeric value to eric or allen or engle or myVar the number will be returned.

I generally use alert boxes in hyperCard and the message box in hypercard for debugging.
 

The length of a string

Get the length of it

is a perfectly valid hypertalk command. In javascript

array.length
 

should return the number of elements of an array.

string.length should return the length of a string.

Thus, for example:

myvar="joj";
alert(myvar.length);

will put up an alert with "3" because "joj" has three characters.

Javascripts biggest deficiency when compared to hyperTalk is the absence of a variable watcher, script debugger and message box. You could make a message box using the eval();command. I have had little success with the MS and Netscape debuggers and no success at making a variable watcher.
 
 

char n of xxx

get char n of yourString
is hyperTalk. Its javaScript equivalent would be
yourString.substring(n, m)
Example:
myvar="EricEngle";
alert(myvar.substring(4))
will return "Engle"

alert(myvar.substring(4,5))

will return "E"

alert(myvar.substring())

will return the entire string, "EricEngle"
 

char n to m of xxx

The basic commands are again the same, namely
get char n to n1 of yourString
in hypertalk and
yourString.substring(n, m)
in javascript.

Examples:

get char 3 to 5 of "Eric"

returns "ic". In javascript.
 

eric="eric";
alert(eric.substring(2,3))
returns "i"
 
 
 

item n of xxx

Put item 3 of "eric allen engle"
will return "engle".

in javascript:

myVar.slice(start,stop);

jojo = new Array(1,2,"eric");
alert(jojo.slice(2,3));
alert(jojo);

jojo.sort;
alert(jojo)

will first put up an alert box that says "eric"
and then will show an alert box that says "1,2,eric"

sort the lines of card field 1
will alphebetize the field, line by line. First numbers, in ascending order, then letters also in ascending order.

In javascript it is not so easy:

jojo = new Array(2,17,2,"eric", "engle");
alert(jojo.sort());

will return first the numbers in descending order then the letters in ascending order, that is 17, 2, 2, engle, eric It is possible to alter this (if you know how tell me), but it is obviously much easier to use the xTalk sort function.

line n of xxx

Put line 3 of card field 1
is a valid xTalk command.
I have not however found an equivalent for javascript. I am sure one exists. If you have a solution let me know!

put xxx before yyy

We should distinguish between string manipulation, i.e. changing text, and field manipulation, i.e the way we display the text. Basicaly hypercard goes from the presumption that most work will be done in fields, though it allows all string manipulations. Javascript presumes you are going to first manipulate the string and then display it. Thus

In hypercard:
Put "http://lexnet.bravepages.com" before card field 1

will put http://lexnet.bravepages.com immediately before card field one.

Similarly:
Put "http://lexnet.bravepages.com" after card field 1

will put http://lexnet.bravepages.com immediately after card field one. This can be done in javascript using DHTML.
I have not however found an equivalent for javascript i.e. to dynamically alter the contents of a field. I am sure one exists. If you have a solution let me know!

Manipulating strings in javascript is relatively easy.
In javascript:

var myFirstString = "eric";
var myPlaceHolder = ", ";
mySecondString = "engle";
myNewString = mySecondString + myplaceholder + myFirstString;

returns "engle, eric"

put xxx after yyy

Now instead of putting secondString before firstString we put firstString before secondString:

In hypercard:
Put "mySecondString" before "myFirstString"

In javascript:

var myFirstString = "eric";
var myPlaceHolder = " " mySecondString;
mySecondString = "engle";
mySecondString =  myFirstString + myplaceholder + mySecondString ;

will return "eric engle".

Pattern matching


find is, for me, the most useful command in hyperCard. There are in fact several different find commands which allow you great precision in hyperTalk - find string, and find whole for example. I mostly use find string because it finds exactly what you are looking for .
 

In javascript the command is:  find(yourString)

function findString
     {
     yourString=getSelection();
     find(yourString);
          }

is equivalent to

on findTheString
     get the selectedText
     find it
end findTheString

Note however that the getSelection() and find() commands are only available in netscape navigator. I have no idea when or whether these commands will be available in internet explorer, opera, or konqueror.  This is one big disadvantage for javascript: it has several dialects which are unique to a browser. Thus "sniffing" browsers, i.e. figuring out which browser your reader is using,  is essential to any but the most basic javascript commands.




Control Structures

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)

Code blocks in javaScript are just as ugly and ungainly as in C, C++ or Java
blockName
{
command();
command2();
}


The left curly brace ({) opens a block of JavaScript code and the right curly brace (}) closes a block of JavaScript code. The left brace is basically the same as "begin" in Pascal or hyperTalk. The right brace is basically the same as "end"
Anyway at least the instruction separator - the return key in hypercard - is a semicolon - just like pascal.

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 javasCript -everything- has to be complicated...
if(condtion)
        {
        instruction1;
        instruction2;
        instruction3;
        }
  else if (condition)
        {
        instruction;
        }
  else
        {
        instruction;
        }
Technically it is possible to do "if" and "else" statements without braces. I do not recommend that. It is better to use the excess braces since you might forget whether they are needed or not. Further when the braces are not needed you can only use one command which must be on only one line. Later you might want more than one line.

if(condtion) instruction1 else if(condition) instruction2 else instruction3

May be valid code and should parse. But why make your job harder? Just use braces. Incidentally the semicolons are also superfluous so long as you use one line per instruction. But again such "shortcuts" actually generate more work later when you delete a space or want to add an instruction or worst "forget" a brace.

Note that I have never gotten the "logic" of C's tendency to "dangling braces", i.e. braces which have no logical position that I can fathom - just some arcane senseless convention. By aligning braces and using them on seperate lines even without an autoformatter to help it should be possible to write and read your programs.

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(anyVariable=starting-value; anyVariable<=ending-value; ++anyVariable) {
  ...
}

Yes, you need those semicolons (command seperator), curly braces (block seperator), and double plus (increments the loop). You could use

To redo our HyperTalk example in JavaScript, we would write

product = 1
for(i=1; i<=10; ++i) { <!--this is considered good form but I would put the brace on its own line-->
  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


repeat while condition
    instruction1
    instruction2
end repeat
 

while (test) {
  stuff-to-do
}
I personally find that really annoying the dangling crochet. Yes it is the "correct" style.
Yes it is unreadable. Here is, in my eyes, a better example.
while (x=3)
{
  alert('X is still equal to three!');
  alert('X is still equal to three!');
  alert('All your base!');
}

Repeat until


repeat until condition
    instruction1
    instruction2
end repeat
 
 

Functions

A function is just a set of instructions which does something and/or returns a value. Its just like a "gosub" in basic, an

on yourHandler
    instructions
end yourHandler

in hypercard. In javascript.

function functionName {instructions;}
 
 

Defining functions

Hypercard has the advantage of having perhaps the easiest way to learn what a function is and does. A function is simply this: a math formula that leads to a certain outcome. In computing science though the math formula can do things like write to your screen the printer, play a sound etc. - which is why computer science is morrre iinteresting than math!

In hypercard we write a function just like a handler.

on functionName (optionalParamaters)
     instruction1
     instruction2
     instructionN
end functionName

In basic we did functions using sub-routines : GOSUB 100 would send us to line 100 where the computer would do its commands till it reached a RETURN statement. Whether you place your functions at the end of a document, like GOSUBs in basic, or at the head like in pascal or anywhere you please, like hypercard, the concept is the same: function call, instructions, return any value and go back to the main program.

In javascript we have to deal with annoying braces and we must always place the paramater parentheses even where there are no variables sent to or returned from the function - i.e. a "void" function still requires parenthesis - unlike hypercard where the parentheses for a void function are not needed

function functionName(param1, ..., paramN)
{
  instruction1;
  instruction2;  
  instructionN;
}

Function calls

Functions in hypercard are easy enough. You may declare any handler essentially forming a function. Thus

on myHandler
    instructions
end myHandler

You can also make functions that return values. Thus in hypertalk:
 

function myFunctionName Paramaters
    instruction
    return theResult
end myFunctionName

Which in javascript can be accomplished using:

function myFunction(paramaters)
{
    instructions
    return theResult
}

Paramaters are passed to the function in the variable or variables listed in paramaters. The result of the function, if any, is sent back using the command return variable. The paramaters and variable returned should logically be global variables.

Examples

on sum x, y
    add x to y
    return it
end sum
 

function sum(x, y)
{
    return x + y;
}


Function parameters

Passing paramaters to a function or getting paramaters back from a function is optional in most any programming language including hyperTalk and javaScript. However the variables used within a function are "local" to the function, i.e. they are only available within the function and cannot be used or read elsewhere.

To avoid the question whether a variable is local, i.e. limited to the function in which it appears, or global, i.e. available everywhere, I simply use only global variables and declaring them at the top of my scripts. That is considered bad programming style, probably from the days when stack space was limited (globals reside on the stack). Due to memory advances that concern is no longer valid. Further global variables can be justified becase javascript has no decent debugger and uses loosely typed variables and flexible arrays both of which are far worse for coding discipline than using only global variables. In hypertalk I sometimes indulge in local variables - though unlike pascal they are not need in hypertalk. JjavaScript is an underpowered and ugly language with no debugging environment to speak of. However it is too useful to be ignored.

Conclusion:

One nice thing about learning javascript - though it is ugly it lets you decide whether you want to learn java or not. At this point if there were a really good developper environment for java (which there probably is) I would actually consider working around those mean ugly hanging braces with no autoformatter. But my true love is Pascal - which explains why I think hyperTalk is so cool.