public class FunctionalAbstraction { /* * The following main routine contains three code blocks, each of which is * very similar to the others, varying only in the runtime values that will * be used to compute the value y = a * x + b. Your task is to "factor out" * the common code by declaring and implementing a single Java function. * Each block of code should then be replaced by a single "call" to that * function. The function should read in the values of x, a and b from * StdIn, compute the value y = a*x+b, and then print the result on StdOut. * You should then modify the code in the main routine, replacing each block * of code with a single line of code that calls evalLinerEq. */ /* * 1. Declare and implement your function here. Call it evalLinearEq. */ /* * 2. Replace each block of code with a single call to your new function. * Plan to discuss two issues: (a) functional abstraction -- how defining a * procedure allows you hide the details of a function implementation and * subsequently to refer to it using a simple name; and (b) reuse -- how * defining a procedure in one place enables you to reuse the same code from * several different points in your program. Which program is easier to * understand? */ public static void main(String[] args) { double y, a, x, b; // read in x, a and b // compute y = a * x + b // then print the result x = StdIn.readDouble(); a = StdIn.readDouble(); b = StdIn.readDouble(); y = a * x + b; StdOut.println(y); // read in x, a and b // compute y = a * x + b // then print the result x = StdIn.readDouble(); a = StdIn.readDouble(); b = StdIn.readDouble(); y = a * x + b; StdOut.println(y); // read in x, a and b // compute y = a * x + b // then print the result x = StdIn.readDouble(); a = StdIn.readDouble(); b = StdIn.readDouble(); y = a * x + b; StdOut.println(y); } } /* * 3. Learn to use the Eclipse function for cleaning up your code. It's * incredibly useful if you've gotten your formatting messed up. Among other * things, it will indent your code properly to reflect the nesting of braces. * The function is available using the menu item Source>Format, or by use of the * shortcut Ctrl+Shift+F (on a PC). Format your code now. From now on, you are * required to turn in code that's properly formatted. With tools such as Eclipse * there can be no excuses for messy source code! */ /* * 4. Learn more about debugging. Set a breakpoint on the first line of code * that calls your new function. Run the debugger. You should end up with the * selected line highlighted in green. Now look carefully at the Debug pane in * the Debugger perspective. What it shows you are the currently executing * "debugger threads." There should be only one at this point. It's important * that you learn how to terminate any undesired threads. Select the current * thread by clicking on its name (FunctionalAbstraction[Java Application]), * then hit either right click and select terminate, or just click on the * red square icon on the debug pane to terminate the debug session (thread). * Next, in the same way, select the "Remove All Terminated" function: with * the double black X icon. You have now cleaned up the state of the debugger * (and in particular you are no longer debugging your program). If you ever * have problems in the future getting the debugger to work, use this method * to get things cleaned up, then start over. * * Now start the debugger again. You should once again end up with an active * debugging thread (indicated in the Debug pane) with control stoppped at the * first breakpoint (indicated by green highlighting in the code window). In the * Debug pane, notice the line with the icon that looks like three blue lines. * This icon represents a "stack frame," which is to say a proceure that is * actively executing. At this point in your program execution, control is in * the "main" routine, so you only have one such "stack frame". Now use the Step * Into function of the debugger to "step into" the call to your new routine. * Look at the debug pane. What changed? You should now see two stack frame * icons. The one on top represents the most recently called, still active * function. Select one of these stack frames then the other. What Eclipse is * showing you is the "nesting" of control: in particular, your "main" routine * has called your evalLinearEq routine. The call to evalLinearEq is "nested" * inside the execution of main. Note also that as you select one stack frame * or another. Now Step Over the statements within your function body. Watch * the Debug pane carefully to see what happens when your function returns. * What happened to its stack frame? Why? Now continue stepping over the * remaining lines of code in your main routine to finish out its run. When * your program completes, what changes about the current thread in the Debug * pane? */ /* * 5. Next we want you to change your evalLinearEq function so that (a) instead of * taking input from StdIn it gets the values of x, a and b as parameters, and (b) * instead of printing out the result, it returns the result to the routine that * called it. Go ahead now and make this change. First, change the function, then * update the main routine. Your main routine should now have just three pairs of * lines, each of which looks something like this (excep the parameter values should * be different on each call to your function--just make up some numbers here): * * y = evalLinearEq(4.1, 2.5, -3.0); // compute y = a*x+b * StdOut.println(y); // print the result * * Once again run the debuuger. This time Step Into EACH call to your function, and * notice how the Variables pane shows you the values of the parameters passed into * the function. Notice how these values differ between calls. It's in this way that * a single function can be made to perform an essentially infinite number of variants * of a given computation. The code captures the common aspects of the behavior, while * the parameters vary from invocation to invocation (from call to call). */