On this page:
2.18.1 Objectives
2.18.2 Exercises (due 2011/  11/  22 08:  45:  00)
2.18.3 Optional Exercises (due 2011/  11/  30 08:  45:  00)
2.18.4 Notes

2.18 Program Design with Mutation

Teenage Mutant Ninja Turtles:

Turtles in a While Loop

Set! power

2.18.1 Objectives

At the end of this class, you should know:

At the end of this class, you should be able:
  • write basic mutation-based programs, i.e. programs that use variables

  • perform store tracking analysis

  • use the while construct

  • use the fopen and getc functions

2.18.2 Exercises (due 2011/11/22 08:45:00)

1. Write the function theRemoveEntry, which takes a name and modifies the address book by removing the associated entries from the book. (Hint: Write without mutation first!)

2. Write isPrime, from last exercise, with a while loop.

3. Create a program called letterCount that reads a file and prints out how many characters are in it. Write in accumulator style. (Remember the example we did in class!)

4. Create a program called wordCount that reads a file and prints out how many words are in it. Write in accumulator style. Remember, words are separated by one or more spaces. You must correctly handle words separated by many spaces. (Hint: The character for a space is ’ ’.)

5. Convert letterCount to use mutation and a while loop.

6. Convert wordCount to use mutation and a while loop.

2.18.3 Optional Exercises (due 2011/11/30 08:45:00)

7. Write to10, from last exercise, with a while loop.

8. Create a program called lineCount that reads a file and prints out how many lines are in it. Write in accumulator style. (Hint: The character for newlines is ’\n’.)

9. Convert lineCount to use mutation and a while loop.

2.18.4 Notes

These notes are primarily for my sake, but I don’t see any reason to hide them from you.

Sometimes we can turn accumulator style into mutator style

 

write factorial with a while loop

-- CLEARLY dervie the mutation version from the functional version

-- n = n - 1 [do not use --!]

-- Make sure you have a nice comment that explains the syntax of while

 

change the address book functions to leave the phone-book argument implicit and have add return void. Instead, they will mutator a static variable.

 

Contrast the two programs: we can do substitution of factorial, but we cannot on the address book functions

 

factorial uses internal mutation, add uses external

 

This means factorial is an abstraction, but add is not

 

Mutation makes it so we can no longer analyze our programs in pieces, we have to take in everything at once.

-- I would use an example where there is a whole bunch of code between two lookups on the same thing, but one returns a number and the other returns "Not found", we have to inspect everything in between to find out what happened

-- Instead of substitution, we must use "store tracking", where we have to keep track of the store AND the program at the same time, whereas before we could keep track of just the program. Show this with factorial.

 

Internal mutation is okay, but external mutation is DANGEROUS, how do we tame it?

 

Write a traffic light simulator with a color and a function 'next' that goes green -> yellow -> red -> green -> ...

-- Write in accumulator style, then port

-- Use this as the way of discussing the design of external mutation-based functions

-- Tests cases aren't simple, because they have to mention the state variable (if color is "green", then after next(), color is "yellow" --- not the same as next("green") == "yellow")

-- Instead, our test cases must look like:

---------- // Pre condition

---------- color = "green";

---------- // Test

---------- next();

---------- // Post condition

---------- printf("The answer is %s, but should be %s\n", color, "yellow");

 

Some built-in Java functions use mutation. For example, getc

 

#include <stdio.h>

int main() {

 FILE* f = fopen("18.cc", "r");

 printf("The answer is %c, but should be %c\n", getc(f), '#');

}

 

// You must explain that %c means "character", which is an integer (like 64) interpreted as a letter (like 'a'). C syntactic minutiae: Notice that single characters use single quotes, not double quotes, like strings.

 

This succeeds, "The answer is i, but should be i"

If we try this test case again,

 

 printf("The answer is %c, but should be %c\n", getc(f), '#');

 

It fails, "The answer is i, but should be #"

 

// More minutate, if getc() ever returns -1, that means the file is over. It will return -1 from that time on.

 

That means getc uses mutation.