Lesson 7 stressed the importance of abstraction in programming and problem solving in general. By defining functions, the programmer is able to add new abstractions to the language. Once defined, a function can be used repeatedly without having to worry about the details of its computation. In addition, functions minimize the complexity of code. As opposed to duplicating the code each time a particular computation is required, that code can be written once, encapsulated inside a function, and then executed repeatedly via function calls.
This lesson describes the next logical step in building abstractions, the definition and use of libraries. Useful functions can be defined and stored in files, which can then be automatically loaded into the JavaScript interpreter and called when needed. Through such libraries of code, commonly used routines can be accessed easily, while the details of their implementations are hidden away.
So far, you have been defining functions directly in the JavaScript interpreter window. Once defined, a function can be called by any code that appears below it in the interpreter. While this model of execution is sufficient for simple functions whose use is limited, it is not ideal for functions that are meant to be used frequently. Consider, for example, the randomInt function you defined in Lesson 7. Throughout this course, you will be encountering many applications which involve generating random numbers. In these instances, you will want to be able to call the randomInt function to do this tricky computation for you. One way to do this would be to retype or cut-and-paste the definition of randomInt into the interpreter every time it is required. In addition to being tedious, this approach has the additional disadvantage of cluttering up the other code with unnecessary detail.
As an alternative to entering function definitions directly into the interpreter, the JavaScript environment for this course allows for saving code in a separate file, and then automatically loading that code into the interpreter. By placing useful function definitions in a file, it is possible to create a library of routines that can be easily accessed. Simply by specifying the name of the library file, all of the functions contained there are made accessible to the code in the interpreter. And since the actual definitions of the functions do not appear in the intepreter window, the programmer is spared the clutter and unnecessary detail of the function definitions.
Note: at this point in the course, you do not have the ability to define your own library files and include them into the JavaScript interpreter. This is possible, but it requires making a copy of the interpreter and executing it locally on your own machine (as opposed to over the Web). To keep things simple, the next few Lessons will only utilize libraries provided by the instructor. Later in the course, you will learn how to define and access your own library files.
As an example, a file named random.js has been provided for you on the class server. This file contains the definitions of several useful functions involving random number generation and selection. The headers for these functions are listed below.
To load a library file into the JavaScript interpreter, you simply enter the name of the file in the box labeled "Files (if any) to be included", which appears at the top of the intepreter window. When the "Execute Code" button is clicked, the contents of any file named in this box will automatically be loaded into the interpreter and will thus be accessible to any other code contained there.
All of the exercises in this lesson involve using the functions defined in the random.js library. Therefore, you should list the file name random.js in the library box, and then access these functions in your code as needed.
Exercise 2:
In Lab 2, you wrote a piece of JavaScript code for testing whether the user has ESP. Your code generated a random integer between 1 and 3 (inclusive) and prompted the user to try and guess that number. A message was then displayed telling them whether their guess was correct. Rewrite this code using the randomInt function to generate the random integer.
Once a function has been defined, it can be used just as if it were a part of the JavaScript language. In particular, you can call one function inside the definition of another function. Building functions out of other functions is a powerful technique for tackling complex problems. Since the details of each function can be ignored once it is defined, each level of abstraction builds upon the previous one.
Functions defined in library files are no different from functions defined directly in the interpreter. In fact, you can think of the code from libraries as being automatically inserted at the top of the interpreter window each time the "Execute Code" button is clicked. Even though you cannot see the actual definition when it is loaded, your code can access the functions from a library and build upon them.
As an example, consider the diceRoll function that you wrote in Lesson 7.
Once you have cut-and-pasted this function definition into the interpreter, you can call it anytime you want to generate a random sequence of letters. As an example of where this might prove useful, consider the opening lines of Lewis Carroll's poem Jabberwocky.
Devise a JavaScript write statement which prints these lines of the poem, but with random letter sequences substituted for some of the nonsense words. Each time you want to substitute a random sequence, call the randomSeq function to generate the sequence for you. Show your code, and report the version of the poem that it produces. Does your version read as well as Carroll's?
Exercise 6:
A slot machine is a rather simple gambling/entertainment device. It is a box with three (or more) wheels that spin independently when the player pulls a lever. The wheels have symbols printed on them (say a cherry, an orange, and a bar), and if they all stop spinning with identical symbols lined up, then the player wins. For example, three cherries is a winner, while two cherries and an orange is not.
Define a JavaScript function called slots which simulates the execution of a slot machine. Your function should have no parameters (since it is completely random), and should return a string representing the results of the three spins. For example, the call slots() might return the string "cherry bar cherry" or "orange orange cherry".
Hint: Each wheel can be simulated using the randomItem function to select a word from the list ["cherry", "orange", "bar"]. The value returned by the slots function can be obtained by concatenating three such random words together (with spaces in between).
Call your slots functions repeatedly and count how many times it takes to generate a winner. Is it close to 9?
Now call the slots function 36 times and keep track of how many winners you generate. Is it close to 4?