Pages

Friday, September 16, 2016

A Powerful Magic Box

Imagine a magician who can perform a trick using a magic box with a lid. The magician invites us to open the lid, put two things, thing1 and thing2, into the box, and shut the lid. After a moment of suspense, the magician opens the lid again and magically one thing, thing3, pops out of the box!

Imagine that our magician tells us that we should only put certain types of things into the box and that the thing that comes out of the box is always a certain type of thing. For example, maybe the magician tells us to put a ring and a twenty dollar bill into the box, and what comes out of the box is always a bird.

Now imagine that the type things that go into the box (thing1 and thing2) as well as the type of thing that comes out of the box (thing3) are all numbers and perhaps the value of thing3 is the value of thing1 raised to the power of the value of thing2.

By now we should know to call the names "thing1" and "thing2" the parameters of the box. And we should know that the actual values of thing1 and thing2 that we put into the box are called the argument values (or just arguments) for a given instance of the magic trick. Let's call the value that comes out of the box when the magician opens it the return value of the box.

What might our box look like if we had to describe it using Java or JavaScript?

Although we might not yet know the secret that explains how the box consumes thing1 and thing2 and produces thing3, we can at least start by describing the box in terms of its parameters and perhaps also its return value.

JavaScript is a loosely-typed language. This means we don't have to specify what type of things thing1 and thing2 are when we describe the box using JavaScript code. In fact, we don't even have to specify how many things we're going to put in the box, but it's very helpful to do so. We can start to describe the magician's box using JavaScript like this:
function box(thing1, thing2) {} // JavaScript
Note that thing3 (the return value) doesn't appear anywhere in the JavaScript code above. JavaScript functions may or may not explicitly return a value. In any event, JavaScript functions do not specify the type of their return value in the same way that they do not specify the types of their parameters. This is in contrast to strongly-typed languages like Java.
In contrast to JavaScript, Java is a strongly-typed language. This means that when describing our magician's box in term of its parameters, we must specify what types of things thing1 and thing2 are. We also have to indicate what type of thing thing3 (the return value) is, but we don't have to refer to thing3 by name. We can describe box in Java like this:
abstract double box(int thing1, int thing2); // Java
In Java we can use the keyword abstract to declare certain “external features” of a method like box without defining how the method actually works “on the inside”. In magicians' terms, an abstract method doesn't reveal the secret of how a trick is performed.

In the Java code above thing1 and thing2 are specific types of numbers called integers, and the value box returns is a type of number called a floating-point number. More specifically, thing1 and thing2 are both of type int (a 32-bit integer) and box returns a value of type double (a 64-bit floating-point number).

Code that invokes or calls a Java method like box must supply argument values that match the types of the declared parameters. The supplied arguments may either be of exactly the same types as the declared parameters or they may be of types that can be implicitly converted (or cast) to the types of the declared parameters. For general information about converting between types, see the Wikipedia article Type conversion.
If our magician's box simply consumed the values of thing1 and thing2—in other words, if the box were empty when the magician opened it—then we could use the keyword void to indicate the return type and describe the box like this in Java:
abstract void box(int thing1, int thing2); /* Java */
In contrast to the abstract Java method declarations above, the JavaScript function definition above is a complete description of a function that can be called once the line of JavaScript code above has been interpreted. The JavaScript function definition not only declares what box looks like on the outside, it also defines how box works on the inside. The JavaScript definition above simply defines a function that does nothing! If we wanted to define a JavaScript function called box that always returns the number 1 (one), we could do so like this:
function box(thing1, thing2) { return 1; } /* JavaScript */
An analogous definition of a method in Java looks like this:
double box(int thing1, int thing2) { return 1; } // Java
In Java, if there is only one version of box for a particular class of objects, then the Java code above can be modified using the keyword static as follows:
static double box(int thing1, int thing2) { return 1; } // Java
If code outside the scope of a particular object needs access to the method called box, then the Java code above may be further modified using the keyword public as follows:
public static double box(int thing1, int thing2) { return 1; }
Note the two styles of comments used in the examples above:
// this is a comment that extends to the end of a line
/* this is a comment that may span multiple lines */
PRACTICE: Modify one of the Java or JavaScript examples above so that box returns the value of either thing1 or thing2 and try to actually call box using Java or JavaScript. Can you figure out how to make box return the value of thing1 raised to the power of the value of thing2?

Don't touch that dial!