Specification of the ADT "simple list of integers" and implementation in a Pascal-like language.

Specification

In an abstract sense, a list is a sequence of "nodes", where each node contains an information (an integer number in this case). "Simple" here means that the only operations of the ADT are: The type of each operation (interface) is specified as follows: where f: () -> T means that f has 0 arguments and result of type T, f: (T1) -> T2 means that f has 1 argument of type T1 and result of type T2, etc.

Implementation

The implementation of an ADT consists of two parts:

Representation of lists

One possible approach to the concrete representation of lists is by using records and pointers.
   type list = ^element;
        element = record
                    info : integer;
                    next = list
                  end;

Definition of the operations

   function emptylist : list;
      begin 
      emptylist := nil
      end;


   function is_empty(L:list): boolean;
      begin
      if L = nil then is_empty := true else is_empty := false
      end;


   function cons(x:integer, L:list): list;
      var aux : list;
      begin
      new(aux);
      aux^.info := x; 
      aux^.next := L;
      cons := aux
      end;


   function head(L:list): integer;
      begin
      if L = nil 
         then head := 0 /* error */
         else head := L^.info
      end; 


   function tail(L:list): list;
      begin
      if L = nil 
         then tail := nil /* error */
         else begin
              tail := L^.next;
              dispose(L)
              end
      end; 

Using the ADT "simple list"

A correct use of the ADT should use only the operations of the interface, i.e. emptylist, isempty, cons, head and tail. For instance, consider below two possible definitions of the append function: The first respect this principle, the second doesn't. Of course, if the language offered a mechanism to protect the ADT, the second could not even be written.

"Good" append (implementation-independent)

   function append(L1,L2:list): list
      begin
      if is_empty(L1)
         then append := L2
         else append := cons(head(L1),append(tail(L1),L2))
      end;

"Bad" append (implementation-dependent)

   function append(L1,L2:list): list
      begin
      if L1 = nil 
         then append := L2
         else append := cons(L1^.info,append(L1^.next, L2))
      end;