<<

Transactions on Information and Communications Technologies vol 10, © 1995 WIT Press, www.witpress.com, ISSN 1743-3517

A first course in object-oriented programming

using Oberon V. Mahnic, B. Vilfan

Faculty of Electrical Engineering and Computer Science, University of Ljubljana, Trzaska 25, 61000 Ljubljana, Slovenia

Abstract

In the paper we describe the content of a new introductory programming course that attempts to expose students to the object-oriented paradigm in addition to the usual paradigm of procedural programming. Particular attention is devoted to the choice of , and to the teaching methods for object-oriented programming concepts. The use of the Oberon language makes it possible to introduce object-oriented pro- gramming concepts in a simpler way, as extensions of well-known concepts of procedural programming.

1 Introduction

All Computer Science students at the University of Ljubljana take the intro- ductory programming course, Programming I, in their first semester. The course has been based up to now on the course CS 1 [3]. The teaching language has been Pascal while the content of the course included the basic elements of Pascal (basic data types, expressions, statements), procedures, composite types, recursion, and dynamic data types. Experience of the last several years has shown that this course content is not suitable any more, and we have therefore decided to restructure it in a fundamental way.

A more detailed analysis of the reasons that have led us to make this decision is described in Section Two. Section Three is devoted to the choice of programming language for the course, while Section Four contains a more detailed discussion of the dilemmas confronting the course designer with par- ticular emphasis on the appropriate approach for teaching object-oriented programming (OOP).

Transactions on Information and Communications Technologies vol 10, © 1995 WIT Press, www.witpress.com, ISSN 1743-3517

330 Software Engineering in Higher Education

2 Factors that have influenced the change in the course design

In the previous decade the Slovenian secondary school system has succeeded in significantly expanding Computer Science education. As a consequence most entering students had already been exposed to one of the procedu- ral languages, usually Pascal. In spite of the fact that the students had not mastered Pascal completely (the lack of knowledge is particularly evi- dent in the areas offil e processing, set types, dynamic data structures, and recursion), they experience Pascal as a teaching language as a redundant effort. Additionally, it has become evident that secondary school program- ming education has certain adverse consequences that are frequently en- countered in the teaching of procedural languages: An excessive emphasis on syntax and implementation details with a concomitant insufficient em- phasis on the principles of "proper programming" characterized by readabil- ity, clear structure, modularity, etc. (Smallwood [7]). Within the present course we have attempted to alleviate this problem by a greater emphasis on the systematic approach, and on a certain discipline during the program design phase. However, the student's opinion has frequently been that it is a case of unnecessary pedantry on the part of the teacher.

Thus, we have decided to restructure the content of the course with the aim of:

• making the course more attractive for students;

• adapting the content to their previous knowledge;

• stressing the principles of "proper programming";

• including the contemporary programming concepts and paradigms with particular emphasis on OOP.

It emerged that some of the goals would be better served by selecting a new programming language. Although Pascal was not excluded initially we paid special attention to identifying a language that would preserve the advantages of Pascal as a teaching language, and simultaneously be appropriate for the teaching of the new OOP paradigm.

3 The choice of programming language

3.1 Factors influencing the choice The choice of teaching language was made considering 5 criteria for a teach- ing language: availability, teacher knowledge, ease of teaching and learning, language utility, and structure appropriate for problem solving (Woodhouse [9]), as well as software quality criterion: The first programming language that is acquired by students should support the elements of good program- ming style that we wish to impart to them (Burgess & Jones [2]). In that case they are more likely to preserve that style in other languages that may be more prevalent but less appropriate for an introductory course.

Transactions on Information and Communications Technologies vol 10, © 1995 WIT Press, www.witpress.com, ISSN 1743-3517

Software Engineering in Higher Education 331

We have additionally included the criterion of support for OOP, and of continuity between the concepts used in secondary school education and the proposed introductory course.

3.2 The decision to use Oberon We considered four languages for use in our course: Turbo Pascal (extension of standard Pascal with support for modules and separate compilation of modules, as well as with elements of OOP), C++, Smalltalk, and Oberon.

Our choice was Oberon (Reiser & Wirth [6]), a language designed as a suc- cessor of Modula-2. Oberon has all the advantages of Pascal and Modula-2 as teaching languages that are necessary for the teaching of good program- ming style in addition to being inherently object-oriented. Paradoxically, in spite of having an extended functionality due to the addition of object- oriented features, Oberon actually has a more compact syntax than its pre- decessor languages. The object-oriented features of Oberon are introduced as simple extensions of Modula-2 (and Pascal) concepts. In that way the introductory programming course at the university may directly build on the existing foundation of knowledge possessed by the entry-level students. Oberon also satisfies the remaining criteria listed by Woodhouse: It is easily obtainable via anonymous ftp, and there is already a certain amount of local expertise on the language since a group of interested faculty mem- bers has been following the developments around Oberon for some time. Also adequate foreign language literature is available and Slovene literature is in preparation. The other language candidates have been judged less suitable for the following reasons:

• Pascal (with extensions introduced by Turbo Pascal) has two prin- cipal drawbacks: the extensions are non-standard; and they are not joined to the language "seamlessly". This is particularly true for the object-oriented elements. In this respect there is a striking contrast between Oberon, which was designed from scratch with compactness

of definition and object-orientation in mind, and Turbo Pascal, to which additional elements have been added as an afterthought.

• C++ is admittedly widespread in industry, but its syntax is too com- plicated, and it does not support the acquisition of good programming habits. Therefore, it was not judged suitable for a first course in pro- gramming.

• Smalltalk requires a different, more radical approach to the teach- ing of OOP, compared with Oberon, and therefore does not meet the

requirement of building on an existing foundation of knowledge. Be- sides, experience has shown that the approach used by Smalltalk is considered unusual and less comprehensible by students (Mclaughlin & Lovegrove [4], Traxler [8]). Thus, Smalltalk is more appropriate to higher level courses in the context of subjects that deal with the comparison of different programming paradigms and styles.

Transactions on Information and Communications Technologies vol 10, © 1995 WIT Press, www.witpress.com, ISSN 1743-3517

332 Software Engineering in Higher Education

4 Content of the course

In the design of the introductory course we have chosen to combine two programming paradigms: the procedural paradigm, and the object-oriented paradigm. The procedural is the foundation upon which we develop the concepts of object-oriented programming. With regard to the detailed course design, we have encountered two problems:

• Avoiding the pitfalls characteristic of many procedural programming

courses (Smallwood [7]).

• The most efficient integration of OOP concepts into the course.

4.1 Early use of procedures and modules The first problem is relatively easily solvable. Oberon's syntax is extremely simple and easily learnable. Besides this, we rely on the students' previous programming knowledge obtained in their previous schooling. Therefore, we do not devote time to detailed syntax presentation, and to the problems of coding; but rather immediately concentrate on the problem of good pro- gram structure. Since the students are already familiar with the concepts of declarations of constants, types, variables and of control flow, we can concentrate on the concepts of procedure and module. Through the use of more complicated examples, we may illustrate program design principles

(particularly stepwise refinement), and the advantages of using modules (data abstraction).

4.2 Transition from procedural to object-oriented programming The second problem is harder, and to some extent similar to the dilemma be- tween the "purist" and the "pragmatic" approach to the teaching of object- oriented programming (Parsons [5]). In spite the fact that the choice of

Oberon as a teaching language has already made the decision in favour of an incremental (i.e. "pragmatic") approach, we were confronted with a choice between two alternatives, differing in the way the concepts of OOP are introduced. The aforementioned alternatives can be roughly described as follows:

The first alternative

1. Introduce the basic elements of object-oriented thinking.

2. Define the appropriate concepts (i.e., class, object, inheritance ...).

3. Introduce the mechanisms for the implementation of a concept in Oberon.

4. Illustrate the implementation with an example.

5. Repeat steps 4 and 5 until all concepts have been covered.

Transactions on Information and Communications Technologies vol 10, © 1995 WIT Press, www.witpress.com, ISSN 1743-3517

Software Engineering in Higher Education 333

The second alternative

1. Describe extensions of familiar concepts that are used to implement object-oriented programming features (extension of record types, pro- cedure variables).

2. Illustrate the use of the extensions on examples.

3. From the examples abstract the general techniques that permit us

to achieve the goals of OOP: heterogenous data structures, generic modules, dynamic binding of procedures, appropriate module organi- zation.

4. Establish the connection to object-oriented programming terminology.

Within the first alternative, object-oriented concepts are introduced gradually; but it still requires the use of a new jargon immediately from the start of the course. OOP concepts are then introduced one by one, and for each concept the corresponding Oberon mechanism is described together with examples. In this way a student is introduced to a concept in general, and only later to its implementation in a specific language, and to examples of use. In the second alternative we defer the use of typical OO jargon as long as possible. All object-oriented techniques and concepts are explained in terms of concepts already known from procedural programming. We selected the second alternative as we believe that it represents a more natural transition from procedural to object-oriented programming.

4.3 Learning through examples

A smooth transition from procedural to object-orineted programming can be illustrated using the example of a picture editor (for details see [6]). The only new concept that must be introduced is the extension of record types. On the basis of this concept, heterogenous data structures can be defined and later processed by generic modules.

Extension of record types In Oberon a data type may be extended by adding new components to the base type. In the following example the record type CirdeDesc is an extension of the base record type FigureDesc:

TYPE Figure=POINTER TO FigureDesc; FigureDesc=RECORD draw:PROCEDURE(f:Figure); move:PROCEDURE(f:Figure; dx,dy:INTEGER); next:Figure

END; Circle=POINTER TO CircleDesc; CircleDesc=RECORD (Figure) x,y,r:integer END; VAR xO:FigureDesc; xl:CircleDesc; pO:Figure; pi:Circle;

Transactions on Information and Communications Technologies vol 10, © 1995 WIT Press, www.witpress.com, ISSN 1743-3517

334 Software Engineering in Higher Education

Each variable of type CircleDesc has the additional components x, y, and r, besides the original components draw, move, and next. The ex- tended data type CircleDesc is assignment compatible with the base type

FigureDesc, meaning that xO can be assigned the value of xl. The pointers to variables of type Figure and CircleDesc have analo- gous properties. After the execution of the assignment pO:=pl, the pointer pO changes its type dynamically since it now points to a variable of type CircleDesc. Through the type guard mechanism one may also access the components z, y, and r. Thus, pO (Circle).x, pO (Circle).y, and pO (Circle).r denote the components x, y, and r, respectively.

Heterogeneous Data Structures The data type FigureDesc (and the corresponding pointer types) may be extended to the various figures that the picture editor is designed to work with (e.g., lines, rectangles, ellipses, etc.). All elements that we wish to display on the screen are placed on a linked list that is pointed to by the variable

VAR FigList: Figure;

The list elements are possibly of different types; but all are (direct or in- direct) extensions of the same base type, FigureDesc. Each list element is an "object", or in Oberon parlance a record with procedure fields, accessed through pointers.

Generic modules The picture editor operations are implemented within a generic module that executes the operations, independent of the figure type. An example is the procedure Draw All, which creates a drawing of all elements of FigList:

PROCEDURE DrawAll(FigList:Figure);

VAR f:Figure; BEGIN f:=FigList; WHILE f # NIL DO f.draw(f); f:=f.next END END DrawAll;

Figure modules Operations which arefigure-specifi car e usually placed in a separate module. Thus we need as many separate modules as there are different figure types. The task of each figure-specific module is to:

• extend the base type Figure with figure-specific data;

• declare procedures for drawing, moving, etc.

• declare a procedure for the creation of a new element of the type being declared.

As an example we describe the definition of the Circles module:

Transactions on Information and Communications Technologies vol 10, © 1995 WIT Press, www.witpress.com, ISSN 1743-3517

Software Engineering in Higher Education 335

DEFINITION Circles; IMPORT Graphics; (* generic module *) TYPE

Circle=POINTER TO CircleDesc; CircleDesc=RECORD(Graphics.FigureDesc) x,y,r:INTEGER END; PROCEDURE Draw(r:Graphics.Figure);

PROCEDURE Move(r:Graphics.Figure; dx,dy:INTEGER); PROCEDURE New():Graphics.Figure; END Circles.

Dynamic binding of procedures At the time of the compilation of the generic module, the does not know, which procedure is to be called for the drawing of a figure. It only knows that its address is the value of the component draw belonging to a procedure type (see the declaration of

FigureDesc). The actual value will become known at the time of creation of a new element of FigList. If the new element is a circle, the latter operation is performed by the procedure New within Circles:

PROCEDURE New():Graphics.Figure; VAR c:Circle; BEGIN

NEW(c); c.draw:=Draw; (* initialization of procedure field draw *)

(* initialization of other fields *)

END New;

Advantages The foregoing example not only illustrates object-oriented programming in Oberon, but also the advantages of this approach: the isolation of different concerns in different modules. Most importantly, ad- ditional shape modules can be added without recompilation of any of the parts of the system. Through redefinitions of some methods, further spe- cializations of the object can often be obtained by reusing existing code.

5 Conclusion

The decision to restructure our existing introductory programming course at the University of Ljubljana was made due to advances in the level of knowledge of Computer Science entering students, as well as the desire to incorporate object-oriented material into the course.

We decided to incorporate into our course both, the procedural pro- gramming paradigm, and the object-oriented paradigm. As the teaching language we selected Oberon because it permits an easy transition from procedural programming to OOP. OOP concepts can be introduced as ex- tensions of familiar procedural programming concepts, which is more suit- able for beginners.

Transactions on Information and Communications Technologies vol 10, © 1995 WIT Press, www.witpress.com, ISSN 1743-3517

336 Software Engineering in Higher Education

The restructured introductory programming course will consist of three parts. The first part is devoted to the basics of the Oberon language. Because of its similarity to Pascal that the students are assumed to be familiar with, the firstpar t may be shortened to two weeks. The second part, lasting 6 weeks, deals with procedures and modules, composite data types and dynamic data types. Emphasis is given to the design of larger programs with the techniques of stepwise refinement and data hiding. The third part, also lasting 6 weeks, concentrates on obect-oriented programming. In this part of the course, the students are exposed to OOP techniques through practical examples along the general lines described in Section 4.

References

1. Budd, T. Introduction to object-oriented programming, Addison-Wesley, 1991.

2. Burgess, C.J. & Jones, B.F. Should software quality be a major issue when teaching firstyea r programming to software engineers?, in Software

Engineering in Higher Education (ed G. King, C.A. Brebbia, M. Ross & G. Staples), CM Publications, Southampton, 1994, pp. 75-81.

3. Curriculum '78: Recommendations for the Undergraduate Program in Computer Science. Comm. /ICM, 22, 3 (March 1979), 147-166.

4. Mclaughlin, P. & Lovegrove, G. Issues in teaching object technology to joint honours undergraduates, in Software Engineering in Higher Educa- tion (ed G. King, C.A. Brebbia, M. Ross & G. Staples), Computational Mechanics Publications, Southampton, 1994, pp. 359-366.

5. Parsons, D. Pragmatism over purism? An incremental approach to teach- ing of object-oriented programming, in Software Engineering in Higher Education (ed G. King, C.A. Brebbia, M. Ross & G. Staples), Compu-

tational Mechanics Publications, Southampton, 1994, pp. 375-382. 6. Reiser, M. & Wirth, N. Programming in Oberon, steps beyond Pascal and

Modula, Addison-Wesley, 1992.

7. Smallwood, D.R. On teaching the procedural programming paradigm: revisited, in Software Engineering in Higher Education (ed G. King, C.A. Brebbia, M. Ross & G. Staples), Computational Mechanics Publications, Southampton, 1994, pp. 259-266.

8. Traxler, J. Choosing languages to teach programming paradigms and programming styles, , in Software Engineering in Higher Education (ed G. King, C.A. Brebbia, M. Ross & G. Staples), Computational Mechanics Publications, Southampton, 1994, pp. 291-298.

9. Woodhouse, D. Introductory courses in computing: aims and languages. Compeer Edwcofwn, Vol. 7, No. 2, 1983, pp. 79-89.