NETB131 Programming Project
Programming language MODULA 3
An overview


Gerasim Trifonov Trifonov, F40483


1. History

Modula-3 is a programming language conceived as a successor to an upgraded version of Modula-2. It appeared in 1980s. While it has been influential in research circles (influencing the designs of languages such as Java and C#), it has not been adopted widely in the industry. It was designed by Luca Cardelli, Jim Donahue, Mick Jordan, Bill Kalsow and Greg Nelson at the Digital Equipment Corporation (DEC) Systems Research Center (SRC) and Olivetti in the late 1980s. Its design was heavily influenced by work on the Modula-2+ language in use at SRC at the time, which was the language in which the operating system for the DEC Firefly multiprocessor VAX workstation was written. As the revised Modula-3 Report states, the language was also influenced by other languages such as Mesa, Cedar, Object Pascal, Oberon and Euclid[1].

Modula-3's main features are simplicity and safety while preserving the power of a systems-programming language. Modula-3 aimed to continue the Pascal tradition of type safety, while introducing new constructs for practical real-world programming. In particular Modula-3 added support for generic programming (similar to templates), multithreading, exception handling, garbage collection, object-oriented programming, partial revelation and encapsulation of unsafe code. The design goal of Modula-3 was a language that implements the most important features of modern imperative languages in quite basic forms. Thus allegedly dangerous and complicating features like multiple inheritance and operator overloading were omitted.

2. "HELLO WORLD" Program


MODULE Main;
IMPORT IO;
BEGIN
 IO.Put ("Hello World\n")
END Main.



3. Fundamental Data Types (integer, floating point, string) and Assignment Operator Definitions:


VAR    
n    : INTEGER      := -15;                (* INTEGER *)
x    : REAL           := 3.0;                  (* REAL *)
str  : TEXT           := "Test";              (* TEXT *)



Assignment Statements

<v> ":=" <e>

Sets <v> to the value of <e>. <v> must be a writable designator (generally, a variable or non-READONLY procedure parameter).

INC "(" x { "," n} ")"
DEC "(" x { "," n} ")"

These are shortcuts for x := x + n and x := x - n, respectively. If omitted, n defaults to 1. x must be an ordinal value (INTEGER, CHAR, or enumerated value). n must be an integer expression. Some examples are in order;

intvar := 53;   
DEC(intvar);     (* intvar = 52 *)

charvar := 'a';
INC(charvar, 3); (* charvar = 'd' *)


4. Basic Control Flow (conditional and loop statements) Conditional operator:  write program

IF Statement

IF <expr> THEN <stmts> { ELSIF <expr> THEN <stmts> ... }
[ ELSE <stmts> ] END

<expr> must be a boolean-valued expression. Here is an example:


IF Text.Equal(txt,"Strawberry") THEN
  IO.Put("Not bad")
ELSIF Text.Equal(txt,"Avacado") THEN
  IO.Put("Yuck!")
ELSIF Text.Equal(txt,"Chocolate") THEN
  IO.Put("Yum")
ELSE
  IO.Put("Nah.")
END


WHILE Statement

WHILE <expr> DO <stmts> END

<expr> must be a boolean-valued expression. <stmts> are executed until <expr> becomes FALSE. If <expr> is FALSE at the start <stmts> are not executed at all.


MODULE Main;      
IMPORT IO;        
VAR num: INTEGER;   
VAR sum: INTEGER := 0;
VAR i: INTEGER := 0;

BEGIN                                     
  IO.Put("Enter number: ");            
  num := IO.GetLine();                   
  IF num < 0 THEN END;
  WHILE (i <= num) {sum = sum +  i*i};
IO.Put("Result is: " & sum & "\n");
END Main.         




5. Functions - syntax, writing and using functions, example

A procedure call has the form:
    P(Bindings)
where P is a procedure-valued expression and Bindings is a list of keyword or positional bindings. A keyword binding has the form name := actual, where actual is an expression and name is an identifier. A positional binding has the form actual, where actual is an expression. When keyword and positional bindings are mixed in a call, the positional bindings must precede the keyword bindings. If the list of bindings is empty, the parentheses are still required.

Each parameter that has a default and is not bound after the first step, the binding name := default is added to the list of bindings, where name is the name of the parameter and default is its default value. The rewritten list of bindings must bind only formal parameters and must bind each formal parameter exactly once. For example, suppose that the type of P is
    PROCEDURE(ch: CHAR; n: INTEGER := 0)
Then the following calls are all equivalent:
    P('a', 0)
    P('a')
    P(ch := 'a')
    P(n := 0, ch := 'a')
    P('a', n := 0)
The call P() is illegal, since it doesn't bind ch. The call P(n := 0, 'a') is illegal, since it has a keyword parameter before a positional parameter.

A procedure call is an expression if the procedure returns a result. The type of the expression is the result type of the procedure.
PROCEDURE <id> <sig> "="
  <decls>
  BEGIN
    <stmts>
  END <id> ";"

A procedure declaration is composed of an identifier, a signature (see section Procedure Types), optional local declarations, and statements. The identifier <id> at the end of the procedure must match the id at the beginning. Declarations made in a procedure are local to the procedure: they exist only while the procedure is executing.

If the procedure signature specifies a result type, the procedure is called a function procedure, and it must include a RETURN statement which returns an expression of the specified type. It is a checked runtime error for a function procedure to fail to return a result.


PROCEDURE Max(a, b: INTEGER): INTEGER =
(* Sample function definition. *)
VAR max: INTEGER;
BEGIN
   max := a;
   IF a < b THEN max := b END;
   RETURN max;
END Max;




6. Arrays - syntax, definition, example

Array Types

ARRAY { <indextype> "," ... } OF <slottype> ";"

<indextype> must be an ordinal type (see section Ordinal Types). The common case is an integer subrange such as [1..numslots], but Modula-3 programs frequently use user-defined enumerations as well.

<slottype> can be any Modula-3 type, even another array.

Here are some examples of array types:

TYPE
  OneDimArray  = ARRAY [1..20] OF REAL;
  OneDimArray2 = ARRAY ['A'..'Z'] OF INTEGER;
  TwoDimArray  = ARRAY [1..20], [1..40] OF BOOLEAN;
  TwoDimArray2 = ARRAY [1..20] OF ARRAY [1..40] OF BOOLEAN;

The built-in functions FIRST, LAST, and NUMBER can be used with array types and variables to return the index of the first and last slot and number of slots, respectively. For example, FIRST(OneDimArray) = 1; NUMBER(OneDimArray2) = 26.

Example program using arrays


MODULE Main;
IMPORT Wr, Fmt, Stdio;
IMPORT Text;
CONST
A = ARRAY [1...6] OF Text.T {
"FORTRAN", "ALGOL", "LISP", "COBOL", "APL", "SNOBOL"
};
VAR
sum :=0;
BEGIN
FOR i:= FIRST(A) TO LAST(A) DO
sum := sum + Text.Length (A[i]);
END;
Wr.PutText (Stdio.stdout, "The total length is " & Fmt.Int (sum) & " .\n");
END Main.



7. Compilers



8. Projects and Software in Modula 3

A number of programming teams selected Modula-3 for industrial and
research projects, and for teaching. It encourages good programming
practices and comes with excellent libraries for distributed
programming and graphical user interfaces.

The SPIN (operating system) was implemented using Modula-3 as its programming language.
The CVSup repository synchronization program was implemented in Modula-3.

9. Standard

The standard was defined in 1989. Twelve changes were made in Modula 3 in the year 1990.
http://www.hpl.hp.com/techreports/Compaq-DEC/SRC-RR-52.pdf



10. Refernces

http://en.wikipedia.org/wiki/Modula-3
http://www1.cs.columbia.edu/graphics/modula3/tutorial/www/m3_toc.html#SEC24
http://www.cs.purdue.edu/homes/hosking/m3/reference/ordinal.html#idx.34
www.faqs.org/faqs/Modula-3-faq/