Introduction to Quilt [1] This window is a Quilt worksheet. Here you can write Quilt programs, execute them and get their results. You can save what is written here as a text file using the 'File/Save' or 'File/Save As' menu items or the 'Save' button of this window. You can create other worksheets using the 'File/New' menu item or the 'New' button of the main Quilt window, the smaller one at the top. The text you are reading is not really a part of a Quilt program. This is written for the use of the human reader, not for the computer. Normally this kind of thing should be written as a 'comment' as the following: // This is a comment. A comment starts with the characters // // and ends at the end of line. It is ignored by the compiler. // From now on I will write my notes as comments. // We have an 'incremental' environment. You can do calculations // and see their results immediately. The basic unit of calculation // is a 'statement'. Simple statements end with a semicolon: ; // The following is a statement that adds two integers. To execute // it, click on the line containing the statement, then select the // 'Run/Execute' menu item, or click on the execute button on the // toolbar, or, easiest of all, press the 'enter' key on the // extreme right of the keyboard. (not the big one on the main part // of the keyboard!) 12 + 3; // Some more operations you can do with integers are: - (subtraction), // * (multiplication), / (division), and % remainder. 12 - 3; 12 * 3; 12 / 3; 12 % 3; // You want to save the result of a calculation by 'assigning' it to a // 'variable' so that it can be used in further calculations. // A variable name is any sequence of letters and digits that starts // with a letter. We assign a value to a name using the = (assignment) // operator. number = 12 + 3; // Now the variable 'number' has a value. Lets use it in some other // calculations. number * number; otherNumber = number - 29; // You can combine Quilt operations to make more complicated expressions // just like in mathematics. (In programming, though, in contrast to // mathematics, use of quite long variable names is encouraged). a = 2; b = 17; c = 5; disc = b*b - 4*a*c; solution = (-b + disc.sqrt())/(2*a); // (You can execute several statements at once by selecting them using // the mouse, and pressing the enter key) // Every operator has a precendence. The precedence of + and - is lower // than the precedence of * and /. Higher precedence operators are applied // before lower precedence operators. So, in the fourth line above, the // multiplications are done before the subtraction. Equal precedence // operators are generally done from left to right (there exceptions, though) // Hence, in the same expression 4*a is done before multiplication by c. // For multiplication this does not matter. (Also, b*b is done before all, // because it the leftmost operation, but this matters even less) // But in the fifth line we have to enclose 2*a in parentheses, so that // it is done before /, which is outside the parentheses. Otherwise, // division would be done before multiplication, which changes the result. // (try it: you can go delete the parentheses and execute it again) //////////////////////////////////////////////////////////////////////// // Relational operators and conditional statements //////////////////////////////////////////////////////////////////////// // Relational operators are these: == (equal), != (not equal), < (less than), // <= (less or equal), > (greater than), >= (greater equal) // These compare two values. The result is 'true' is the relation holds, // or 'false' otherwise a >= 2; b < 5; c != 5; a == 5; // Be careful not to confuse the following. They are TOTALLY diferent. a == 5; a = 5; // You can never use = to do comparisons, it is assignment. // Now we want to set the value of the variable 'absVal' to the absolute value // of the variable 'otherNumber'. We have two cases. One is when 'otherNumber' // is negative, other is when not. This is done using the 'if' statement if (otherNumber < 0) absVal = -otherNumber; else absVal = otherNumber; // The expression in the parentheses is the 'condition'. If it is true, then // the following statement gets executed. Otherwise, the statement following // the 'else' keyword is executed instead. If there is nothing to do when // the condition is false, you can omit the else part. Suppose we want to // set the variable 'solution' to the absolute value of itself. Then we may // write if (solution < 0) solution = -solution; // since there is nothing to do when 'solution' is nonnegative. // When you execute these if statements, you won't see any results. // This is because you can and will generally do more compicated // computations than assigning a simple value to a variable inside // if statements. To see the value of 'absVal', you can execute absVal; // or click the 'Browser' (magnifying glass) button in the main window, // which shows the values of all variabled which are assigned values. //////////////////////////////////////////////////////////////////////// // Loops //////////////////////////////////////////////////////////////////////// // Now we want to calculate the factorial of something, say the variable 'c'. // Although this simply involves multiplying all integers from 1 to c, // we can not do it by writing 1*2*3*4..., since we do not know the number // of factors. Even if we knew, we would not like do this kind of thing if // the value of c were, say, 1000000. A 'for' loop does this job. We need // two new variables, one to hold the result of computation, the other (k) // to hold the factors one by one during the computation: factC = 1; for (local k = 2; k <= c; k = k + 1) factC = factC * k; // A for statement has four parts: oth the three inside the parentheses, // the first (initializer) and third (increment) are simple statements, // and the second is a condition. And there is the following statement, // the 'body' of the for statement. // (factC = 1; is not a part of the for loop, it is a separate statement, // so that when the loop starts, 'factC' has the value 1. // Ignore the keyword 'local' for now. The initializer statement gets // executed first, and it sets the value of k to 2. // Then the following happens repeatedly: The condition is evaluated, // if it is false, the computation ends at this point. Otherwise, the // body is executed, THEN the increment is executed, and we return to // check the condition again, and so on until it becomes false. // This is somewhat bizarre, but this is how the computer does it. For // a programmer, the first line of the for loop summarizes what happens // to k during the computation: It starts with 2, it gets incremented // by one at each step, and it can not be larger than c, so it gets // all the values between 2 and c inclusively. The body says that // factC is multiplied with each of these values, and we have set it // to 1 to begin with, so we get the factorial of c. // To see the result, evaluate: factC; // The more basic type of loop is the 'while' loop. Is is sinpler than the // for loop; it has a condition and a body (which is a statement): x = 0; while (x*x <= factC) x = x + 1; // Its semantics is exactly what you understand when you read it aloud: // as long as the condition is true, execute the body repeatedly. When // the while loop ends, one thing we know is that the condition has // become false. (note that you can write while loops that never end!) // This is the key to understanding what a while statement does. // In the particular example above, when the loop end, we have that // x*x <= factC is false, that is to say, we have x*x > factC. // In the course of the loop, we increment the value of x one by one, // and it was zero to begin with. So the loop calculates the smallest // x whose square is greater than factC. // Every for loop can be written also using a while loop. Read the // description of the for loop again. It has a condition and a repeated // calculation. Only problem is that what is repeated in the for loop // consists of two statements, whereas the while loop allows a single // statement as its body. This is no problem, because we can always // make any number (zero, one, two, ...) of statements into a single // statement by enclosing them between curly brackets: { }. This // is called a compound statement. So the for loop example above // can also be written as factC = 1; k = 2; while (k <= c) { factC = factC * k; k = k + 1; } // Note that, it is perfectly possible that the body of a loop gets // never executed. By the definitions of while and for loop, this // happens when the loop condition is false the first time it is // evaluted. // When does this happen for the while loop above? // What is does the value of factC become if this happens? // Does it make sense? //////////////////////////////////////////////////////////////////////// // Functions //////////////////////////////////////////////////////////////////////// // Let us calculate the value of the binomial coefficient (9;5)=9!/(5!*4!) // We can do it using what we have seen so far: // calculate 9! factNine = 1; for (local k = 2; k <= 9; k = k + 1) factNine = factNine * k; // calculate 5! factFive = 1; for (local k = 2; k <= 5; k = k + 1) factFive = factFive * k; // calculate 4! factFour = 1; for (local k = 2; k <= 4; k = k + 1) factFour = factFour * k; // and finally the result result = factNine/factFive/factFour; // remember the operator precedence rules: you have to write this as // factNine/factFive/factFour or factNine/(factFive*factFour) // but factNine/factFive*factFour does something different. // Also note the comments inside the code explaining what it does. // This is the real use of comments. // We won't be able to go much far with this kind of code. We would // like to be able to write something like the following, much // like we would write in math: // (if you execute this, you will get an error. There is nothing // called "Factorial" yet) result = Factorial(9)/(Factorial(5)*Factorial(4)); // Here, Factorial will be a 'function' that takes one argument, and // produces a value that is related in some way to its argument, // presumably in a way that is suggested by its name. That is, we want // this function to calculate the factorial of its argument. It is our // job to write such functions. It is also our responsibility to write // them such that they will really calculate what they are supposed to. // This is called 'programming'. // Here is how to define a function Factorial = function (x) { local fact = 1; for (local k = 2; k <= x; k = k + 1) fact = fact * k; return fact; }; // Let's look at the anatomy of this expression. First of all, it is an // assignment, that is we create a function, and assign it as the // value of the variable 'Factorial', much like when we write x = 15; // A function has a number of 'formal parameters' written in parentheses // after the 'function' keyword. This has one, that we have called x. // It could have none, two, three or more. When we 'call' this function, // for instance, by writing Factorial(9), with an 'actual parameter' or // 'argument', which is 9 in this case, the variable x gets this value // when the function is 'entered'. One important point is that this // x has NO relation whatsoever to a variable named x elsewhere. // We have set the variable x to some value above. Its value will not // change. If it did, it would be a terrible mess. // After the formal parameters, we have the 'body' of the function, which // is a statement, typically a compund statement consisting of several // statements. On every call of the function, these statements are // executed, with the formal parameters set to the values of actual // parameters. // The value of the function is determined by a 'return' statement. // Eventually a return statement is executed. At this point, the // function execution ends, whatever expression we have next to the // 'return' keyword becomes the value of the function call, (say, // the Factorial(9) in the larger expression above. // Now, the 'local' keyword. Preceding a variable by this keyword // at its first appearance means that, we want it to be a different // entity from any variable of the same name elsewhere, exactly like // the formal parameters. Since k is declared local in it, a call to // this function has no effect on the value of k defined outside it. // This normally what you want, it is very important to make these // local declarations to write programs that work. // Let us write some more functions // You can have more than one return statement in a function. // Whichever gets executed, determines its value. AbsoluteValue = function (u) { if (u < 0) return -u; else return u; }; // This is a function with three parameters, it has to be called // with three arguments SolveQuadratic = function (a, b, c) { local disc = b*b - 4*a*c; return (-b + disc.sqrt())/(2*a); }; // Now we call them SolveQuadratic(2, 17, 5); Factorial(9)/(Factorial(5)*Factorial(4)); // Even better, we can write a function for binomial coefficient BinomialCoefficient = function (m, n) { return Factorial(m) / (Factorial(n) * Factorial(m - n)); }; BinomialCoefficient(9, 5); // That is all for the 'control structures'. Any program can be written // using if statements, while statements, and function definitions // along with the 'primitive' operations like addition and assignment // We will see more about these primitives in QuiltTutorial2. // A note on names. We can use any name for the variables and functions // we create, with the exception of the language keywords like // if, else, for, while, return, function, local and and a few more. // You can recognize keywords, easily as they are displayed in blue // in the editor. // Nevertheless, there are 'naming conventions' to be used when writing // programs. I have been using one in the code in this file. // The name of anything is composed of as many words as needed to // describe it. The first letter of each word is capitalized. // The first letters of function names are capitalized, but the first // letter of anything else is in lowercase. Single letter variables are // used only for absolutely trivial variables. Abbreviations may be used, // but they should be easily understandable in the context they are used. // So, the names 'fact' and 'disc' in the functions Factorial and // SolveQuadratic are OK, and we could also write AbsVal or BinomialCoeff, // but anything shorter is no good. // You should also follow these rules to make your life easier. Introduction to Quilt [2] // Every programming language has some primitive data objects, and // primitive operations. We combine primitive operations into programs // that perform complex calculations by using 'control structures'. // We have seen these. We also combine primitive data objects into // more complex 'data structures' to model objects from the 'real world'. // Now we will first look at the primitive objects, and the primitive // operations we can apply to them. Later we will see how to create // and work with more complex data. // Most important primitive objects are numbers. These come in two kinds, // integers and reals. // We have used a lot of integers previousy, they are written normally, // as sequences of digits. You can also write integers in hexadecimal // (base 16) like 0x5AF (0x means it is hexadecimal, we use A,B,C,D,E,F // for digits 10,11,12,13,14,15 respectively). 1455 == 0x5AF; // real numbers have a decimal point or an exponent or both. This is again // the usual notation, with the understanding that for example, 3.5e12 // means 3.5 times 10 to the power 12 // computer integers and reals have curious properties. For example while // You can write x = 3.5e12; x = 3500000000000.0; // the following does not have much meaning n = 3500000000000; // since there is no such 'computer integer'. Also check the following 1000000*1000000; // integers 1000000.*1000000.; // reals // We also have the boolean constants 'true' and 'false', and the special // object 'nil' as important primitive objects. nil means "nothing" // Now we give a table of some primitive operations. This is a partial // list, there are more. // operator use definition // ++ x++ increase by one // -- x-- decrease by one // - -x unary minus, negative // * x * y multiplication // / x / y division // % x % y integer remainder // + x + y addition // - x - y subtraction // == x == y is equal to // != x != y is not equal to // < x < y less than // <= x <= y less than or equal to // > x > y greater than // >= x >= y greater than or equal to // && x && y logical and // || x || y logical or // = x = y assign // += x += y add y to x // -= x -= y subtract y from x // *= x *= y multiply x by y // /= x /= y divide x into y // %= x %= y remainder x by y // this table is grouped by precedence. The operations above are // done before the operations below in the table, when they occur // together in unparenthesized expressions. Operators that are // grouped together have the same precedence // We have seen the relational operators. All can be used to compare // numerical values. == and != can be used to compare any object // to any other object to find out whether they are equal or not. 12 == 1.2e1; 12 == true; 0 == false; 5 != nil; // The logical operators && and || operator on boolean values. They // are the familiar 'and' and 'or' operators on truth values. Using // them we can write things like if (x >= 0 && x <= 5) y = x*(5 - x); else y = 0; // or even xIsOutOfRange = x < 0 || x > 5; // Arithmetic operations are familiar, but they have some novel properties. // Most important of these is that division behaves differently for // integers and real numbers. The quotient of two integers is always an // integer! 22.0 / 7.0; 22.0 / 7; 22 / 7; // Assigment is listed in the above table. You know that it is something // different than the other operators. It *changes* the value of its // left hand side. So it has to be something whose value can be changed, // namely a variable. // The operators in the same group with = are really abbreviations. // You may have noted that about half of the statements we have written in // this tutorial so far were the likes of k = k + 1; and fact = fact * k; // You may write k += 1; and fact *= k; instead of them. They do exactly // the same thing and can be read as "add 1 to k" and "multiply fact by k" // which is more natural. // similarly x -= y; means x = x - y; x /= y; means x = x / y; // and x %= y; means x = x % y; // Finally, we have so many x = x + 1; and x = x - 1; statements // in programming that we can further abbreviate x += 1; as x++; // and x -= 1; as x--; // Of course, one of the most popular places for these expressions // is the for loop. Factorial = function (x) { local fact = 1; for (local k = 2; k <= x; k++) fact *= k; return fact; }; //////////////////////////////////////////////////////////////////////// // Math functions //////////////////////////////////////////////////////////////////////// // Remember how we calculated the square root in the first part: // disc.sqrt() // This notation is called a 'method call' and used for evaluating // several familiar functions, and for other things we will see. // You have to write parentheses, since a method call may have parameters. // Here is a list of available methods for numerical values: x = 3.5; y = 2.5; z = 0.75; x.exp(); // the exponential function e to the power x x.ln(); // natural logarithm of x x.log(3); // logarithm of x for a particular base x.log10(); // base 10 logarithm of x x.sqrt(); // square root of x x.pow(y); // x to the power y x.pow(0.5); // another way of calculating the square root of x x.cos(); // cosine of x. x is in radians for all trigonometric functions x.sin(); // sine of x x.tan(); // tangent of x z.acos(); // inverse cosine of z z.asin(); // inverse sine of z x.atan(); // inverse tangent of x x.atan2(y); // inverse tangent of x/y, but y == 0 is allowed x.cosh(); // hyperbolic cosine of x x.sinh(); // hyperbolic sine of x x.tanh(); // hyperbolic tangent of x x.abs(); // absolute value of x x.floor(); // largest integer less than or equal to x x.ceil(); // smallest integer greater than or equal to x x.trunc(); // integer part of x x.fract(); // fractional part of x x.sign(); // sign of x