Lab: Kick Forward Style in Java

Kick Forward style in Java - Introduction

In this lab you will implement a solution of the Kick Forward style in Java for the term frequency task.

(The unchanged task description is available in the Prelude of the first lab.)

The constraints of the Kick Forward style are the same as the ones specified in the previous lab.

Unlike the previous lab, this one requires you to think about types. Try to use “strong types”: you should avoid circumventing the type checker (e.g., try to avoid casts, and avoid Object as a type).

Create and Clone Your GitHub Repository

To create the repository for this lab, fork this starter repository.

Your repository now exists on the GitHub servers. If you want to work on it, you first have to “clone” it on your computer.

Implement Your Program

You can find Crista’s Python implementation of the Term Frequency task in Kick Forward style in her GitHub repository:

https://github.com/crista/exercises-in-programming-style/tree/master/09-kick-forward

If you want, you can use Crista’s implementation as a starting point for your Java code (but be mindful of the last lab’s warning). You can also make use of the functions’ implementations you wrote for the Java Pipeline lab (or the code snippets provided in the description of that lab).

Once you have the repository (a directory) on your computer, you can open it in your IDE (e.g., in VS Code). You can easily do this using the code command, passing as an argument the path to the appropriate directory:

code ~/lab-04-kickforward-java

Before you start “hacking”, please read the README (file README.md).

Then create a new Java file named TermFrequency.java.

Implement a solution to the term frequency task in Java following the Kick Forward style.

A few words about types

One of the core parts of this lab is specifying the right types for the continuations (i.e., the functions passed “to be executed next”). The page of the Java documentation on functional interfaces (package java.util.function) might come in handy.

Besides the generic Function<A, B> type, there are also specialized types that might be helpful (e.g., Supplier<B> or Consumer<A>). The answers to this question on StackOverflow also provide convenient summaries.

Be also mindful of how to invoke a function whose reference is stored in a variable. If f is a variable of type Function<A, B>, you cannot use f(a), but you need to invoke the method apply (i.e., f.apply(a)). The name of the method differs for each functional interface: consult the documentation to read about the appropriate one for each case.

Run, Test, and Debug the Program

Read the README.md and the first part of this lab to figure out how to run the program.

Test

We strongly recommend to use the test script, because it shows you whether your solution is functionally correct. For this, it compares your output with the reference output we provided. Obviously, this only works if you strictly follow the rules (e.g., don’t print out debug output), otherwise the script will tell you that you don’t produce the correct output.