Innovative Courseware Development with Mosaic and WWW
Dr. Rajiv Tewari
Temple University
Philadelphia, PA 19122
ABSTRACT
The recent explosion of interest in the World Wide Web (WWW) has sparked
a number of efforts to build courseware modules for distance or remote
learning allowing students to take courses anytime, anywhere using a PC and a
publicly available WWW browser such as Mosaic, Lynx, Cello, WinWeb or tkWWW
The ability to offer courses has been enhanced by the Common Gateway Interface
(CGI) and forms support provided by newer releases of Mosaic. Examples of
courseware modules developed include the Globewide Network Academy's C++ course,
a WWW Algorithm Animation course at University of Geneva, and the W3Kit
Object Library for Interactive WWW applications.
There are several issues unique to developing WWW based courseware. Some
of the problems such as precise placement of text, tables and mathematical
equations are already being addresses by HTML+. In our work we are looking
at the fundamental issue of designing a course that lends itself to the
hypertext browsing metaphor inherent in Mosaic. Courseware authors can
design a course web using structured techniques that essentially present
information hierarchically, or think along more object-oriented design (OOD)
techniques that use a layered model of encapsulating both data and
procedures in the form of objects that are related to the concepts prevalent
in the subject domain of the course being designed. We are using an OOD
approach to design a course to teach object-oriented programming using Ada 9X
through a WWW based courseware module.
Changes in Ada 9X
Ada 9X is the result of several years of work by members
of the international Ada users community, to revise the Ada 83
standard, and provide enhancements in the following areas:
- Object-Oriented Programming
- Programming in the Large and Software Engineering
- Real-Time and Parallel Programming
In this paper, we will be primarily concerned about the object-oriented
programming enhancements in Ada 9X. Ada 83 is an object-based language
since it provides the notion of objects, but not the facilities of
inheritance and run-time polymorphism.
Ada 83 has a facility for defining
Abstract Data Types (ADT's) and defining a new type as a derivative of
an existing type. For Ada 9X, this capability is generalized by allowing
private and record types to be extended with additional components.
For example (Tucker, 1993), in Ada 9X, we can allow new components to
be defined as part of a type derivation:
type Basic_Window is tagged limited private;
type Fancy_Window is new Basic_Window
with record
Border_Width : Pixel_Count := 1;
Border_Color : Color := Black;
end record;
In the declaration of the new type Fancy_Window, we have all the components
of a Basic_Window, plus two additional components to allow more control
over the appearance of the border. This enhancement of derived types is
sufficient to provide support for the concept of inheritance.
However, derived types with extensions are not sufficient to provide
run-time polymorphism in Ada 9X. The property of run-time polymorphism is
provided by using the concept of "universal" types and type classes.
The concept of class refers to any set of types that are formed from the
direct and indirect derivatives of a given type.
Thus Ada 9X adds type extension, late binding and polymorphism to Ada 83
providing greater flexibility while retaining the strong typing of Ada 83.
Inheritance through Type Extension
An extensible record is marked tagged since it contains a hidden component.
The tag is used at run-time for type discrimination. Consider the following
example of a public transportation system using buses. The package declares
a type Bus with some components common to all buses, and a number of
procedures operating on objects of type Bus such as Print_Details.
package Transport is
type Bus is tagged
record
Engine: Engine_Class;
Weight: Integer;
-- other components
end record
procedure Print_Details(T: Bus);
-- other procedures
end Transport
We can use type extension to create a new type of Bus, called a Luxury_Coach
as follows:
type Luxury_Coach is new Bus with
record
Passenger_Capacity: Integer;
Air_Conditioning: Boolean;
Rest_Room: Integer;
end record;
type Transport_Bus is new Bus with
record
Seats: Integer;
end record;
procedure Print_Details(T: Luxury_Coach);
procedure Print_Details(T: Transport_Bus);
The overloaded procedure Print_Details will use the existing version of
the parent type Bus to print the common details of Luxury_Coach and
Transport_Bus by calling the Print_Details function of the parent type.
Late Binding and Polymorphism
Polymorphism in Ada 9X is achieved through the facility of class-wide
programming. This allows programs to have dynamic facilities thereby
allowing the manipulation of of a family of types that are derived
from a common base type. Each tagged type T has a class-wide type
T'Class, and the possible values of T'Class are all values of T plus
all its derived types. This allows us to create a general procedure
as follows:
procedure Analyze(B: Bus'Class) is
begin
Print_Details(T); -- execute relevant procedure based on tag
end Analyze;
The call to Print_Details in the above examples illustrates dispatching
based on the tag type at run-time. The run-time system determines the
specific type to which T belongs at the time of execution, not at the
time of compilation. Hence, T could be a Luxury_Coach or a Transport_Bus,
or even a new type derived from Bus that is not yet declared. The value
of T includes a tag indicating the specific type to which it belongs, and
the choice of which Print_Details to execute is based on the value of the
tag at run-time. The selection of which procedure to execute at run-time
is called dispatching, which is an example of late binding. Class-wide
type are polymorphic because they include a number of specific types.
Encapsulation and Abstraction
One of the key tenets of the OOP approach is to be able to extend
an existing system by adding new types, without having to
recompile and test existing software components. The component based
approach to software development holds good promise for systematic
software reuse, and is a goal of languages like Ada. Abstract base
types can be created that contain the common properties of a group
of entities, and then this abstract base type can be extended to
create new types that are required by the system designer. This
technique can be used to implement type hierarchies that are
equivalent to C++ class libraries.
Objects of an abstract type cannot be instantiated. It is important to note that
abstract base types are not useful by themselves, but are useful only in
the context of providing a foundation for building other useful concrete
types for a particular application.
Object-Oriented Programming
The main facilities provided by the Ada 9X language to support OOP are
(Ada 9X Rationale, 1994):
- Record types that are marked as tagged may be extended with
additional components on derivation.
- The class attribute may be applied to a tagged type and denotes
the corresponding class-wide type.
- Subprogram calls with formal parameters of a specific type called
with actual parameters of a class-wide type or a dispatching
call.
- Types and subprograms may be specified as abstract.
- There are various new forms of generic parameters corresponding
to derived and tagged types.
Typically, an object-oriented design technique or language provides at least
three constructs. The first construct is that of an object that
represent entities that have behavior and state information associated
with them. The second is encapsulation that implies the capability
of information hiding and abstraction of data and behavior of an object.
Encapsulation results in a separation of the interface and the
implementation of a software component. The third construct is that
of inheritance. These three constructs together with the facilities
of late binding and polymorphism, provide an environment that allows
OOP and OOD. The Ada 9X requirements reflect the need to provide
improved support for the OOP paradigm through three study topics:
- Subprograms as Objects: Ada 9X should provide a mechanism for
dynamically selecting a subprogram that is to be called with
a given argument list, and should also provide a means of
separating the set of subprograms that can be selected
dynamically from the code that makes the selection.
- Reducing the Need for Recompilation: the recompilation and
related rules should be revised to minimize the need for
recompilation.
- Programming for Specialization/Extension: the language should
make it possible to define new declared entities whose
properties are adapted from those of existing entities by
the addition of modification of properties. This should be done
in such a way that the original entity's definition and
implementation do not need to be modified, and the new entity
can be used anywhere the original one could be.
The essence of OOP in the context of Ada 9X is therefore summarized by
the following two aspects:
- Variant Programming: New abstractions may be constructed from
existing ones such that the programmer need only specify the
differences between the old and new abstractions.
- Class-wide Programming: Classes of related abstractions may be
handled in a unified fashion such that the programmer may
systematically ignore their differences when appropriate.
In addition to the above, there are two additional problems to be
addresses for retaining efficiency and avoiding unnecessary run-time
overhead. These are dispatching and multiple inheritance.
Example of OOP in Ada 9X
A tagged record or private type may be extended with additional components
when a new type is deived from the base type. Tagged objects are
self-identifying because their tag indicates their specific type. Tagged
types enable single inheritance similar to the Smalltalk and Simula
language facilities. The following example clarifies these concepts:
type Account is tagged
record
Identity: Account_Number := None;
Balance: Money := 0.00;
Rate: Interest_Rate := 0.05;
Interest: Money := 0.00;
end record
procedure Accrue_Interest(On_Account: in out Account;
Over_Time in Integer);
procedure Deduct_Charges(From: in out Account);
With the above language statements, we can now create type extensions:
type Free_Checking_Account is new Account with
record
Minimum_Balance: Money := 500.00;
Transactions: Natural := 0;
end record
procedure Deposit(Into: in out Free_Checking_Account;
Amount: in Money);
procedure Withdraw(From: in out Free_Checking_Account;
Amount: in Money);
procedure Deduct_Charges(From: in out Free_Checking_Account);
The type Account is a tagged type. The type Free_Checking_Account is derived
from Account, and therefore inherits copies of its state components, as well
as its operations. The derived type declaration has a record extension part
that adds two components, and also adds two new operations for Deposit and
Withdrawal transactions. The derived type declaration also overrides the
procedure Deduct_Charges originally defined in the base type declaration.
Class Wide Types and Operations
A record or private type marked as tagged may be extended on derivation
with additional components. The run-time tag identifies information that
allows class-wide operations on the class-wide type to allocate, copy,
and perform other operations allowed on objects of the class wide type.
An example of class-wide types is described in (Ada 9X Rationale, 1994).
The root type Alert
has the primitive operations
Display, Handle and Log
. These are inherited and/or
overridden by the derived types Low_Alert, Medium_Alert,
High_Alert
. Low_Alert
inherits the three primitive
operations without any changes, Medium_Alert
inherits all
three from Alert
but overrides Handle
,
while High_Alert
inherits from Medium_Alert
and overrides Handle
while adding Set_Alarm
.
This example illustrates the facility for selectively overriding
procedures that have been defined in root types, thereby allowing
the construction of software components from hierarchical component
libraries.
Advantages of the Ada 9X OOP Approach
In summary, the approach to extending Ada 83
for adding OOP functionality,
has the following advantages:
- Compatibility: This implies that legal Ada 83 programs should continue
to work with newer Ada 9X compilers.
- Consistency: The new Ada 9X compilers should be conceptually consistent
with existing Ada programming models. The accepted meaning of
objects, types, subprograms, generic units and other constructs
should be preserved.
- Efficiency: The new standard should offer efficient performance for users
of the language, with little or no distributed overhead for non-users
of the new facilities.
- Ease of Implementation: The solution should be readily implementable using
current compiler technology, and provide opportunities for
optimizations.
References
- Object-Oriented Software Engineering in the Introductory Computer
Science Curriculum, F.L. Friedman and R. Tewari, ACM OOPSLA '92
Educators Symposium, October 1992, pages 1-11.
- Integrating Object-Oriented Software Engineering in the Undergraduate
Curriculum, R. Tewari and F.L. Friedman, 6th SEI Conference on Software
Engineering Education, Lecture Notes in Computer Science 640, published by
Springer-Verlag, San Diego, CA, October 1992, pages 270-283.
- A Framework for Incorporating Object-Oriented Software Engineering
in the Undergraduate Curriculum, R. Tewari and F.L. Friedman, Computer
Science Education, Volume 4, 1993, pp. 45-62.
- On Object-Oriented Libraries in the Undergraduate Curriculum: Importance
and Effectiveness, R. Tewari and D. Gitlin, Proceedings of the 25th ACM SIGCSE
Technical Symposium on Computer Science Education, Vol. 26, No. 1, March 1994.
- Object-Oriented Programming in Ada 9X, J. Barnes, Alsys World Dialogue,
Spring 1993.
- Ada 9X -- A Technical Summary, S. Tucker Taft, Ada 9X Mapping/Revision
Team, Intermetrics Inc., 1993.
- Ada 9X Rationale -- The Language and The Standard Libraries, Draft Version
5.0, 8 June 1994, Intermetrics Inc.
- Ada 9X Reference Manual, Draft Version 5.0, 1 June 1994,
Intermetrics Inc.
- Ada 9X: From Abstraction-Oriented to Object-Oriented, S. Tucker Taft,
Proceedings of OOPSLA Conference, 1993, pp. 127-135.
Biography of Dr. Rajiv Tewari
Dr. Tewari received his Ph.D. (Computer Information Systems) in 1990,
from Rutgers University. He is an Assistant Professor of Computer and
Information Sciences at Temple University. He is currently
conducting research on innovative instructional methodologies for introducing
object-oriented programming concepts at an early stage in the introductory
curriculum, and also the effects of the object-oriented paradigm and Ada 9X
in a software engineering course.
Dr. Tewari is very optimistic about the educational potential of WWW and Mosaic,
and is actively engaged in developing WWW based courseware. He is the
co-principal investigator of an NSF grant for course and curriculum development
for incorporating object-oriented concepts in the undergraduate programming
course sequence, and is also the co-principal investigator
for an NSF Instrumentation and laboratory Improvement grant on the same
topic. He was the PI for a grant from Sun Microsystems Inc. for 1992-93
for related work. He received the Eli Lilly Foundation
Teaching Fellows award for 1993-94 for teaching excellence.
Dr. Tewari has taught courses in the areas of programming in Pascal,
C and C++, Ada, data structures, database management, and object-oriented
computing. He was an invited panel member on the panel on object-orientation
in the computer science curriculum at the ACM OOPSLA'92 conference held at
Vancouver, B.C. He has published more than thirty papers related to
software engineering and distributed computing in refereed IEEE
and ACM journals and conferences.
E-mail: tewari@trek.cis.temple.edu