jj logo
Take a quick tour of JJ
Teacher Registration
Student Registration
Industry Registration
Guest Registration
Some Humor
Friends
Quotes


Name
Password
School


..
The Making of JJ: Designing a Beginner's Language That Offers Advanced Features


David Epstein
Department of Computer Science
California Institute of Technology
Pasadena, California 91125
depstein@cs.caltech.edu

John Motil
Department of Computer Science
California State University, Northridge
Northridge, California 91330
jmotil@csun.edu

ABSTRACT

JJ is a language and online environment designed for beginners. JJ has an ideal CS1 syntax and consists of a desirable subset of the features found in Java. The first part of this paper describes part of our process for defining the JJ language and glances at some of our goals and choices. In addition to the features expected from a subset of Java (such as public and private variables and methods, choices and loops), JJ has a few extra features which could be covered before introducing inheritance. The second part of this paper describes three extra features:
  1. GUI building with panels, buttons and text areas
  2. File I/O with exception handing
  3. Design by Contract with assertions
This paper concludes with a world wide invitation to free online JJ accounts and instructional material.

INITIAL GOALS

Language design by more than one individual can be a painful pile of compromising positions. Giving decision ownership to agreed upon goals, however, can result in a consistent elegance. We present to you our initial goals and a snapshot of our decision making as we struggled, strategized and simplified before finalizing the JJ definition.

We started with two important goals:

 Goal #1 BEGINNER: Be an ideal language for beginners
 Goal #2 JAVA: Be an introduction to Java.
Not knowing which of these two were more important to us, we aimed at both. The beginner goal #1 (be an ideal language for beginners), does not (unfortunately for the Java goal #2) involve semi-colons and curly brackets. If one were willing to accept the semicolons and curly brackets, it turns out that Java does not have too many disturbing syntactic characters such as #, :, & and many uses for *, as found in C++. We wondered, "Can we live with the Java syntax, its ; and {}?" Java's typical Hello World program gave us our answer:
public class MyFirstClass {
 public static void main (String args[]) {
  System.out.println("Hello, world");
 }
}
Of these twenty six tokens we wanted to keep only two
 out "Hello, world"
We opted for a Java subset without the Java syntax, knowing if we change our minds we could simply return to a pure Java subset. (As it turns out, we never did turn back.) Thus, we could keep both the beginner goal and the Java goal. Or could we?

Initially, we had no idea if one of these two seemingly opposing goals would dominate the other when it came down to language design decision making. As a pleasant surprise, we can now see how these two goals worked cooperatively instead of combatively in the creation of the JJ language definition.

Looking back, it was actually quite simple. We would first subset Java, selecting desirable CS1 features, and second we would consider the appropriate CS1-friendly syntax.

It was time for a very important third goal

 Goal #3 READABILITY: A beginner's language should
be easy to read: close to natural languages and
devoid of unnecessary punctuation.
From this goal, we decided to begin defining the actual language syntax using the following COMMAND WORD rule: every command begins with a reserved keyword. Not knowing if this rule would result in an elegant definition, we visited some simple examples:
  • Out (which eventually became Output) instead of System.out.println.
  • In (which eventually became Input) instead of gosh.knows.whose.library.readSomething
  • If and EndIf instead of if ... { and }
  • Class and EndClass instead of class ... { and }
  • Routine and EndRoutine ... is public-or-private instead of public-or-private void ... { and }
The more we added to this list, the more we were able to convince ourselves of the command word rule. A large percentage of our ideal beginner's language fit quite nicely with the READABILITY goal and command word rule.

Seeing the benefit behind this goal may require some distaste for the overloaded end character ('}') in C, C++ and Java. Those of us C, C++ and Java programmers tend to like or even love curly brackets. It is unfortunate, however, for some beginners that they must learn to match these characters. For some beginners this is not a problem, but for others it prevents them from learning the concepts while also following the syntax rules.

Those that argue for the beauty of '{' and '}' may want to skip to SECTION 2 (link here) which discusses the advanced features of JJ. Read on from here for extra emphasis on the importance of the READABILITY goal and command word rule.

Understanding common beginning programmers' errors and the difficulties for compilers to accurately report helpful messages helps one appreciate the reasons for not using the characters { and } instead of specific command words. An exercise of randomly removing or adding a '}' from any Java class and recompiling can quickly explain the command word rule. For example, placing a '}' at the end of a Java class could result in the following, confusing for a beginner, message (from javac): "Class or interface declaration expected."

Compilers are usually not written for beginners, so their messages typically report what the compiler is "expecting" instead of what the student likely forgot or misplaced. The command word rule facilitates accurate compiler error messages.

Imagine the absolute beginner, attempting to write (copy) their first program, placing an extra } at the end of the System.out.println line is told the above confusing error message: "Class or interface declaration expected."

public class MyFirstClass {
 public static void main (String args[]) {
  System.out.println("Hello, world");}
 }
}
A certain percentage of absolute beginners, having no idea what is wrong, could take the message literally and replace the keyword "class" with the word "Class". Afterall, the error message does complain about a "Class ... declaration", and the instructor has already warned the students that words are case-sensitive so take care to type the words exactly. The result of the next compile is disasterous, reporting three errors with the final error (usually the one beginners see first) suggesting that the file be named Class.java. Any absolute beginner that follows this path, changing the filename to Class.java is not likely to ever find the extra }.

Using specific words such as EndIf and EndRoutine instead of a single character, '}', not only helps the compiler's error reporting, it helps the readability and understandability of small examples for beginners.

At this point, with the command word rule proven, our focus returned to the desirable Java subset for CS1. For our next step, we aimed for our upper limit: What limits JJ? This was simple. We decided that JJ does not offer inheritance. This helps strengthen the words "introduction to" in Java goal and eliminates the possibility of any confusion with the words "replacement for". JJ is a Java tool, a tool that helps beginners learn the basics of programming in a Java style (that is, a Java style but not a Java syntax). Java is a feature-full, professional programming language (better make that "language, library, and environment") not needing replacement from two underfunded educators. We had our fourth and final goal

Goal #4 NO-INHERITANCE: JJ does not do inheritance.
Nothing went without questioning. We considered inheritance. When we looked again at the direction of our creation if JJ did inheritance, and saw mostly a copy of Java with an altered syntax. Remembering the Beginner goal, and relying on the statistic--about seventy five percent do not cover inheritance in CS1--we concluded that the No-inheritance goal stays. JJ does not have the word "extends" or "implements" or any such issues that accompany these features.

Did we keep the word "class"? Yes. JJ is designed to teach encapsulation, but stops before inheritance. Some may use JJ for a whole semester; others may use JJ for only the first half of the semester. Regardless of length of time before switching from JJ to Java, we encourage instructors to show the translation to Java before the end of the semester (since something could get lost in the translation in another course with another instructor at another time).

Given four goals, what follows briefly conveys how we made a few language design choices guided by these goals.

SOME CHOICES

Given our above goals, we took a stab at an initial definition and had a major part of our first definition within a few Fridays. With time, everything was questioned, over and over. The rest of this paper introduces a language that has taken us over a year to define, refine, and redefine.

Variable? This word seems to confuse students. How about "container"? No. For one, it has recently taken a different definition in programming. Container does, however, have a nice visual aspect. But, no, it is too long.

We were searching for the keyword to begin a command that declares a variable. The type could be the first word (Int, Real, Bool) or the word Variable, Container or Decl?

Box!

Box is a perfect word, yet we wanted to consider all reasonable possibilities, so we asked ourselves, "Why not Int, Real and Bool?" Looking at some Java variable declarations

 private int i1;
 int i2;
 int[] i3Array;
 int i4Array[];
one sees that the first word in these commands is of no help for a struggling beginner. The type of the variable (int or int[]) is no more important than its accessibility. What is really the most important word in a declaration? We decided that the type is not more important than the fact that a declaration of a variable is happening. We were, afterall, designing a language for beginners. There is nothing broken with the Java language definition, it simply was not designed for beginners. We decided that the command name for a variable declaration, and the first word in the command is the word Box. (For the rest of this paper, we will use the word "box" instead of the word "variable".)

Next, we decided that the name of a box is more important than its type. After considering many options, we defined the Box command

 Box name type
But, needing to capture either public or private (protected is, of course, not needed as JJ does not do inheritance) for a class box, we discarded
 Box name type
and
 Box name type public_or_private
for
 --local box
 Box name ofType type
and
 --class box
 Box name ofType type is public_or_private
A theme of alternating keywords and nonkeywords began; something you will recognize in other JJ commands.

You may be asking, "What in the world is ofType?" During this discussion on declarations, we decided on the types--int, real and bool. Short and sweet. Recalling the Java goal, we added String (later we shorted String to Str) giving us four short words that translate directly to four types in Java.

Actually, in this case, the Java goal wins over goal Beginner goal as String is a class and int, real and bool are types. A more "pure" CS1 language would likely have all four as objects or would offer some sort of String as a primitive type (perhaps char). It is actually unclear what a pure CS1 language would offer as primitive types, if any. For us, there was a clear benefit to using strings as a means of introducing the notion that there are classes and there are types. Classes are different than types. Since JJ is a stepping stone to Java, C++ and possibly other languages, we saw a benefit in introducing the concept of primitive types versus classes instead of going purely with classes.

JJ's box declaration commands are

 Box name ofType type
 Box name ofType type is public_or_private
 Box name ofClass name 
 Box name ofClass name is public_or_private

type is int, real or bool
public_or_private is public or private
Str is a predefined name.
Arguments (parameters) are different than boxes. We wanted a different word, something other than Box. We considered Argument, Arg, Parameter or Param. Either too long or not clear. Arg is not as clear as ... Slot! Each argument is declared in a Slot command.

Some visual aspects of JJ began to unfold. Unfortunately, this theme did not extend much further than Box and Slot. We opted for Class, Function and Routine (where a routine is a "void function" in the function-only world of C, C++ and Java) which are words that do not induce any particular visual image. The words Box and Slot can be visually reinforced with drawings. For example, we draw a box and a slot as follows:

(* picture of box and method with slots belongs here *)

Resisting the abbreviations Func and Rout (or Func and Proc) somewhat broke the "short and sweet" approach for command words. But, we were searching for short words as compared to short abbreviations (please excuse int and bool, but these words appear far more often than Function and Routine, so we justified using these abbreviations).

There are many more interesting choices and rechoices as we iterated on the JJ definition. For example, we considered the word array before opting for the two character token '[]'. We considered no indentation requirement, then forced indentation requirement, finally converging on two appropriate indentation requirements:

  1. The End-ing command must be in the same column as its matching command (that is, the E in EndIf must be in the same column as the I in If).
  2. Nested constructs cannot begin in the same column (that is, the I in inner If must not be in the same column as the I in an outer If) preventing the "everything in column one" default for the stuggling CS1 student.

After observing examples, we added a Boxes command so that

 Box x ofType int
 Box y ofType int
 Box z ofType int
could be shortened to
 Boxes x,y,z ofType int
Rare it was, however, that we allowed shortened versions. The Boxes command is one example of a convenient shortening (in both keystrokes and number of lines) of an already available feature. Distaste for i++;, ++i; and i += 1; did not prevent us, however, from offering an Inc and Dec command.
 Inc i by 1
is only a slightly shortened version of
 Set i = i + 1
but it helps the reader recognize an increment at a quick glance. Which leads us to one of our final discussions of our choices while defining JJ (in this shortened summary). Notice above, the word "Set"? Recall the command word rule from the readability goal. It had us fishing for a word to start an assignment command. Not that
 i = 3
is all that bad for beginners; it simply does not flow with the rule, not to mention greatly complicating the compiler's ability to accurately report errors. Somehow, a Set command reads much better than an assignment command which can begin with any name, particularly when the command is surrounded by other commands that all begin with a reserved keyword. We originally began the assignment command with the word Let. We switched from
 Let i = 3
to
 Set i = 3
after much consideration. The heaviest influence being textbooks and error messages stating that one must "set" a box before using it. (Even better, one must set a value into a box before using the box.) Imagine the error message if we had decided on Let instead of Set
 Box x ofType int
 Box y ofType int
 Let x = y
---------^---------------ERROR
"Box y must be let before this command"
Indeed, it is much nicer to report
 Set x = y
---------^---------------ERROR
"Box y must be set before this command"
Revisiting the option to break the command word rule and allow
 i = 3
will explain the introduction of yet another JJ command word--Call. If we break the command word rule for assignment and the first word of a command is not required to be a reserved keyword, one would consider the most Java-like definition in JJ for calling a routine to be
 i(arg1, arg2, arg3)
which, as far as the first token is concerned, looks exactly like an assignment command. Attempting to quickly scanning down the left side of a list of commands, a great deal of confusion can result from having any name occur as the first word in the two special cases of an assignment and a method invocation. For example, compare
 Box Box1 ofType int
 Box1 = someFunc()
 someRout(Box1)
with
 Box Box1 ofType int
 Set Box1 = someFunc()
 Call someRout with (Box1)
If you are not convinced, scan down the left side of the JJ code in the second example above, then do the same with the first example immediately above. If you are still not convinced, here you see the same examples with longer box and routine names
 Box myFirstIntBox ofType int
 myFirstIntBox = someFunc()
 myFirstRoutine(myFirstIntBox)
versus
 Box myFirstIntBox ofType int
 Set myFirstIntBox = someFunc()
 Call myFirstRoutine with (myFirstIntBox)
It may take a little imagination to see the benefit which such small snippets of code. Reading and writing larger JJ examples will clear any final doubts about sticking to the command word rule for assignment and method invocation. (After reading and writing some JJ code, one learns to scan downwards at the first word on each line and quickly get an idea of what sort of flow control is happening, and sometimes noticing if a command is missing or is out of place.)

JJ offers the following Call commands

 Call name
 Call name with (expr-list)
where the first form is the Call command if the routine does not expect any values for slots and the second form is the Call command which passes values into the expected slots.

The following shows some slightly larger examples of JJ code:

(* some examples here, maybe factorial or two *)

THE DEFINITION

The complete JJ BNF and JJ-to-Java translation definition is available online. Listing the commands can convey much of JJ for those familiar with languages.

For this paper, we divided the below JJ commands into seven groups. The groups represent potential stages of introducing programming concepts to your students before switching to Java and introducing inheritance. (Once the instructor is ready to present inheritance, JJ provides a natural transition into Java, but JJ does not prohibit one from making a transition into other languages such as C++.) The first three groups we consider mandatory before switching to Java, the final three groups list the extra features which are explained in the rest of this paper.


In the following SYNTAX sections, a word that is all CAPITALIZED represents a term that is expanded. All other words are keywords. Terms are not expanded below, but there is one term worthy of expansion in this paper--TYPE refers to int, real or bool.

STAGE 1: Intro (in possible order of introduction)

 COMMANDS
  Output, Outputln, Box, Input, Set, If, ElseIf, Else, EndIf,
  Repeat, ExitOn, EndRepeat, Inc, Dec, Boxes
 COMMAND NOTES
   note#1.1: Every If must have a matching EndIf
   note#1.2: One and only one ExitOn is required inside a
    Repeat/EndRepeat and it must not belong to an If/EndIf.
 SYNTAX
  Output EXPR
  Outputln EXPR
  Box NAME ofType TYPE
  Box NAME ofType TYPE is PUBLIC_OR_PRIVATE
  Input NAME
  Set LHS_NAME = EXPR
  If EXPR then
  ElseIf EXPR then
  Else
  EndIf
  Repeat
  ExitOn EXPR
  EndRepeat
  Inc LHS_NAME by EXPR
  Dec LHS_NAME by EXPR
  Boxes NAME_LIST ofType TYPE
  Boxes NAME_LIST ofType TYPE are PUBLIC_OR_PRIVATE
STAGE 2: Introducing methods
 COMMANDS
  Function, EndFunction, Routine, Start, EndRoutine, 
  Call, Slot, Debug, Debugln
 COMMAND NOTES
   note#2.1: The Start command must be in one public routine
    in order to turn it into the "main" routine.
   note#2.2: Each slot (argument) must be defined in a Slot command.
   note#2.3: Debug and Debugln commands are used in functions since
    functions cannot have side-effects and thus cannot have debugging
    Output and Outputln commands.  The Debug and Debugln commands
    will write to the Java console and not to the output panel.
 SYNTAX
  Function NAME(ARG_LIST) ofType TYPE is PUBLIC_OR_PRIVATE
  Function NAME(ARG_LIST) ofClass NAME is PUBLIC_OR_PRIVATE
  EndFunction NAME
  Routine NAME(ARG_LIST) is PUBLIC_OR_PRIVATE
  EndRoutine NAME
  Start
  Call NAME
  Call NAME with (ARG_LIST)
  Slot NAME ofType TYPE
  Slot NAME ofClass NAME
  Debug EXPR
  Debugln EXPR
STAGE 3: Introducing classes
 COMMANDS
  Class, EndClass, Constructor, EndConstructor,
 COMMAND NOTES
   note#3.1: A constructor is mandatory inside a class if there is
    public class boxes.
   note#3.2: The Start command may be in one public routine
    in order to turn it into the "main" routine.
   note#3.3: An Import command is introduced at this stage
    and is required if there are any Input, Output or Outputln
    commands.  For now, the only import students need to know
    is an import of JJIO.
    At later stages, imports can be JJGui or JJFileIO.
 SYNTAX
  Import NAME
  Class NAME
  EndClass NAME
  Constructor NAME(ARG_LIST) is public
  EndConstructor NAME
STAGE 4: Arrays, and more than one class (a.k.a. introducing "objects")
 COMMANDS
  New, NewArray, Constant, Loop, EndLoop
 COMMAND NOTES
   note#4.1: A New command creates an object for a box.  Boxes
    ofClass Str, however, do not require New commands (ala Java).
   note#4.2: The NewArray command helps students understand the
    two part process of creating an array and then creating the objects
    in that array (ala Java).
   note#4.3: The Loop and EndLoop commands are counting-loops (for
    arrays) and need not be used should one want to stick with
    Repeat, ExitOn, EndRepeat and create a separate box for counting.
 SYNTAX
  New LHS_NAME ofClass NAME
  New LHS_NAME ofClass NAME with (ARG_LIST)
  NewArray NAME ofType TYPE[EXPR]
  NewArray NAME ofClass NAME[EXPR]
  Constant NAME = EXPR
  Loop NAME from EXPR to EXPR while EXPR
  EndLoop
STAGE 5: GUI
 COMMANDS
  none
 COMMAND NOTES
   note#5.1: These commands write to the console (System.out.println)
    which is needed instead of the Output and Outputln commands should
    one desire GUI by importing JJGui.
   note#5.2: GUI is made available by importing JJGui.
   note#5.3: If importing JJGui, also importing JJIO is not allowed.
   note#5.4: Words (instead of commands) are added to accomplish 
    GUI capabilities in JJ.
STAGE 6: FileIO and exceptions
 COMMAND
  TryCall, TrySet
 COMMAND NOTES
   note#6.1: These commands introduce the concept of exceptions
   note#6.2: FileIO is made available by importing JJFileIO.
 SYNTAX
  TryCall IO_METHOD_CALL onFail LHS_NAME = EXPR
  TryCall IO_METHOD_CALL onFail NAME
  TryCall IO_METHOD_CALL onFail NAME with (ARG_LIST)
  TrySet LHS_NAME = IO_METHOD_CALL onFail LHS_NAME = EXPR
  TrySet LHS_NAME = IO_METHOD_CALL onFail NAME
  TrySet LHS_NAME = IO_METHOD_CALL onFail NAME with (ARG_LIST)
STAGE 7: Design by Contract
 COMMANDS
  PreCheck, PostCheck, Check, Invariant, EndInvariant
 COMMAND NOTES
   note#7.1: More on this below.
 SYNTAX
  PreCheck EXPR bounce MSG
  PostCheck EXPR bounce MSG
  Check EXPR bounce MSG
  Invariant
  EndInvariant

THE EXTRAS (GUI, FILE I/O, Design by Contract)

The JJ language includes three features that an instructor may or may not choose to introduce before switching to Java and covering inheritance. These features are:
  • GUI building with panels, buttons and text areas
  • file I/O with exception handing
  • Design by Contract with assertions

GUI

Although quite powerful, JJ's GUI features are actually an absolute minimum subset of Java's GUI features. The idea, a challenging one, is to introduce during CS1 some of Java's GUI features. No new JJ commands are introduced. Instead, four new classes are available--JJGridPanel, JJBorderPanel, JJButton and JJTextArea.

Once students discover how simple it is to put together a JJ program that displays buttons, interest is sometimes sparked in those that were just "getting by" and barely completing the labs. The design of the GUI features in JJ was driven by the difficulty of learning the Java AWT due purely to its size (list of features).

In Java, reading about frames, windows, panels, buttons, text fields, text areas, labels, and five layout managers, it is easy to have no idea what a panel is. Java (AWT or Swing) GUI building is actually quite simple if the features are divided and only a subset of the widgets are presented. On one hand place panels and layout managers, on the other hand place text areas and buttons.

Another simplification is made by reducing the list of layout managers to the two most often used--BorderLayout and GridLayout.

Since layout managers are used to describe panels, one last reduction is made by combining panels and layouts. JJ offers a JJBorderPanel and a JJGridPanel.

This paper leaves little room for explaining these four words to those unfamiliar with GUI features of Java. We do, however, show one example, a tic-tac-toe program written in JJ.

Import JJGui

Class TicTacToeUsingArrays
--Name: ??  --the name (replace '??') has to match the login name
 Box   buttons                    ofClass JJButton[] is private
 Box   ta                         ofClass JJTextArea is private
 Box   gp                         ofClass JJGridPanel is private
 Box   bp                         ofClass JJBorderPanel is private
 Box   whoseTurn                  ofClass Str is private

 Constructor TicTacToeUsingArrays(none) is public
  Box i ofType int

   --allocate an array and loop thru New buttons
   NewArray buttons ofClass JJButton[9]
   Set i = 0
   Repeat
    New buttons[i] ofClass JJButton     with ("")
    Inc i by 1
   ExitOn (i == 9)
   EndRepeat
   New ta ofClass JJTextArea   with ("X's turn: To Start, click a button",2,34)
   New gp ofClass JJGridPanel with (3,3)
   New bp ofClass JJBorderPanel
   Set whoseTurn = "X"
 EndConstructor TicTacToeUsingArrays

 Routine ActsAsMain(none) is public
  Box i ofType int

   Start -- tells JJ that this is the "main"

   --loop thru adding buttons to panel
   Set i = 0
   Repeat
    Call gp.add with (buttons[i])
    Inc i by 1
   ExitOn (i == 9)
   EndRepeat

   Call bp.add with ("Center", gp)
   Call bp.add with ("South", ta)
   Call bp.jjShowAsMainPanel
 EndRoutine ActsAsMain

 Routine jjHandleButtonPress(b) is public --Always needed
  Slot b ofClass JJButton --Always the same ...
  --  ...although, the name (b) could be different
 
  Box ok ofType bool
  Box i ofType int
  Box buttonLabel ofClass Str
  Box bCurr ofClass JJButton
   Set ok = false

   --loop thru buttons until finding the pressed one
   Set i = 0
   Repeat
    Set bCurr = buttons[i]
    If (b == bCurr) then
       Set buttonLabel = bCurr.getLabel()
       If (buttonLabel.length() == 0) then
          Set ok = true
          Call bCurr.setLabel with (whoseTurn)
       Else
          Call ta.setText with ("*** ERROR *** Button already pressed")
       EndIf
    EndIf
    Inc i by 1
   ExitOn (i == 9)
   EndRepeat

   If (ok) then
    If whoseTurn.equals("X") then
     Set whoseTurn = "O"
     Call ta.setText with ("O's next: Please click a button")
    Else
     Set whoseTurn = "X"
     Call ta.setText with ("X's next: Please click a button")
    EndIf
   EndIf
 EndRoutine jjHandleButtonPress
EndClass TicTacToeUsingArrays

FILE I/O

We introduced file I/O in JJ to allow more involved programming examples and exercises before teaching inheritance. Recall, we expect the typical time for switching from JJ to Java to be once everything desirable, before inheritance, has been presented. As with GUI building, the instructor may or may not decide to present file I/O before switching to Java and presenting inheritance.

A lot of ground can be covered without file I/O, but it is nice to have the option of manipulating thousands of data values instead of a few hand-entered values. Another benefit of teaching file I/O with JJ is the introduction of exception handling.

There are two possible exceptions in JJ:

  1. Attempting to read or write to a file that was not previously opened for reading or writing
  2. Attempting to read invalid input.
From Java, we kept the word Try, but replaced the word "catch" with the word onFail. We opted against a series of command inside a "try block". Instead, the trying all happens in one command The result is the addition of two new commands-- TryCall and TrySet. The syntax is as follows
 TryCall io-routine onFail method-call
 TryCall io-routine onFail assignment
 TrySet lhs = io-function onFail method-call
 TrySet lhs = io-function onFail assignment
Here is a brief explanation of the steps required to achieve file I/O in JJ.
  1. Define a box ofClass JJReadFile or JJWriteFile
  2. Create a new JJReadFile or JJWriteFile object for this box (using the already mentioned New command)
  3. Try to read-from or write-to this object using methods available in the JJReadFile or JJWriteFile class (readWord, readLine, write or writeLine) with a TryCall command
  4. If reading, obtain the value from the getString method.
  5. If desired, Try to convert the string that we read into an int or a real with a TrySet command.
Why are readWord and readLine defined in JJ as routines instead of functions? In JJ, functions cannot have side-effects. A favorite saying for this design is, "Asking the question should not change the answer." Thus, reading a line and retrieving the value read are two distinct actions. This leads us into a discussion of our final feature-- responsible programming with assertions and Design by Contract.

Design by Contract (DBC) [1]

Learning how to program and teaching beginners how to program has proven to be challenging. One might ask, "Why make the task more complex with the addition of Design by Contract capabilities?" As with the other two JJ features, an instructor could, of course, decide not to cover DBC. The benefits of emphasizing responsible programming at an early stage, however, pays off with the increased likelihood that these skills will be practiced.

As CS1 can be overwhelming, it is tempting to allow the focus to become "getting the program to work". Introducing Design by Contract opens an opportunity for the instructor to emphasize communication, documentation and responsibility of classes (contracts).

As society becomes more and more dependent on computers, we will soon see a large emphasis on responsible programs, not just ones that work. The Y2K hoopla is truly just a beginning of the awareness of our dependency on unreliable software.

With much appreciation for Bertrand Meyer and Eiffel, we introduced into JJ the notion of a precondition, a postcondition and a class invariant. Assertions can also be placed in the middle of a routine or function, but these do not become a part of the public contract.

The Design by Contract facilities in JJ was cleanly defined with the aid of two rules:

  1. All functions are "pure"--cannot have side effects.
  2. Private methods cannot call public methods.
At first, it may not be obvious why these rules are helpful. Here is a brief explanation for these two rules.

The first rule, all functions are "pure", is based on the desire to include function references in assertions. The class invariant, for example, contains a list of assertions. Since these assertion conditions could call functions, yet another recursive-class-invariant-language-design nightmare could be introduced if functions were allowed to call routines. Not allowing side-effects in functions, a nice language design decision regardless of Design by Contract, allow functions to exist within the condition of an assertion without the hassle of some esoteric recursive requirement.

The second rule, private methods cannot call public methods, is based on the definition of a class invariant. The class invariant must hold upon returning from a public method. (The first public method of interest is the constructor, which must setup the class invariant before returning.) An incredibly complex language definition results if a public method calls a private method which in turn calls a public method. Ensuring the class invariant within the middle of methods was simply too complex a definition. Disallowing calls to public methods from private methods solved this language design problem.

The JJ commands used for DBC are

 Invariant
 EndInvariant
 Check
 PreCheck
 PostCheck
The syntax of the three assertion commands is
 Check cond bounce msg
 PreCheck cond bounce msg
 PostCheck cond bounce msg
The Invariant/EndInvariant block is placed above the class constructor and can contain only Check commands. The PreCheck and PostCheck assertions appear at the beginning and end of a public method respectively.

All these commands, along with the public boxes and the signature of the public methods can be shown to a customer of the class as the contract--the external definition of the class.

THE ENVIRONMENT

Even an ideal beginner's language will fail if the environment is not readily availability or the installation is complicated. JJ runs on the Internet (no installation required) and is currently free for educational use. Industry use of JJ to teach Java to their employees or to their customers comes at a small fee, a fee large enough to help fund ongoing development of the JJ environment, tools and educational material.

Notice we did not say that JJ is available for downloading off the Internet. We said that JJ runs on the Internet.

A QUICK TRIBUTE AND ACKNOWLEDGEMENTS

While defining JJ we were heavily influenced by Bertrand Meyer, his book "Object Oriented Software Construction, 2nd edition" [1], and the Eiffel programming language. If it were not for the overwhelming influence of Java on CS1 and our prediction that this will continue, we surely would have let Eiffel drive our definition ... and be informing you about EJ or JE instead of JJ. You have, by the way, already seen some of Bertrand's influence with our use of the word "command" instead of the word "statement".

SUMMARY

Learning how to program using the somewhat unforgiving syntax and environment of Java (and other languages such as C++) is difficult. JJ provides a simplified syntax and environment, designed for beginners. Although JJ is based on a subset of Java, extra features are available for instructors to choose from before presenting inheritance and object oriented programming. We introduced three extra features of JJ--GUI, file I/O and Design by Contract.

The JJ environment runs in a browser. This online environment includes the compiler, a one-to-one line-by-line translation to Java, and a language reference material. JJ accounts are currently free for noncommercial educational use and can be requested from http://jj.cs.caltech.edu.

REFERENCES

[1] Meyer, B. Object Oriented Software Construction, 2nd Edition, Prentice Hall (1997)
Return to
    JJ
home page
..