Class 8 — Monday, September 21

Progress Exam 1, then the first Java: the same functions you already wrote, in a second language.

The first half is Progress Exam 1. This page is the second half.

Nothing below is new. Every function here is one you have already written in Pyret — the only thing changing is how it is spelled. You stay in a browser tab today; nothing to install.

Outline

  1. Two spellings — the same function, side by side
  2. Where the program starts — main, and printing
  3. The contract is the signature
  4. Run it — pairs, at the keyboard
  5. What else to do — if you got there early
  6. Before Wednesday

1. Two spellings

stripe-width from the first week of the course, and the same function in Java:

fun stripe-width(u :: Number) -> Number:
  doc: "the width stripe draws for unit u"
  u * 6
where:
  stripe-width(10) is 60
  stripe-width(5) is 30
end
// the width stripe draws for unit u
int stripeWidth(int u) {
    return u * 6;
}

With your neighbor: three things that are different, and one thing that is the same. One of you puts them in the Journal.

2. Where the program starts

Add a starting point and the file runs. This is the whole thing:

// the width stripe draws for unit u
int stripeWidth(int u) {
    return u * 6;
}

void main() {
    IO.println(stripeWidth(10));
    IO.println(stripeWidth(5));
}

void main() is how Java spells start here. Every program has one, and it is the part Java runs.

IO.println prints. Pyret showed you the answer to every line you typed; Java shows nothing at all unless you ask it to.

This is Java’s short form and it needs Java 25 or newer, which is what OneCompiler gives you. Older Java wraps all of this in a class and spells main a longer way — you meet that later in the course.

Most Java you will find online looks like this. It is the same program:

public class Main {

    // the width stripe draws for unit u
    static int stripeWidth(int u) {
        return u * 6;
    }

    public static void main(String[] args) {
        System.out.println(stripeWidth(10));
        System.out.println(stripeWidth(5));
    }
}

public, static, void and String[] args each get their own day later in the course. On an older Java, IO.println gives you cannot find symbol: variable IO — that is the version talking, not your code.

3. The contract is the signature

Week 1:

circle :: (radius :: Number, mode :: String, color :: String) -> Image

Java:

Image circle(double radius, String mode, String color)

You have been writing type signatures since the first week. The types move in front of the names and the arrow becomes the word at the start, and that is the entire difference.

There is one real difference underneath it. Try this in both languages:

stripe-width(2.5)

Pyret gives you 15. Java will not run the program at all:

required: int
found:    double

Number covers 2.5 and int does not. Java checks the contract before the program starts; Pyret checks it as the program runs.

Now put the same mistake somewhere it can never run:

print("starting")
if false:
  stripe-width("blah")
else:
  0
end
print("finished")
IO.println("starting");
if (false) {
    stripeWidth("blah");
}
IO.println("finished");

Pyret prints starting and finished and says nothing else. Java refuses to compile.

The bad call never runs in either language. Java found it by reading the program, not by running it.

4. Run it

Pairs. You will both get a turn at the keyboard — I will say when to swap.

Same shape as code.pyret.org: an editor, a Run button, output underneath.

  1. Open https://onecompiler.com/java.
  2. Clear out whatever is in the editor and type the program from section 2 in. Do not copy and paste it.
  3. Press Run.

Done when it prints 60 and 30.

Then: check it the way where: did

Your where: block asked whether stripe-width(10) is 60. Java spells that ==, and it gives you back true or false. Change the two lines in main to ask the question instead of printing the answer:

IO.println(stripeWidth(10) == 60);
IO.println(stripeWidth(5) == 30);

Done when it prints true twice.

Then: one you write yourself

A flag is two stripes wide. Here is the contract and the examples — you write the // line and the body, and check it the same way.

int flagWidth(int u)
flagWidth(10)  is  120
flagWidth(5)   is  60

flagWidth is allowed to call stripeWidth. It is shorter if it does.

If Java stops with a red error, read the line number first — it points at the line it got stuck on, which is more than Pyret ever gave you. ';' expected means that line needs a semicolon at the end.

5. What else to do

Only if flagWidth is running. The first three are independent.

One that takes two numbers

A second parameter is a comma. stripes is the width of n stripes at unit u:

int stripes(int u, int n)

Done when stripes(10, 2) == 120 prints true. flagWidth(u) is stripes(u, 2).

One that gives back true or false

The type in front can be boolean:

boolean isWider(int u, int limit)

isWider(20, 100) is true; isWider(10, 100) is false.

Done when both print what you expect.

One that gives back words

String describe(int u)

describe(10) gives back a stripe 60 wide. + joins text, and joins a number onto text without being asked:

return "a stripe " + stripeWidth(u) + " wide";

Done when IO.println(describe(10)) prints that sentence.

Make it accept 2.5

Do this one last — it changes stripeWidth for the others.

Section 3 ended with Java refusing stripeWidth(2.5). Change the contract: both ints in stripeWidth become double. Java then stops on flagWidth:

incompatible types: possible lossy conversion from double to int

It still promises an int. Change it too.

Done when stripeWidth(2.5) prints 15.0. stripeWidth(10) prints 60.0 now as well.

6. Before Wednesday

Install a JDK and an IDE. Both are linked from Resources.