Javascript Light

From Numerus
Jump to navigation Jump to search

NovaScript and JavaScript

NovaScript is an extension of a well-known and widely used language called JavaScript. This means that NovaScript uses JavaScript syntax for all of its code; moreover, any legal JavaScript program is also a NovaScript program. This includes the code used for initial Stock values, Flows and Terms. Fortunately, there are many good sources for learning to program in JavaScript. We will review a few important ideas about programming as it applies to building Numerus models below.

Statements, Commands, Expressions

Programs consist of one or more statements that operate on data values. The latter are expressed either as constants or variables. Statements are divided between expressions, which compute a value using operators of various sorts (e.g., the arithmetic operators +, -, * and =); and commands, which change the state of the program by assigning values to variables, or by performing some side-effecting operation (e.g. “print”).

The values used in a program are categorized according to their datatype. Virtually all programming languages include one or more numerical types (e.g., integer and reals, also called floating point). Another common datatype consists of textual data, which are called character strings, or just strings. Finally, languages generally provide some means of combining multiple values into a single entity. These include arrays, which are sequences of values indexed by integers; and structures or objects, in which the components, or fields, are labeled by a string property names.

JavaScript Highlights

JavaScript has become a prominent language if for no other reason than its role as the standard for programming the behavior of Web browsers. Here is a brief list of JavaScript highlights which will be of particular use in NovaScript. While this review is not enough to teach you how to program, it will help you to understand much of the JavaScript that appears in Numerus. Click here for a complete JavaScript reference.

Variables

Variables are declared using the var keyword:

var x = 17, y = "hello"; 
var y;

In the latter case y is initialize to undefined. Variables are not restricted by datatype and can be assigned a value of any JavaScript type.

Datatypes

Floating Point
(i.e. real) numbers: 1, 3.14, 2.78e01
Character Strings
"This is a character string", "So is this".
Arrays
In JavaScript arrays are lists, or sequences, of values indexed by an integer argument. An empty array is created using the new keyword as follows:
 var a = new Array();
Array constants are denoted using square brackets; e.g., var b = [1,2,3,4]. Similarly, array components use square brackets to denote the index for assignment and access; e.g., b[0], b[1]. Unlike most languages, however, the index set may contain holes; e.g., b[0], b[1], and b[7] may be defined while b[2] through b[6] are not.
Objects
Every other datatype in JavaScript is an object. The simplest of these is the Object type, which consists of a list of fields. Each field contains a property name labeling a property value. A property name must be a string, but the corresponding value can be of any type. When an object field value is a function (see below) we call that function a method. The new keyword can be used to construct an empty object, to which name-value pairs can be added:
 var c = new Object();
Object constants are denoted using curly brackets enclosing the name-value pairs, and may included embedded object constants as values:
 var a_person = {name: "Steve",
                 date_of_birth: {month: 1, day: 28, year: 1980}
                }
Functions
Functions are unique in that they are both a datatype and contain actual executable code. JavaScript is one of a small number of computer languages that allow you to treat functions this way (sometimes called first class treatment). Consequently you can create a function, store it in an object or array, and pass it as data to another function where it can subsequently be executed. This kind of expressiveness turns out to be very useful for constructing complex Numerus models.
Functions are defined using one of two similar syntaxes:
 var double = function(x){return 2 * x;} 
 function triple(y){return double(y) + y;}
The first case allows you to create a function without the necessity of providing a name. For example, if
 var apply_to_two = function(f){return f(2);}
Then invoking apply_to_two(function(z){return z * z;}) will result in 4. This also shows that functions may be passed as parameters to other functions.

Program structures

JavaScript adapts the structure of the C and C++ languages for its code. Common control structures (i.e. coding structures that direct the flow of the program) include conditionals, for-loops and while loops. One particularly useful version of the for-loop specific to JavaScript has the following form, assuming variable a refers to either an array or object:

 for (var i in a) {
   print(a[i]);
 }

The index variable i will cycle through all defined indices in a. Another important feature involves the conditional, or “if” statement. Suppose we want to assign the maximum of x and y to z. One way would be

 if (x > y) {
   z = x;
 } else {
   z = y;
 }

This familiar statement is called a conditional command because it provides a pair of alternative commands, only 1 of which is actually executed, depending on the outcome of the conditional test.

An alternate way of doing the same thing uses the conditional expression:

 z = (x > y) ? x : y;

The right hand side expression produces one of a pair of values again depending on the outcome of the conditional test. This form is particularly useful in creating the Numerus expressions that appear in component definitions.

Primitive operators

Actual computation (i.e., combining and manipulating data to create new values) is performed by JavaScript's primitive operators, or primops. The most familiar primops to most people are the standard arithmetic operators (+, -,* , =). JavaScript provides additional mathematical operators via the Math object. This is a special object whose properties are bound to various mathematical functions. For example, Math.sin(x) computes the trigonometric sine of the value of x. A reference to the complete listing of available Math primops is provided here. A second large set of primops is provided by the underscore.js library. These functions are all properties of a special object denoted by the underscore character, _, and are documented on the library's Web page. For example, _.last(a) will return the last element of the array a.