`PI`

and a radius variable
`r`

helped, since we don't have to continually write out
the value of Pi.
However, we still had to keep writing the formula over and over.
For example, we have to say `r * r`

every time we want to
square the radius, and then we have to remember to multiply by Pi.

Let's first address the problem of squaring a number. Instead of
having to write the expression `r * r`

every time, it would
be nice to have a **black box**, or a procedure, that would take in
a numerical argument and return the square of that argument.

If we had this, we could write

square(837)instead of

`837 * 837`

.
This may not save us much typing
but one can argue that the code is more readable, and certainly if
we were taking cubes or higher powers, it would become ridiculous to
start stringing the numbers all out in a line.
In Java, we can create a procedure called `square`

as follows:

double square(double x) { return (x * x); }

The "double" at the beginning is the type of return value from the
procedure. This is followed by the name of the procedure, and then a
list of **formal parameters** separated by commas. In this case,
there is only one formal parameter, called `x`

and its type
is `double`

.

When the procedure is **invoked**,
the actual values passed in from the procedure call are bound
to the formal parameters. The part in curly braces ({}) is the
**procedure body**. The procedure body contains some number of statements
that are executed in order. When one of the formal parameters is used
inside the body, it's value is the value that was passed in from the
calling procedure. The expression in the return statement is
evaluated at the end of the execution of the procedure and the
resulting value is returned to the calling procedure as the value of
the procedure call.

Now let's invoke the procedure. Suppose we execute the line

double area3 = square(3);The value 3 is called the

So, the actual parameter 3 is passed into the procedure `square`

and bound to the variable x. Then the body of the procedure is executed.
The return value 9 is computed, returned as the value of
the expression "square(3)", and subsequently assigned to the
variable `area3`

.

Any expressions can be used in the actual parameter list when making a procedure call, provided that the types match the types of the corresponding formal parameter list. For example,

double x, y; double r = 3; x = square(2+1); // 2 + 1 is evaluated, 3 is passed in y = square(r); // r is evaluated, 3 is passed in i = square("3"); // ERROR: type String doesn't match double parameter

`areaOfCircle`

that compute the
area of a circle, given the radius. Then we could write statements
like
double area5 = areaOfCircle(5);

So, how do we write the procedure? Assuming that we have already defined the constant PI, we can write:

double areaOfCircle(double radius) { return (PI * square(radius)); }

Notice that we are using the square procedure to compute the square of the radius.

Let's do some more examples of procedures.

`sqrt`

that takes one
parameter (a double) and returns its square root:

We don't know what `sqrt`

is doing inside, but we can use
it anyway because we understand its specification. This is a nice
advantage of procedural abstraction.

Suppose we want a procedure **hyp** that finds the length of the
hypotenuse of a right triangle, given the lengths of the other two
sides.

Recalling that the length of the hypotenuse is the squre root of the sum of the squares of the lengths of the sides, we can write:

double hypotenuse(double sideA, double sideB) { return sqrt(square(sideA) + square(sideB)); }

And we can call the procedure as follows:

double hyp = hypotenuse(3,4);

Let's think about the evaluation step by step, using the substitution model:

hypotenuse(3,4) sqrt(square(3) + square(4)) sqrt((3 * 3) + (4 * 4)) sqrt(9 + 16) sqrt(25) 5

`Math`

. (A
method is a procedure defined as part of a class.)
We'll say more about classes later, but for now you can think of
the math class as a collection of procedures (methods) and constants,
accessed by `Math.`

*name-of-method* or
`Math.`

*name-of-constant*. Examples include:

Math.sqrt(double x) // returns the square root of x Math.pow(x,y) // returns x raised to the power y Math.PI // an approximation of piSee the Math class documentation for a complete list of the available methods and constants.

Another useful class is the `System`

class that provides
an output stream for printing textual output
from your program to the screen,
as in the following example.

public class Triangles { public static void main(String args[]) { test(3,4); test(9,12); } public static double square(double x) { return (x * x); } public static double hypotenuse(double sideA, double sideB) { return Math.sqrt(square(sideA) + square(sideB)); } public static void test(double a, double b) { System.out.print("A right triangle with sides " + a + " and " + b); System.out.println(" has hypotenuse " + hypotenuse(a,b)); } }Some notes:

- The first line says that we are defining a class called Triangles that is publicly available (accessible externally).
- The second line sets up a
method called
`main`

that will be the entry point of the program. - The modifier
**static**means that the method is part of the class, as opposed to a method of an object instance of the class. We'll see more about this later, but for now, just think of a class as a type of object. We may create many objects of a given class and call methods on those objects to ask the objects to do things. However, sometimes we want the class itself to be able to do things. These are called**static**methods.) - The modifier
**void**means that the method does not return a result. - The
`System.out.print`

method prints its argument to the screen. The`System.out.println`

method is the same, except that it also goes to the next line after printing.

So, the output of the program would be:

A right triangle with sides 3 and 4 has hypotenuse 5. A right triangle with sides 9 and 12 has hypotenuse 15.

- Hides details.
- Allows us to think about the general framework & postpone details for later.
- Gives us building blocks we can reuse in other situations.
- Lets us use local names.
- Lets us easily replace implementations by better ones.

double rect_diag(double s) { return Math.sqrt(square(a) + square(b)); }However, we can save ourselves some work by using what we've already done. We can

This would be coded as

double rect_diag(double a, double b) { return hypotenuse(a, b); }We've transformed one problem to another. This is called a

`Math.abs`

wasn't built in. Thus, we want a black box
like this:

The mathematical definition of this function is

double abs(double x) { return ???Wait! How can we do something different depending on the value of x? So far, all of our computations have been

What we want is for the execution to be **conditional** on
some **test**. For the **test**, we can use any boolean
expression (also known as a **predicate**). But how do we
make the execution **conditional** on whether the test is true
or false?

For this purpose, Java provides ** conditional statements**.
One possible form is

Here, theifcondition // NO SEMICOLON!! consequent;

Here, if theifcondition consequent1;elseconsequent2;

Using this construct, the `abs`

example could be written as

double abs(double x) { if (x > 0) return x; else if (x == 0) return 0; else return -x; }We can shorten this a bit, but it's important to check that all possible cases are covered!

double abs(double x) { if (x >= 0) return x; else return -x; }Notice that execution continues after the conditional statement, so we could also have written

double abs(double x) { if (x >= 0) return x; return -x; }Note: indentation has no meaning in Java. It is only used for readability.

boolean inside(int x1, int y1, int x2, int y2, int px, int py) { return ((px >= x1) && (px <= x2) && (py >= y1) && (py <= y2)); }Now we can use this procedure as a test in a conditional statement. For example,

if inside(3, 3, 10, 12, 5, 7) // rectangle: 3,3,10,12; point: 5,7 System.out.println("The point is inside the rectangle."); else System.out.println("The point is outside the rectangle.");We can also use the results of procedures

if (hypotenuse(3, 4) != 5) System.out.println("Error in hypotenuse test.");

- When the consequent has more than one statement, you must use
curly braces. When there is only one statement in the consequent,
you may omit the curly braces, but some editors expect the braces anyway
in order to do automatic indentation of your code.
if ... { ---; ---; } else { ---; ---; }

- Always use indentation within the conditional to make the blocks of code more readable and to make it easier to follow control flow.
- Try to use simple expressions in your tests. Ideally, the code
should make sense when read as an English sentence.
- Good:
`if (y > Math.sqrt(z)) ...;`

- Bad:
`if !(y < Math.sqrt(z)) ...;`

- Good:
- Avoid using a conditional just to return the value of a test.
That is, instead of
if (exp) return true; else return false;

writereturn exp;