CSE130 LECTURE NOTES

May 8, 2002
 
 

ADMINISTRATION

The third assignment is now available.  This is a team project, with due date Friday May 24.

Reminder: The midterm will be in class, on Monday May 20.  The midterm is intended mainly as practice for the final exam, which will be on Monday June 10, from 7pm to 10pm.
 
 

IMPERATIVE PROGRAMMING REVISITED

Today we will look at object-oriented programming from the point of view of trying to understand it in terms of programming language concepts that we know already.  We will compare OOP to abstract data types.  However first we will look again at imperative versus functional programming.

Updatable variables and assignment commands are the essence of imperative programming.  There are two basic reasons for using variables: (1) to remember intermediate results (2) to keep track of things changing in the outside world.

The second use of updatable variables is much more fundamental.  If you think of a software module as simulating something in the
real world, e.g. a database system simulates the population of UCSD students, then it is very natural to update variables as events
happen in the real world, e.g. a student adds a class.

In object-oriented programming, an object is a generalization of a variable as used to model something in the outside world that can change.
 
 

USING VARIABLES TO REMEMBER TEMPORARY RESULTS CAN BE AVOIDED

Consider this version of the factorial function:
function fact (n: integer): integer;
    var temp: integer;
begin
    if n = 0 then temp := 1
    else
        begin
            temp := n-1;
            temp := fact(temp);
            temp := n*temp
        end;
    return temp
end;
Is using updatable variables to remember intermediate results really necessary? The answer is no, because using nested
expressions, the programmer can let the compiler take care of computing intermediate results in the right order:
function fact (n: integer): integer;
begin
    return ifthenelse( n=0, 1, n*fact(n-1) )
end;
Temporary variables are inessential.
 
 

WHAT IS AN OBJECT?

Remember the second, most important, use for updatable variables: to keep track of things changing in the outside world.

If you think of a software module as simulating something in the real world, e.g. a database system simulates the population of UCSD students, then it is very natural to update variables as events happen in the real world, e.g. a student adds a class.

In object-oriented programming, an object is a generalization of a variable as used to model an entity in the outside world.

Definition: An object is a variable with implementation-independence.

The idea of "representation-independence" is a special case of "implementation-independence", which is an idea that can apply to types, to variables, constants, functions, procedures, and more.

In modeling a real-world entity, what is important is that the model should behave like the entity being modelled, not the details of how the model is implemented.

An object contains data, called its state or private variables, and it has operations that can update its private variables called methods.  Methods are sometimes called member functions.

A class is a type of objects. We say that an object is an instance of a class.  The operations of an object typically have side-effects, so they are not pure functions.

Objects are thought of as active individuals rather than passive values.  Invoking an operation of an object is called sending a message.

Therefore, instead of writing x := plus(x,y) we write send x "add y" for example.  This calls the add method of the object named x. Every method has an unwritten (implicit) first argument, which is the object itself.
 
 

CLASSES COMPARED TO ABSTRACT DATA TYPES

The definition of a class looks similar to the implementation of an ADT, but no separate signature or specification is given.
class financial-history =
begin
    state cash, receipts, expenses
    method init = cash := 0; receipts := []; expenses := [];
    method receive (amount) = receipts := amount :: receipts; cash := cash + amount;
    method spend (amount) = expenses := amount :: expenses; cash := cash - amount;
    method cash? () = return cash;
end;
Individual objects can be declared in the same way as variables:
var myaccount: financial-history;
A class introduces a collection of operations which are imperative.  Methods modify objects which have an internal, updatable state.

In contrast, an ADT introduces a new type. Any operation on a value of the new type must take the value as an input parameter.  With a pure ADT, there are no operations that modify values of the type.  Instead, some operations can generate fresh, new values of the type.

 

RESTRICTED IMPERATIVE UPDATING

A type is pure if variables having the type cannot be updated in any way, i.e. no assignment commands are available for this type.  In functional programming, all types are pure.

Errors are very likely with unlimited direct updating of composite variables.  Consider what happens with the following procedure
if the user gives an address with less than 5 lines:

const length = 5;
type address = array [1..length] of string;

procedure update (a: address);
    var j: integer := 1; s: string;
begin
    while (j <= length) and not eof(input) do
    begin
        readln(s);
        a[j] := s;
        j := j+1
    end
end;

Classes are typically not pure, because objects can be updated, i.e. modified.  However programming with objects is still safer than programming with regular composite types, because updating can only be done through predefined methods.
 
 



Copyright (c) by Charles Elkan, 2002.