The Old Elementary Level

The old Elementary Level provides support for programming in functional Java, which can be taught with only algebraic data types--types that are inductively defined, such as integers, booleans, lists, and trees. Because of this, only a small subset of the Java language is necessary. Most importantly, all fields and variables are immutable; in other words, they are automatically made final, so their values cannot be changed once they are set.

Because of this immutability of data, for, while, and do loops cannot be used at the Elementary level. We also do not allow arrays because they are commonly used with a procedural-style approach to programming (loops) rather than an object-oriented one and are inherently mutable. And since void return methods have few uses without mutable data, they are only allowed in JUnit test cases at this level. We also simplify the language for the student by not allowing null as a keyword. This protects beginning students from getting null-pointer exceptions but also means that instructors should not allow the students to use library functions that return null. In addition, interfaces are not allowed at the Elementary Level; only classes and abstract classes are allowed. By waiting to introduce interfaces until after the students are familiar with abstract classes, we hope students will have an easier time differentiating between interfaces and abstract classes. We also disallow the use of explicit access modifiers (final, private, static, etc.), and instead automatically make all fields and local variables private and all methods public. The one exception to this is that classes and methods can be denoted as abstract. We also do not allow the use of package or import statements in order to simplify the concepts that beginning students must learn. Of course, students' classes can still reference other files in the same directory, and they also have access to all classes in the java.lang package, and if students extend "TestCase" we automatically import junit.framework.TestCase for them.

We automatically generate a constructor for each class that students write at the Elementary Level. Each class's constructor takes a value for each of its fields, and sets the fields to those values. None of a class's fields can be set outside of the automatically generated constructor. We consider fields to be any field in the class or one of its superclasses that also has a visible accessor (a method of the same name as the field that returns its type). We automatically generate accessors for each field (for example, field my_field would have an accessor my_field()). We also generate a toString() method that returns a description of the object--its class name and field values, an equals() method that determines if two objects are equal by comparing their class types and the values for each of their fields, and a hashCode() method that follows the Java Language Specification that if two objects are equal, their hash codes are the same. Students cannot override any augmented methods at this level.

Although at first glance this level seems limited, even the basic functionality provided is powerful and flexible. The Composite, Union, Interpreter, and Factory patterns can all be taught at the Elementary level.