Judith Bishop, University of Pretoria, South Africa
e-mail: JBISHOP@dos-lan.cs.up.ac.za
URL: http://www.cs.up.ac.za/photos/judy.html
Paddy Nixon, Trinity College, Dublin, Ireland
e-mail: Paddy.Nixon@cs.tcd.ie, URL: URL: http://www.dsg.cs.tcd.ie/~pnixon/
Evelyn Rozanski, Rochester Institute of Technology, USA
e-mail: epr@it.rit.edu, URL: http://www.it.rit.edu/~epr/
Peter Welch, University of Kent, Canterbury, England
e-mail: P.H.Welch@ukc.ac.uk
URL: http://unix.hensa.ac.uk/parallel/www/SEL-HPC/People/PeterWelch.html
Nan actively sponsors M.S. projects to develop Java applets to aid in teaching computer graphics concepts. Masters students are excited to learn a language that will make them more marketable and that their projects will have a life beyond meeting their degree requirement. One of these projects, "Tinker Toys On-line" is available for students studying three-dimensional viewing concepts as presented in Introduction to Computer Graphics by Foley, etal. Others are in progress: color, line and circle drawing, anti-aliasing, polygon filling, fractals, two dimensional clipping, two dimensional transformations, color quantization and fractals.
Nan presented a selection of applets that can be used in teaching computer graphics. These included some that resulted from Bruce Land's graphics, visualization, and research courses at Cornell University. Others were created by Patrick Min, Princeton University, appear on his "Computer Graphics Applets Page" But, perhaps the most ambitious collection appears in the GRAPHICA (Computer Graphics Apprentice) project from Georgia Institute of Technology. Here such applets are provided in the context of teaching graphics through real world case studies.
Our Programming Languages course provides an overview of the principles of the design and implementation of programming languages. In addition to the conceptual overview, we generally require short or medium-sized programming projects in two or three languages, specifically chosen to be somewhat different from the dominant language used in the department (which at the moment is C++). For the Fall '96 semester I chose to use Scheme and Java. I chose Java in order to:
Java turned out to be an even better fit than I had expected. Some of the topics I covered in the course included interpretation versus compilation, exception handling, concurrency, and multi-threading. Each of these can be illustrated quite nicely in Java.
The Data Communications and Networking course is an advanced course, with a light coverage of communications and an emphasis on networking principles and protocols. The programming examples in the book (Computer Networks by Tannenbaum, 3rd Edition) were generally in C. An important part of the coursework is the completion of a student-designed project, typically consisting of a software system of some kind. Several of the students chose to teach themselves Java and used it for their projects, overall with great success. Java is provided with a class library that provides basic network functionality, using a very simple interface that makes it possible to quickly develop simple network-based programs.
While Java's features make it simple to write simple network programs, it is not necessarily the best choice for all network programming, and not just because of efficiency issues. Certain choices that can be made easily in a C program are hidden by the class libraries, requiring the programmer to either develop new class methods, or revert to C. In addition, it was clear that to use Java effectively required the dreaded "paradigm shift" for those who already knew how to do things in C or C++ -- not necessarily a bad thing, but something to be aware of.
I was pleased with the use of Java in these intermediate and advanced classes. Because of the relatively sophisticated nature of the students, we were generally able to work around the instructor's limited knowledge, and rather rough implementation environments, to solve the problems we wanted to solve. I would encourage faculty who want to use Java in the curriculum to begin with higher-level courses, not because beginning students can't learn Java -- I'm sure that they can -- but because this will give the faculty a chance to learn the language well before teaching beginners. I believe that it is very important that we understand the language well before teaching it in the first year, if indeed we think that's a good idea.
Judith's presentation explained how Java was condensed into small enough blocks to slot into existing courses. An example of one of the assignments the students tackled was shown, and others mentioned. Focused assignments were emphasised because the language was only the vehicle. The Java resources used included information from the web, and from this year onward, material from Judith's own book, Java Gently. Having locally produced, well-understood examples was seen as essential in getting the essence of the language across quickly.
The headlong, rapid approach revealed that Java has fairly extensive requirements in terms of memory, disk, bandwidth, and of course, a 32-bit operating system. It was helpful to experience the limitations of the existing equipment with mature groups of students before starting with the large novice classes.
Two semesters of Java in second, third and fourth level courses have resulted in a core group of students who can become assistants once Java starts in the first year. There has also been a spin-off into the research groups, fueled by the enthusiasm of the students. In this way, the reluctance of staff to change was side-stepped.
Judith made the point that the rapid approach is a viable alternative to waiting until Java can be introduced from first year and filtered through the curriculum a year at a time. Given a basis in a modern object-oriented programming language, Java slips quite easily into other courses and a whole department can be transformed to be Java literate within less than a year.
Given this guiding principle, we made the conscious decision to introduce the object-oriented programming paradigm across a wide range of computer science courses, and in particular, as the first paradigm that students encounter in our curriculum. A number of choices had to be made as part of this change of emphasis. The most important was that the choice of the first programming language had to be reviewed. We choose Java.
This presentation will focus on how well Java facilitates the learning process and, in particular, how well it enhances the students' understanding of object-oriented concepts.
The promises
Object-orientation has been adopted as a theme running through the
whole of the first year Computer Science course. This
programming paradigm is well supported by Java. This was, and is, the
main reason that Java was chosen as the first language. With the exception
of basic types such as "int" and "double", everything is an object in Java.
This works well from a teaching perspective and is complemented by the
strongly typed nature of the language, providing a tight framework within
which to learn good programming practices.
The surprises
The first two weeks of the course were spent providing an introduction
to objects and modeling. Although this reduced the time spent on the
"syntax", it not only contributed to student programming skills but, very
significantly, to their understanding of the concepts presented in the
object-oriented design course that was taught in parallel.
Minor problems previously encountered, like the difficulty students have with the concept of parameter passing disappeared. This is at least partly attributable to the fact that classes and methods (a.k.a. things with parameters) arrived on day one. Subsequently, the students only became aware of the importance of method parameters at a late stage - too late for them to feel confused by the concept.
Equally important was the fun-factor, although I'm not sure why. We did not build applets or graphical user interfaces until very late in the course. Despite this, the students retained their perception that Java was a "fun" language.
The downsides
One perceived drawback is that, when compared to previous CS1 classes,
the Java class did not travel as far along the traditional path. For
instance, the students did not reach the heady heights of recursion.
However, this must be balanced against the progress that students made in other
areas not covered previously, such as objects, classes, and
inheritance. Students clearly took longer to assimilate the object
approach; the reasons for this are open to debate.
Java still possesses carry overs from its C++ heritage. The "public static void main" confuses students. The syntax is a little rough, the use of "{}" is clearly not the most ideal for the new or naive learner. The flip side of this is that the students progression to C++, which we use for our systems programming and our graphics courses, should be easier than from Modula-2.
Input/output is a big problem because Java does not provide for "easy" keyboard input. During the course we resorted to building our own class for input/output and used it as the case study at the end of the course. This served to demonstrate the power of the language and of the object-oriented paradigm. Nevertheless, the provision of a "standard" input/output interface is a must if the language is to proliferate as a teaching language.
The conclusions
Our first experiences with Java have been very rewarding. Motivated students are
always more stimulating to teach, and for whatever reasons, Java has
motivated them. It is our job as educators to motivate our students.
Java contributes in this area, but it clearly not the only factor.
We deliberately steered away from the applet-zone in this course, deciding the added baggage required to introduce applets and graphical interfaces would detract from the understanding of objects, modeling, and programming. This is being reviewed for the next offering of the course.
I am not sure about Java's general applicability as a first language. Personally, it would seem a little unusual to use Java if the focus of the whole degree course were not firmly based around the object-oriented paradigm. If you decide that an object-oriented paradigm is pivotal to your degree course, then Java fits well! It provides many of the benefits of more purist languages such as smalltalk, smooths the progression to other courses that use C++, and seems to introduce a zest for learning which I have personally not experienced before in similar courses.
The approach in this course is to minimize the discussion of class design and to work almost exclusively with applets. Students are introduced to object-oriented terminology and develop a simple base class for an application program and an applet. Other programming projects (re)use Java class libraries, primarily the graphics and abstract windowing toolkit (AWT), and focus on graphical results rather than on number crunching. These have included a "here is my family" applet using a variety of fonts, colors, and a user-defined class; images using the graphics class and applet parameters; a greeting card with sound and animated images using double buffering, threads, media tracker, and parameters; a graphical user interface (GUI) using canvases and nested panels; and an interactive graphical game. This last project was done by teams of two and proved to be very successful. Each team's work was presented to the class, sharing experiences and creativity. The students worked on PCs, Macs and Unix workstations using an environment that included software such as Netscape, Symantec Cafe and the JDK.
The course has been taught twice and the results have been both exciting and excellent! Virtually all students successfully completed the course. While inexperienced students initially found the language overwhelming and confusing, all students were eventually able to write reasonably sophisticated programs, style notwithstanding, using simple classes. Students with stronger programming backgrounds found the transition to Java relatively painless and even designed classes for their applets.
The course was not without problems. The text that was used, Teach Yourself Java in 21 Days, was fine for the first three weeks; however, after that students needed a good language reference book. There was a great deal of frustration with the mundane things that experienced programmers are used to dealing with such as unclear error messages and long loading applet times. Many times, applets ran differently not only within the same environment, but also between the appletviewer and the Symantec Cafe. Lastly, as Java is not yet stable, it was difficult teaching a language that was in transition.
There were several conclusions that can be drawn from this experience:
We are about to introduce Java(TM) as the main language for teaching imperative (object-oriented) programming and will include it in the parallel programming curriculum. Java provides support for parallel computing through a model that is built into the language itself, i.e., threads, but we do not believe that it provides these threads at the right level of abstraction and that we have to do something to raise this before letting students (or, arguably, anyone) loose on them.
Threads are not exactly highlighted in current Java textbooks, or web-mounted tutorials, and the information we do find makes them look hard. A recurring emphasis is that threads programming is difficult (race hazards, deadlock, livelock, starvation ...) and that their use should be fiercely rationed. The motivation given for using them at all is merely to improve performance, primarily response times in graphical user interfaces (GUIs).
This runs almost precisely counter to all our experiences of working with threads over the past decade. Our main motivation for using threads is that they are a powerful tool for structuring both the design and the implementation of systems. Our experience in teaching and developing complex reactive systems (for example GUIs and distributed applications) is that multi-threaded code leads to logic that is simpler to write, read and maintain than its equivalent single-threaded expression. The opportunities they afford for increased performance (through multiprocessors and/or interrupts) are a useful, but secondary, bonus.
The problem with Java threads is that the language designers used the wrong Tony Hoare paper and based them on the concept of monitors [1] (an idea from the late 60s and early 70s) rather than his later algebraic theory ofCommunicating Sequential Processes (CSP) [2][3][4]. A crucial benefit of CSP is that its thread semantics are compositional (i.e. WYSIWYG), whereas monitor thread semantics are context-sensitive (i.e. non-WYSIWYG and that's why they hurt!).
For example, to write and understand one synchronized method in a (Java) class, we need to write and understand all the synchronized methods in that class at the same time - we can't knock them off one by one! This does not scale - we get a combinatorial explosion of complexity!! As advertised, avoiding race hazards (etc.) becomes very hard.
On the other hand, CSP threads can refuse individual events if they are not in a state to accept them. They do not wait on shared condition variables and do not rely on other methods to fix things up for them. Each method has its own contract and looks after itself. This type of logic does scale.
The teaching we have successfully developed over the last ten years is based upon the CSP model, although we hide the mathematics behind the elegant and secure abstractions provided by the occam multiprocessing language [5]. Fortunately, there is a way to build the CSP model on top of Java monitors. We call it JavaPP (Java(TM) Plug-and-Play) [6].
We just need to create a class library for CSP events, channels and alternation (and, possibly, a higher-level kit bag of buffers, multicasters, multiplexors, routers etc.). The implementors of the CSP primitives need to get (carefully) involved in those difficult non-WYSIWYG Java primitives (e.g. synchronized, wait, notify), but nobody else does. The Java language is unchanged, but application programmers work solely with the CSP classes to glue their threads together. They can inherit all the CSP design and analysis methods and tools. Multi-threaded systems become structured to reflect real world system hierarchies. Components become automatically thread-safe and reusable. The nasty accidents of deadlock, livelock and starvation can be ruled out by design. System complexity can be ramped up with linear increase in effort. And no run-time overheads are imposed that wouldn't be needed anyway to prevent race hazards. Of course, without changing the Java language, we cannot match the full security rigour (or even the performance) achieved by a CSP-aware language such as occam, but these are significant wins.
With colleagues at the Universities of Twente (the Netherlands) and Oxford (UK), the above work has been done. Initial results were presented at a WoTUG workshop in England in September, 1996 [7] and further refined at the WoTUG-20 conference in the Netherlands in April, 1997 [8]. A one-day tutorial will be presented in June, 1997 at the PDPTA'97 conference in Las Vegas [9].
We are about to embark upon teaching this material in the undergraduate curriculum and we invite others to download the JavaPP class libraries and join us. Although at Kent we will probably still refer to both CSP and occam as we teach, we do not believe that this is essential - the benefits of the CSP model will transfer even without explicit reference to it! It's time to change the culture: Keep-It-Simple-Stupid (KISS) no longer means stick with one thread until you are forced otherwise. Instead, KISS means using threads because they are natural - and nature does have a way of coming up with simple solutions to complex problems.
There are two models for teaching introductory programming: a high level conceptional model using a language such as Scheme and a machine model using a language like C. How can we mesh these two models and where does Java fit in? It was suggested that the conceptual model be used first with the machine level details coming later, as they are needed. For example, most students do not need to know the fine points of floating point numbers unless they take a numerical methods course or otherwise become involved with scientific computing. Others noted though that topics such as non-determinism are difficult to teach using a functional language and that Java represents somewhat of a middle road and provides a meshing of the two models.
Do we know Java well enough to teach it to our first year students? Judith remarked that when she wrote her Pascal book, Pascal had been out for 15 years and she had had a lot of experience teaching it. Authors today are treading in uncharted waters with Java. This is why most beginning programming books using Java look like rewrites of pre- vious beginning programming books. The experience is just not there yet. Authors (and professors) need to recognize that, no matter how the topics are ordered, all that is being offered is a best guess as to how to teach it. Thus, a discussion about whether to start with applets or applications is irrelevant at this point. There is no one right way, rather it is up to the individual instructor. As long as an instructor is enthusiastic about the approach chosen, either can be supported.
Is prior exposure to the object-oriented paradigm essential for students to learn Java? he consensus seemed to be "no". Certainly, if students are already familiar with object-orientation, learning Java is relatively easy. If they are not, Java is still a good vehicle for teaching object-oriented concepts even to non-computer science students.
There must be some drawbacks to using Java; What are they? A number of issues have come up in teaching java, but the panelists agreed that Java itself had a smaller list of catastrophic problems than most other languages. These issues include:
Others talked about the changes to the client server model from AWT version 1.0 to 1.1 and the difficulty this presents in teaching. It was agreed that it is important, however, for students to be exposed to this event handling paradigm.
In contrast, variables of the primitive data types (the six numeric types, a character type and boolean) are treated like variables in C. Assignments copy values, and the value is copied, namely called-by- value, when these variables are passed to a method.
Helping beginning programmers understand the difference between reference-semantic objects and value-semantic variables is non-trivial. Early experience suggests that this is one of the more difficult issues in Java for beginners.
One might argue that everything should be an object in Java, but that would just present a different set of concerns. For instance, if integers were first class objects, then every instance of 7, for example, would be a different object. This would be confusing for beginners as well.