# The Science of Programming/Guzzintas and other Cipherin'

Although we now have a nifty way to represent constants, we are now left with a bigger problem: how to combine terms and constants. We can't use Sway's `+` operator, since it only works for numbers and strings.^{[1]} Instead, we will create an object to hold the two items to be added.^{[2]} Let's create a constructor named *plus* to remind us that it generates an object that holds the (potential) sum of two objects:

function plus(p,q) //p and q are terms/constants { this; }

We can't do much with *plus* objects, however, except extract the original items, bound to *p* and *q*.

How should we enhance our plus constructor? Just like terms and constants, a plus object should be able to:

* compute its value * compute its derivative * visualize itself

Of course, the *plus* object doesn't know how to do any of these things, since it's just a container for holding two items. What it *can* do, however, is ask those items to perform computations and then combine the results in a meaningful way. ^{[3]}

Now our questions become:

- how should the values of the items be combined?
- How should the differentials of the items be combined?
- How should the visualizations of the items be combined?

For the *value* method, how should the value of *p* and the value of *q* be combined? Since the value of *p* is a number and the value of *q* is a number and since the *plus* object represents the additions of its items, we can simply add the item values together:

function plus(p,q) //p and q are terms/constants { function value(x) { p . value(x) + q . value(x); } this; }

Thus, to compute the *y* value of a two terms added together, we simply find the *y* values of the terms separately, then add the results together. Mathematically,

Let's test:

sway> var a = term(-5,2); sway> var b = term(7,0); sway> a . value(3) + b . value(3); INTEGER: -38 sway> var z = plus(a,b); sway> z . value(3); INTEGER: -38

Note that our *plus* constructor doesn't actually specify what kinds of objects the formal parameters *p* and *q* must be bound to; the only requirement is that those objects have a *value* method that takes a single argument. We will take advantage of this fact later and use *plus* objects to glue together *terms*, *constants*, and other *plus* objects, nilly willy.

## The Power Rule and Sums[edit]

We now turn our attention to the second method *plus* objects need to implement, the *diff* method. Of course, the power rule won't work for sums, because the rule only works only for computing the derivative of a single term.

It turns out the derivative of two things added together is the sum of the derivatives of each thing alone. Mathematically,

Now here's the tricky part (well it will seem tricky now, but in a short time, you will think this is as easy as pie). We use a *plus* object to represent the addition of two terms, correct? The right-hand-side of the equation above involves an addition. What are being added? Two derivatives. If *a* and *b* are term objects, then what kinds of things are the derivatives of *a* and *b*. Both are terms! Thus the right-hand-side in this case is simply the sum of two terms. But what do we use to represent the sum of two terms......wait for it......a *plus* object.

Wow! Then the derivative of a *plus* object, consisting of two terms, is another *plus* object containing the derivatives of those two terms. This is both amazingly powerful and amazingly simple at the same time.

If the above explanation has confused you, perhaps looking at the code will help. Here is the revised *powerRule*:

function powerRule(obj) { if (obj is :term) { var a = obj . a; var n = obj . n; term(a * n,n - 1); } else if (obj is :plus) { var dp/dx = powerRule(obj . p); var dq/dx = powerRule(obj . q); plus(dp/dx,dq/dx); } else { throw(:calculusError,"powerRule: unknown object"); } }

Note that *dp/dx* is a variable name and is something entirely different from *dp* / *dx*, which is the variable *dp* divided by *dx*. For *plus* objects, we extract the two terms, *p* and *q*, take their derivatives using the power rule, and then combine them into a *plus* object.

## More than two terms[edit]

Our *plus* constructor is fine for representing lines as a line is composed of two terms, one of them being a constant. What do we do for a sum of three or more terms?

How about doing...nothing.

Yes, nothing. It turns out that our design of *plus* is so fine it not only handles the sum of two terms but the sum of a *plus* object and a term.^{[4]}. Recall that the only requirement for the parameters *p* and *q* in a *plus* object are that they both be bound to objects that have a *value* method. Does a *plus* object have a *value* method? Yes, indeed! So that means *p* or *q* or both can be bound to *plus* objects. Let's see:

var a = term(-5,0); var b = plus(term(3,1),a); var y = plus(term(4,2),b);

The variable *y* now refers to the polynomial:

or more simply:

Now, just because we should (and can) be able to combine sums and terms nilly-willy with our *plus* constructor doesn't mean we can assume *plus* is completely correct as written. We need to test^{[5]} in order to convince ourselves thoroughly that the code works. Let's test *a*, *b*, and *c* at some value of *x* that is easy to verify, say x = 2:

sway> a . value(2); INTEGER: -5 sway> b . value(2); INTEGER: 1 sway> y . value(2); INTEGER: 17

In this interaction, we see that *a*, which is , has a value of -5 when *x* has a value of 2. The object *b*, which is a *plus* object representing , has a value of 6 - 5 or 1. The object *y*, which is also a *plus* object and represents , has a value of 16 + 6 - 5 or 17.

It is not surprising that the object *a*, which is just a term, and the object *b*, which is composed of two terms, both give the correct answer; we are using their constructors exactly in the manner they were intended. Less obvious is why *y* works, being composed of a term and a *plus* object. The next section will demonstrate *visualization* to help you understand 'why'.

## Visualizations[edit]

A very good way to see why *y* works is to *visualize* the *y* object. We begin by modifying the term constructor to add a *toString* method. In general, a *toString* method is used to generate a string representing the current state of the object.^{[6]} Such a string is called a *visualization*.

Before continuing, read up on strings.

Here is the modified *term* function with its new *toString* method:

function term(a,n) { function value(x) { a * (x ^ n); } function toString() { "" + a + "x^" + n; } this; }

As always, we write a bit of code, and then test, test, test!

sway> var t = term(3,2); sway> t . toString(); STRING: "3x^2"

Given any term, we can quickly see the parts of our object in a way that is very easy to understand. ^{[7]} This is the goal of visualization.

We will also need to add a visualization to *plus*:

function plus(p,q) //p and q are terms or plus objects { function value(x) { p . value(x) + q . value(x); } function toString() { p . toString() + " + " + q . toString(); } this; }

Note that *plus* visualizes itself by using the visualizations of its component objects and adds a '+' sign to indicate addition.

Now we remake *a*, *b*, and *y* with these new definitions of *term* and *plus* in force:

var a = term(-5,0); var b = plus(term(3,1),a); var y = plus(term(4,2),b);

Let's see what *y* looks like:

sway> y . toString(); STRING: 4x^2 + 3x^1 + -5x^0

Looks exactly as intended.

To see further why the visualization works, it is sometimes useful to look at the sequence of calls generating the result. These calls are organized into what is known as a 'call tree'. Actions within a call are indented one-level from the originating call. Leftward pointing arrows represent return values.

Here is to call tree for *y'*s *toString* method call:

call y . toString() //object y is plus(term(4,2),b) call p . toString() //object p is term(4,2) <-- "4x^2" //return value " + " call q . toString() //object q is b, plus(term(3,1),a) call p . toString() //object p is term(3,1) <-- "3x^1" //return value " + " call q . toString() //object q is a, term(-5,0) <-- "-5x^0" //return value <-- 3x^1 + -5x^0 //return value <-- 4x^2 + 3x^1 + -5x^0 //return value

Combining the strings from top to bottom at the first indentation level gives us the overall return value:

4x^2 + 3x^1 + -5x^0

We can construct a call tree determining the value of *y* when *x* = 2, as well:

call y . value(2) call p . value(2) // p is 4x^2 <-- 16 + call q . value(2) // q is 3x^1 + -5x^0 call p . value(2) // p is 3x^1 <-- 6 + call q . value(2) // q is -5x^0 <-- -5 <-- 1 <-- 17

Summing the return values at the first indentation level yields 17, the overall return value.

Visualization is an important technique. You should always include a visualization method for all your objects so that you can easily debug your program when things go awry. In such cases, your visualization will likely point out that an object does not appear as you expect it to, an important first step in solving your problem.

## Power Rule Modifications[edit]

We have tested our *powerRule* function on sums of terms, but will it work for sums of sums? Let's examine the code:

function powerRule(obj) { if (obj is :term) { var a = obj . a; var n = obj . n; term(a * n,n - 1); } else if (obj is :plus) { var dp/dx = powerRule(obj . p); var dq/dx = powerRule(obj . q); plus(dp/dx,dq/dx); } else { throw(:calculusError,"powerRule: unknown object"); } }

If the formal parameter *obj* is bound to a sum of *plus* objects, the *powerRule* function is called recursively on the two objects making up the sum. As long as either of those two objects is a *plus* or *term* object, it appears if *powerRule* can handle it. In the case of a *plus* object, *powerRule* calls itself recursively again.

Let's test the *powerRule* function on the polynomial bound to the variable *y* above. Recall *y* visualized as:

4x^2 + 3x^1 + -5x^0

We would expect the *powerRule* function to produce a polynomial that visualizes to something like:

8x + 3

Let's see.

var dy/dx = powerRule(y); sway> dy/dx . toString(); STRING: 8x^1 + 3x^0 + 0x^-1

Looking at the last term of the result, we note that zero times anything is zero, so the result is equivalent to:

8x^1 + 3x^0 + 0

or

8x^1 + 3x^0

Noting, as before, that is equal to 1, the result becomes:

8x^1 + 3*1

or

8x^1 + 3

Finally, realizing that is simply *x*, the result becomes:

8x + 3

as desired. Some of the questions at the end of this chapter explore how to have the *plus* and *term* perform some of these simplifications automatically.

## Other mathematical combinations of terms[edit]

What if we wish to subtract two terms, as in:

y = 3x^2 - 4x

We can write a function named *minus* to do this:

function minus(p,q) { function value(x) { p . value(x) - q . value(x); } function toString() { p . toString() + " - " + q . toString(); } this; }

This is just like *plus*, except that minus signs are used instead of plus signs in methods *value* and *toString*.^{[8]}

What is the power rule for the subtraction of terms? It is similar, but not quite the same as the power rule for the addition of terms:

Thus *powerRule*, as written, cannot work for *minus* objects because there is no code in *powerRule* that subtracts or even produces a *minus* object. We will need to add a new clause to *powerRule*:

function powerRule(obj) { if (obj is :term) { var a = obj . a; var n = obj . n; term(a * n,n - 1); } else if (obj is :plus) { var dp/dx = powerRule(obj . p); var dq/dx = powerRule(obj . q); plus(dp/dx,dq/dx); } else if (obj is :minus) { var dp/dx = powerRule(obj . p); var dq/dx = powerRule(obj . q); minus(dp/dx,dq/dx); } else { throw(:calculusError,"powerRule: unknown object"); } }

While this will work, there is a clue that we are doing something wrong. Whenever you see a if-chain dealing with objects, it means you are not fully exploiting the power of objects and you should reorganize your code to remove the if-chain. The next section shows how.

## The Object Way[edit]

The design of a program usually evolves over time. Some programmers feel very invested in the code they have written and will doggedly hang on to it even when a better way of doing things becomes apparent. In the words of the immortal Kenny Rogers, "you got to know when to hold 'em, know when to fold 'em". In this case, our *powerRule* function is threatening to get out of hand, so we are going to fold and get a new deal.

Our new approach expands on the statement:

- An object should be able to ...

In the case of our *term* and *plus* objects, we have already implemented the following versions of the above statement:

- A term object should be able to return its coefficient
- A term object should be able to return its exponent
- A term object should be able to compute a
*y*value given an*x*value - A term object should be able to be able to visualize itself
- A plus object should be able to return its components
- A plus object should be able to compute a
*y*value given an*x*value - A plus object should be able to be able to visualize itself

To this list, we will add the following statements:

- A term object should be able to differentiate itself
- A plus object should be able to differentiate itself
- Other similar objects should be able to differentiate themselves

Let's first update our *term* constructor so that terms can differentiate themselves. We do this by adding a *diff* (for differentiation) method:

function term(a,n) { function value(x) { ... } function toString() { ... } function diff() { term(a * n,n - 1); } this; }

The body of the *diff* method is simply a form of the term code found in the *powerRule* function.

We can do the same for the *plus* constructor:

function plus(p,q) { function value(x) { ... } function toString() { ... } function diff() { var dp/dx = p . diff(); var dq/dx = q . diff(); plus(dp/dx,dq/dx); } this; }

To make *plus* a little shorter, we can replace the body of the diff method with a single line:

function diff() { plus(p . diff(),q . diff()); }

Using the fact that *plus* is a function of two arguments, we can use infix notation as well:

function diff() { p . diff() plus q . diff(); }

Modifying the *minus* constructor is similar. What about multiplying and dividing terms?

According to CME, the mathematical rule for differentiating a product is:

The rule for division is more complicated still:

The implementations of the *diff* methods for *times* and *div* constructors are left as an exercise.

After doing all this, the *powerRule* function becomes very simple:

function powerRule(obj) { obj . diff(); }

It is so simple, in fact, that it is longer doing any useful work and can be discarded.

## Questions[edit]

All formulas are written using Grammar School Precedence.

**1**. What happens if you pass a *plus* object to the original *powerRule* function? Explain what happens.

**2**. Define and test a *times* constructor. Be sure to add *toString* and *diff* methods.

**3**. Define and test a *div* constructor. Be sure to add *toString* and *diff* methods.

**4**. Modify the *toString* method of term to use only the coefficient if the exponent is zero.

**5**. Modify the *toString* method of term to ignore the coefficient and/or the exponent if it is 1. That is, term(3,1) should display as 3x, not 3x^1, and term(1,4) should display as x^4, not 1x^4.

**6**. Modify the *toString* method of term to produce the empty string `""`if the coefficient is zero.

**7**. Modify the *plus* constructor to throw away terms if they have a coefficient of zero. How do you 'throw away' a term?

**8**. Modify the *plus* constructor so that if the second argument is a term with a negative coefficient, it produces an appropriate *minus* object instead.

**9**. Use Sway for Problem 6 on page 64 of CME.

**10**. Use Sway to differentiate y = (x - 3/2) + (x^2 -5x) + (3x^3 + 7x^2 + 3x + 5) Define function *y* and

**11**. Work exercises 1-5 on p. 64 of CME using pencil and paper.

**12**. Use pencil and paper to solve exercise 11 on p. 77.

## Footnotes[edit]

- ↑ Later, we will learn how to
*override*the`+`operator so that it can add terms and constants as well. - ↑ Why we are doing this is not obvious. As we proceed, we will see that the approach works, but it won't give us much insight on how to come up with such solutions in the first place. We are essentially going to
*delay*the addition of the items until we really need to add them together (*e.g.*, when we are trying to compute a specific*y*value). The idea of delaying is a powerful computer science concept. Knowing when to delay, however, is more art than science. - ↑ There are two main kinds of relationships between objects. In this case, the relationship between the
*plus*object and*p*(or*q*) is*clientship*. The object*p*(or*q*) is said to be a client of the*plus*object since*p*(or*q*) is a component. The other main relationship between objects in*inheritance*in which objects share traits. You can read more about in The Sway Reference Manual. Although explicit inheritance is not used in this case, one can think of*terms*and*constants*inheriting the idea of the three methods:*value*,*diff*, and*toString*. - ↑ You will find these happy occurrences often if you write code that is simple and elegant.
- ↑ When you are a senior, rather than test some code to see if it appears correct, you might
*prove*it correct. The advantage of proving code correct is that performing all possible tests is sometimes difficult or impossible. - ↑ The use of the name
*toString*is just a convention. We are basing this convention on the Java Programming Language, which uses a*toString*method for this very purpose. - ↑ Be aware that this representation uses the operator precedence you learned in grammar school, namely that the exponentiation operation is performed before the multiplication by the coefficient. This is unlike Sway, which would evaluate the expression
`3 * x ^ 2`as`(3 * x) ^ 2`. To learn more about how Sway computes arithmetic expressions, see Precedence and Associativity in The Sway Reference Manual. - ↑ A fine example of
*programming by analogy*. Be aware, that making a new function by copying an existing function and making minor changes is usually a 'bad idea'. If you find yourself doing this, ask yourself how can the the two functions be combined into a single function? There is a nice way to do this for*plus*and*minus*, but we'll skip that as to not impede the narrative flow.