1. Basic InstinctMost paused scene on VCRs: Elements of An Ox Program
  1. Introduction
  2. A computer program attempts to transfer a wish your clever but messy brain has into instructions for a dumb but orderly computer to do. If you are new to programming you have to learn about the different layers of symbols and meanings in any program written in a particular language. If you have already learned a language you will see how the rules of Ox compare to the languages you have learned.

    As with any other choice, there are tradeoffs between different programming languages. Many of these tradeoffs boil down to: Pay me now or pay me later. Some languages are designed to be "easy" to learn. Ox is not like that. Its rules are a lot like C and C++, which were not developed to be "easy". However, for doing economics Ox is much easier than many if not all other languages.

    This section introduces you to these overall features of an Ox program without delving into many details.

    Most of your time learning to program will be taken up with details discussed later not these features. And there is a limit to how much understanding of the list above can be gained without just doing it. So you might find it useful to simply skim this section first and return to it later if/when things go wrong. Some of these concepts include most of the meat of the program. Others are limited but very important in making your program readable, reliable and replicable.

  3. Comments and Whitespace
  4. A comment is text inserted into a computer program that is ignored by the computer when running the program. In this sense, comments are completely unessential to what the program does. However, comments are completely essential for you, other humans, and in some cases other computer programs to understand what your think your program does.

    Ox, like many languages, have two different kinds of comments. The first kind is text that falls between two special sequences of characters, /* and */. Special characters that begin and end different kinds of code in a program are called delimiters.

    
    /* This is an Ox  comment */
    
    Anything between /* and */ is considered a comment in Ox. This kind of comment can be nested (unlike C and C++):
    /*  A comment
        /* a comment inside a comment*/
    */
    println("hello world");
    
    Why would /* be used as a delimiter? The reason is that /* is never in a valid mathematical expression so it is safe for the language to use it as a special item. The other thing to note is that a single comment of multiple lines can occur in the program. This allows you to expand and format your comment to make it easy to read.

    Anything from // to the end of the line is also comment.
    // This is an Ox comment … until the end of the line
    
    Note that this kind of comment also has a beginning and an end, but the delimiters are not symmetric as in /* … */ comments. We get end-of-the-line by hitting the Enter key. It turns out that doing this actually inserts two special characters into your program that are not printed. One character says to return to the first column of the page. The other character says to create a new line. So really these comments are delimited by // … <CR><LF>. These comments make it easy to add an aside to your code. It also makes it easy to temporarily remove one line of code that you may later want to make operational again.
        one = cons + 1;   // comment
        /* two = cons + 1;   // comment inside a comment
        */
    
    Some computer languages like Python treat lines of code and spaces at the start of lines as important to the meaning of the code. Ox follows in the tradition of languages that do not care about lines (with a couple of minor exceptions). Each of the following code segments are the same in Ox:
    println("hello world");
    
    println( "hello world" );
    println( "hello world") ;
    println( "hello world" );
    The first two are probably clearer than the others because of the random patches of whitespace in the latter examples. You will develop your own style of programming in terms of adding or deleting whitespace. It is important for both you and readers of your code that your style helps display the logic of the code.
    The use of indentation in Python to 'structure' the code is perhaps the biggest difference between Ox and Python syntax. Ox uses braces, { }, to create blocks of code instead of indentation. And it uses ; to end statements instead of the end of a line or ENTER.
    Things Can Go Wrong with Comments
    While comments are essential for explaining (documenting) your code they do not do anything. They are removed by the process that implements or executes your code (discussed in the next chapter). But this means that comments can cause problems. First, you might not close a comment properly:
    /* My hello world program!! /*
    main() {
        println("hello world");
        }
    
    Here /* does not close out the comment above (should be */). Everything past main() is ignored because it is still in the comment. The other problem is a deleted end-of-line:
    // Print hello.  decl h="hello";
    println(h);
    
    The decl statement is accidentally on the same line as the comment. A syntax error occurs because h is not declared.

    As you start to write more complicated programs make sure the sophistication of your comments keeps up with the code. Notice this does not mean the quantity of comments have to expand as your code does.

  5. Identifiers
  6. An identifier in Ox is the name of something. The next section talks about different kinds of things in Ox. In our programs, most identifiers will be the name of variables and functions. As with all other languages, Ox has rules for what is a valid identifier. In Ox, identifiers are made up of letters and digits. The first character must be a letter. Underscores (_) count as a letter. Identifiers can't start with a digit because Ox will think it is a number (numbers are not identifiers). Identifiers can't have any other special characters other than _, because many of these characters have special meanings already. For example, + means addition, so you can't use a+b as an identifier. If you tried, Ox would think you are giving it an instruction: add b to a not referring to a thing named a+b. Identifiers are also case sensitive. So abc and ABC are two different identifiers.

    What about hello? According to the rules above, it is not an identifier because is neither a letter nor _. Instead it is a constant string (also called a literal string) rather than the name of something. Sometimes Ox will use strings as labels for rows or columns of output. Again, that is not the same thing as an identifier.

    There are some other rules about identifiers, both in Ox and other languages. For example, it would be confusing in English if someone's name was Me, or even worse, me. If we read Me says he is going to the store. it is hard to tell what the meaning is. Or, what would Give it to me! mean?

    Even though Me is otherwise a perfectly reasonable English identifier most parents would not torture their kids by giving them such a name, although Frank Zappa named his kids Moon Unit and Dweezil. They seemed to turn out okay. The jury is still out on X Æ A-Xii Musk. Poets like to play with the implicit rules of identifiers, including e e cummings, kd lang, and .

    The same is true in a programming languages: some valid identifiers are off limits to the programmer because they mean something special in the Ox language. In a programming language, such special identifiers are called keywords and/or reserved words. If you make the mistake of using an Ox keyword as an identifier it will probably create a syntax error, but Ox may have trouble telling you what the error is.

    Table 1. Keywords in Ox 9.0

    oxkeywords.txt
     1:    array     default   goto       private      switch
     2:    break     delete    if         protected    switch_single
     3:    case      do        inline     public       this
     4:    catch     double    int        return       throw
     5:    char      else      matrix     serial       try
     6:    class     enum      namespace  short        virtual
     7:    const     extern    new        static       while
     8:    continue  for       operator   string
     9:    decl      foreach   parallel   struct  
    
    Do not pick any of these as identifiers for things in your program. Your code will be misinterpreted by Ox. Ox will probably notify you of the problem. If you try to declare a variable with one of these names it will complain (try it!). Our programs will contain only a few of these keywords, but if you look at the full Ox syntax you will see each of them plays a special role just like me and the play special roles in English.

    Further, there are names that are valid identifiers and not keywords that are still bad ones to use. For example, you could use println as an identifier because it follows the rules and is not a reserve word. But that would be a bad idea if you ever want to print something out from your code.

  7. Constants and Literals
  8. If you look at a well-written Ox program that does some real work and count the characters in the file you would probably notice that it consists mostly of comments, whitespace and identifiers. The next most frequent components would probably be constants and literals. These come in different flavours which should be fairly natural, although some of the distinctions may not be clear until later.

    First, we have already encountered a literal: hello, world. This is a string constant. There are some details about strings best left for later since most strings in your code will be simple like hello, world. Next, we have integer constants such as 2, -33, 99999. A sequence of digits, with possibly a leading - is an integer constant.

    A double constant has a name that won't make sense because it comes from programming concerns in past decades. But essentially a double constant is a real number. As text it consists of an integer part, a decimal point, a fraction part, and optionally e, E, d or D and an optionally signed integer exponent. Either the integer or the fraction part may be missing (not both); either the decimal point or the full exponent may be missing (not both).

    Various ways of writing 1.0:
         1.0     1.      0001.0      1.00000   1E0   10E-1   0.001E3
    Various ways of writing 1/10:
         .1     00.1    .10000      0.10000   1E-1  10E-2   0.001E2
    

    We now encounter a first important feature of Ox as a tool in economics. Ox understands vectors and matrices. This is not true of all languages. For example, C has no notion of a matrix as we have, which is one of the motivations for an economics student to create a language like Ox. A matrix constant lists within < and > the elements of the matrix, row by row. Each row is delimited by a semicolon, successive elements in a row are separated by a comma. For example:

        < 0, 1, 2; 10, 11, 12 >
    
        < 0.0, 0.1, 0.2 >
    
        < 1100 >
    
    which are respectively a 2 by 3 matrix, a 1 by 3 matrix and a 1 by 1 matrix, the first constant is:
     0    1    2
    10   11   12
    
    The index of each row is one higher than the previous row. Within each row, the column index of an element is one higher than that created with the previous element in the same row. An empty matrix can be written as:
        < >
    
    At this point you might not see a reason to allow such a thing, but it turns out to be a useful when the program is going to construct a matrix bit-by-bit. Starting with an empty matrix and then building is common in larger programs. Further, Ox has a sophisticated way to create large and complicated matrix constants. For someone already familiar with a similar language it would make sense to discuss these features now. However, in this book we return to this material later.

    03c-const-matrices.ox
     1:    #include 
     2:    main() {
     3:     decl M ,x ;
     4:     M = < 0 , 1 ; 2 , 3>;
     5:     x = exp(1.0);
     6:     println("M = ",M,"\nx = ",x);
     7:     }
    
  9. Constant Arrays and Enumerations
  10. The thing that Ox documentation calls an array constant might also be called a list constant. A list constant is created in your code by placing constant items in curly brackets separated by commas:
        { "A crazy constant list" , 5.0 , 99 , TRUE , <1.0;3.0;5.0> }
        
    Here are some examples,:
    03b-const-arrays.ox
     1:    #include "oxstd.h"
     2:    
     3:    main() {
     4:    	println("Start/Finish",
     5:    		{ "hello, world", "goodbye, cruel world"}
     6:    		);
     7:    	println("Here are some random things in a list:",
     8:    		    { 12, 99.5, "pi" }
     9:    			);
    10:    	println(" Here is a list of lists: ",
    11:        	{ {"integers", -5  , 99,   0},
    12:              {"doubles" , 22.3, -0.5   },
    13:              {"strings" , "a" , "b"    } }
    14:    	  );
    15:    
    16:    }
    
    Run this program to see what is printed. A constant list might contain another constant list, so this is a recursive definition. The constant can itself be an array constant as shown in the last example. It is possible to do a great deal of computational economics in Ox without using ox arrays (lists). However, lists can be very useful in more complex code and they play a role in making you output from Ox look nice.

    Here is an Ox array (or list) that is not constant:

    decl v;
    v = 5;
    { 12, v, 99.1}
    
    The reason is that v is a variable (discussed below), and variables are not constant. Certainly variables can be put in a list, it's just that it will then not be a constant list. That means it may create an error when only a constant list would be allowed.

    Ox inherits from C the notion of an enumeration or simply enum. (Note that enum appears on the keyword list.) An enumeration is a sort constant list of integers. The enum itself contains indentifiers, but each identifier will be replaced with the integer it matches up to anywhere it appears in the program. Another way to think of an enum: it allows your program to give integers a meaningful name. You might think of an identifiers in an enum as aliases for integers.

    03a-enums.ox
     1:    #include "oxstd.h"
     2:    enum{Zero,One,Two}
     3:    enum{OFF,ON}
     4:    enum{MinusOne=-1,Zed,Three=Two+One}
     5:    enum{UNDEFINED=-2,WRONGTYPE=-3,BADINPUT=-4}
     6:    
     7:    main() {
     8:    	println(One," is the loneliest number\n",
     9:    			Two," can be as bad as ",One);
    10:    	println("A valid name for ",MinusOne," is MinusOne.");
    11:    	println("You can do simple arithmetic in an enum: ",Three," equals ",Two," + ",One,": ",Two+One);
    12:    	println("But enums are not variables.  Uncomment the next line to see an error.");
    13:    	//ON = 1-OFF;
    14:    }
    
    Run that code and see how the identifiers in the enum get replaced with integers. In other words, One is now exactly the same as putting 1 in your code.

    Here is another explanation to explain what happens in that code. At the start of the enum statement Ox sets a "counter" to 0. Unless you put = in the enum list the counter is incremented by 1 after each comma. The identifier you list then takes on the value of the counter. Putting = in the enum followed by an integer resets the counter to whatever follows the equal sign. Here is the idea:
                                                                    //Hidden Counter Value
            enum {                        // 0
                         first 
                         , second               // 1
                         , fourth=3             // 3
                         , sixth=fourth+2       // 5
                         }
            enum { another_first }       //  0
    
    The enum's above create five identifiers that can be used in the program: first, second, fourth, sixth, another_first. The comments show you what value each identifer will take on. If in doubt, just print out the value of items in the enum. The first enum starts at 0, increments automatically to 1 after the first comma, then gets set to 3 and then gets set to 5 because fourth+2 ≡ 3+2 = 5. The second enum resets to counter to 0. So now there are two different names for 0 available in this program: first and another_first.

    So in the program MinusOne gets the value of -1. Then, unless there is another equal sign, the next item in the enum will be an alias for -1+1 = 0. So Zed is an alias for 0. Enums can also include very simple arithmetic, as in the case Three=Two+One.

    Python has something called enum that has some similarities to Ox or C enums, but is more flexible and less simple to set up.

    Notice that Zero, OFF and Zed are all aliases for 0. Any integer can have multiple aliases in your code from different enums. Why allow this? Without using enum{} your code may have lots of integer constants like 0 or -1. Sometimes 0 will mean one thing, at another point it means another. If your code changes you might change some of these 0s to 1s but keep others the same. Further, 0 does not tell us what it means, whereas OFF can mean something even if it is just an alias for 0.

    Ox has some built-in or pre-defined enums{}. One that you should learn to use in order to make your code more reliable is:

    enum{FALSE,TRUE}
    
    In other words, your program can replace the integer 0 with FALSE and the integer 1 with TRUE. (You do not have to include the enum definition because it is part of Ox.) This reflects something discussed in more detail in the next chapter, that the number 0 is associated with something being false and 1 with it being true.

    New programmers are easily confused by things like constants and enums. One reason is that this explanation that Ox has a hidden counter for each enum statement happens before your program starts executing. Other things like calculating the square of a value and storing it somewhere happens while the program executes.

  11. Things Physically Exist During an Ox Program
  12. The official Ox term for a thing is an object. However, "object" is sometimes used to refer to one particular kind of thing. So here I use "thing" to refer to anything in your program that has a particular physical location in computer memory assigned to it while your program is running. Most things in basic Ox programs are either a variable or a function.

    It may seem strange to think of an aspect of a computer program as a physical thing. This physical location is an amount of computer memory is associated with the thing in question. Memory consists of semi-conductor bits which are actual physical locations on the memory chip. On the other hand, in enum{Off,On} On and Off are not things because they are just tags for the numbers 0 and 1. Before your program begins to execute the Ox system replaces those tags with the digital value of the integer. So as your program runs On is not associated with a location in memory. So an enumerated value like Off above is not considered a thing (or an object in the official Ox lingo).

    A thing in Ox must be declared before it is used (referred to). If you try to use a thing in Ox before it is declared then Ox will complain and stop executing your program. Variables are declared with the decl operator.

    Python does not require you to declare variables before you assign a value to it, so if you know Python you have to get used to this in Ox. There are pros and cons to requiring explicit declaration, so this does not make Python better just easier to use for simple programs.

    Functions are declared by simply listing the function name and its arguments. This can be done separately from the definition. Or both the declaration and definition can be done at the same time. (The possibility of separating them makes it easier to break a large program into separate files, as discussed later.)

    f(a);                       // declare a function named f but do not define it yet
    
    decl y;                     // declare a variable named y
    
    g(b) {                      // declare a function g and at the same time define it.
        println("b= ",b);
        }
    
    In Python you put the keyword def before the name of the function when defining it. In Ox you simply define it by placing { after its header.

    Languages like C, FORTRAN require that a variable's type is specified when it is declared. If you create an integer named j in C then j will be interpreted as an integer at all times during the program. These are examples of statically typed languages. Ox and Python are examples of dynamically typed languages. If you decl j it starts as uninitialized (no type). It can then become an integer, change to a string and end up as a function while your program executes! If you have only coded in statically typed languages before this can be a bit confusing.

    Basic Types of Ox Variables

    Here is some text from the Ox documentation. It probably won't mean much to you but if you are a trained programmer it might be helpful:
    Variables in Ox are implicitly typed, and can change type during their lifetime. The lifetime of a variable corresponds to the level of its declaration. Its scope is the section of the program in which it can be seen. Scope and life do not have to coincide.
    Is that clear? Probably not. The ideas of "scope" and "lifetime" are hard to understand without some knowledge of how programs actually run on the computer. But within a given language like Ox their meanings can be learned by trial and error and lots of examples. Here is some code and an explanation of the concepts to get started:
    03e-things.ox
     1:    #include "oxstd.h"
     2:    decl joe;
     3:    f() {
     4:        decl sally;
     5:        sally = 5;
     6:        }
     7:    main() {
     8:        joe = "hi";
     9:        f();
    10:        }
    
    There are two variables in the code, joe and sally. The scope of joe is everywhere because it is declared outside of any curly brackets. That means joe can be seen and used anywhere below its declaration. The scope of sally is simply the statements between { and } that surround it. So the main function cannot see sally (try printing sally inside main and see what happens).

    The lifetime of an object is when the variable exists. Since joe is global (declared outside any brackets), it exists the whole time the program executes. The lifetime of sally is normally only while f() is executing. (The contents of sally can continue to exist after f() finishes if it contains an object of a class, but this is not important for basic Ox programs.)

    The basic Ox types are listed below. Later chapters discusses several more types and go into depth about the life of things.

    int
    an integer, holding values like 5 or -493
    double
    a real number holding values like 13.2 or -3.19417.
    matrix
    a two-dimensional grid of real numbers which can be manipulated as a whole, such as $\matrix{1&2\cr 3&4}$.
    string
    zero or more characters as in hello, world.
    array
    a list of Ox things (technically, references to things). The word array is often used more generally, so these notes will usually use list instead.
    What Ox calls "double" Python calls "float". (Exercise: find out why these names are used instead, for example, "real." Python is not matrix-oriented so it has no native matrix variable type. Python's "list" type is essentially the same as Ox's array type. Python's "tuple" type is the same as a const decl array in Ox. Ox 8.0 does not have an equivalent to Python's dictionary type, but Ox 9.0 will have something similar.
  13. Modified decl statements
  14. You can modify how a variable is stored by adding one (and in some cases two) of three keywords to the decl command. The main one we see in this class is making the thing a constant. (The other two are static and extern, which are used in classes and programs that involve multiple files.
    03c-const-decl.ox
     1:    #include "oxstd.h"
     2:    
     3:    decl y;
     4:    
     5:    const decl answer = 42;
     6:    
     7:    main() {
     8:     	y = 5;
     9:    	println("y= ",5," and the answer is ",answer);
    10:    	y = "love";
    11:    	println("Now the word is ",y);
    12:    	//Uncomment the next line to see that you can't mess with const's
    13:    	//answer = "love";
    14:    
    15:    	// const's can't be declared inside a function:  uncomment the next line to see another error
    16:    	// const decl v = 12;
    17:    }
    
    In the code y is an ordinary variable. (Note that it is declared outside of main(), something we will discuss later.) However, answer is set to 42 and it cannot be changed later in the code. Run the example and then uncomment the lines to see what happens.

    Note that enum{} creates an kind of constant, but only integer values. On the other hand, const decl can create any kind of Ox value, such as a matrix, a list or a string.

  15. Statements
  16. In Ox, a statement does something. A statement is like a complete sentence in English, except that statements in Ox end with a semicolon ;. The reason might be obvious: periods also show up in real numbers (like 33.2) so using it to also end a statement can be confusing. So println("hello, world") is not a complete statement, but println("hello, world"); is. The semicolon tells Ox it should have received all the information about what to do for this step in the program. Anything after ; would either be the next statement or some other aspects of the program. So when it comes time to run the program this statement will be executed before going past the semicolon.
    Semicolons are EssentialOne of the most common syntax mistakes students make is forgetting that semicolons are essential in Ox. Some languages like Python use the end of a line to indicate the end of a statement. In Ox, if you forget ";" you will confuse it, and the syntax error message you get won't be "you forget ;, dummy!" Getting used to this takes time, but when you see an error, often check and make sure there are semicolons at the ends of statements above the error.

    What makes computers and programming languages powerful is the capacity to build complex statements out of simpler ones. The most fundamental of these structures is a statement that will run a statement only if some condition holds. This is the if () then structure in Ox. These are discussed later.

  17. Preprocessing Directives
  18. The last element of an Ox program introduced now is ironically often at the top of the program. It happens before anything else (hence the term preprocessing). The symbol # in Ox signals a preprocessing directive. These are like statements except Ox statements do stuff when the program is running. Preprocessing directives happen as your Ox program is being read and understood but not yet executed. We have already seen an example of this hello-world:
    #include "oxstd.h"
    
    This directive tells Ox to:
    1. Find the file named oxstd.h. If it can't be found everything stops and the program never runs.
    2. Insert the contents of the file as if the programmer had typed them.
    3. NOTE: If Ox cannot find a .h file then it will also look for the oxstd.oxh file. This is a special feature related to header files.
    All the #directives are handled first, and then the program is read again. So on the second pass #include ... has been replaced by the contents of the included file.

    The only other preprocessing directive seen in simple Ox programs is #import. This is like #include but does more and its use is best discussed later. It is key for writing complex Ox programs that are reliable and easy to read.

Summary

Exercises