© Kenneth C. Louden, 2003 1
Chapter 1 - IntroductionChapter 1 - Introduction
Programming Languages:
Principles and Practice, 2nd Ed.
Kenneth C. Louden
Chapter 1 K. Louden, Programming Languages 2
What is a Programming What is a Programming Language?Language?
Definition: A programming language is a notational system for describing computation in machine-readable and human-readable form.
Chapter 1 K. Louden, Programming Languages 3
Computation:Computation:
Described by a Turing Machine - a very simple computer that can carry out all known computations (albeit not very efficiently).
A programming language is Turing complete if it can be used to describe any computation performed by a Turing Machine.
Chapter 1 K. Louden, Programming Languages 4
What is needed for Turing What is needed for Turing completeness?completeness?Virtually nothing:
– A programming language is Turing complete provided it has integer variables and arithmetic and sequentially executes statements, which include assignment, selection (if) and loop (while) statements.
Even if statements are unnecessary (see exercises).
Chapter 1 K. Louden, Programming Languages 5
Machine-readability:Machine-readability:
Also not a huge requirement:Basically, the existence of a (more or less) linear-time translation algorithm.
Usually boils down to:The syntax must be given by a context-free grammar. (See Chapter 4.)
Chapter 1 K. Louden, Programming Languages 6
Human-readability:Human-readability:
This is the real issue!Virtually all the complex details of a
programming language are there to (supposedly) enhance human readability.
Still not very well understood.Is strongly dependent on good
choice of abstractions.
Chapter 1 K. Louden, Programming Languages 7
What about human “writability??”What about human “writability??”
Aren’t programming languages there to promote the writing of programs, not the reading of them?
Nonsense! Writability is a hacker’s goal: Perl is very writable, but try to read it!
Readability is the real goal: many people are going to have to read your program after you have written it.
Chapter 1 K. Louden, Programming Languages 8
Abstractions:Abstractions:
Simple Structured Unit
Data int, char
class, struct
file, package, API, ADT
Control goto, =
if { } else { }, while { }, procedure
file, package, API, ADT
Chapter 1 K. Louden, Programming Languages 9
Language Paradigms:Language Paradigms: Imperative (procedural): traditional
sequential programming (passive data, active control). Characterized by variables, assignment, and loops.
Object-oriented: data-centric, data controls its own use, action by request to data objects. Characterized by messages, instance variables, and protection.
Functional: passive data, but no sequential control; all action by function evaluation (“call”), particularly recursion. No variables!
Chapter 1 K. Louden, Programming Languages 10
Language Paradigms (cont.):Language Paradigms (cont.):Logic: Assertions are the basic data;
logic inference the basic control. Again, no sequential operation.
Parallel: well, maybe not really a paradigm, but some think so. Again, no sequential operation.
“Declarative”: Logic and functional paradigms share this property: state “what” needs computing, not “how” (sequence).
Chapter 1 K. Louden, Programming Languages 11
Languages and paradigmsLanguages and paradigms
Imperative: C, Pascal, core Ada, FORTRAN
Functional: Lisp (Scheme), ML, Haskell
Object-oriented: C++, Java, Smalltalk
Logic: Prolog
Parallel: Java (threads), Ada (tasks)
Chapter 1 K. Louden, Programming Languages 12
Are functional languages Turing-Are functional languages Turing-complete?complete? Previous theorem on Turing-completeness
(slide 4) depends on the existence of variables and loops.
Functional programs do not have variables or loops. Can all computation be expressed?
Yes!:– A programming language is Turing complete if it has
integer values, arithmetic functions on those values, and if it has a mechanism for defining new functions using existing functions, selection, and recursion.
Chapter 1 K. Louden, Programming Languages 13
Examples in three languages Examples in three languages (Euclid’s gcd algorithm):(Euclid’s gcd algorithm):
Compute the greatest common divisor of Compute the greatest common divisor of two integers input by the user, and print two integers input by the user, and print the result. For example, the gcd of 15 the result. For example, the gcd of 15 and 10 is 5.and 10 is 5.
Chapter 1 K. Louden, Programming Languages 14
C (Figure 1.7, p. 26):C (Figure 1.7, p. 26):#include <stdio.h>
int gcd(int u, int v) /* “functional” version */
{ if (v == 0) return u;
else return gcd (v, u % v); /* “tail” recursion */
}
main() /* I/O driver */
{ int x, y;
printf("Input two integers:\n");
scanf("%d%d",&x,&y);
printf("The gcd of %d and %d is %d\n",
x,y,gcd(x,y));
return 0;
}
Chapter 1 K. Louden, Programming Languages 15
Java (Figure 1.9, p. 27):Java (Figure 1.9, p. 27):import java.io.*;
class IntWithGcd
{ public IntWithGcd( int val ) { value = val; }
public int getValue() { return value; }
public int gcd ( int v )
{ int z = value; /* “imperative” version */
int y = v;
while ( y != 0 )
{ int t = y; y = z % y; z = t;
}
return z;
}
private int value;
}
Chapter 1 K. Louden, Programming Languages 16
Java (continued):Java (continued):class GcdProg /* driver */
{ public static void main (String args[])
{ System.out.println("Input two integers:");
BufferedReader in = new BufferedReader(
new InputStreamReader(System.in));
try /* must handle I/O exceptions */
{ IntWithGcd x = /* create an object */
new IntWithGcd(Integer.parseInt(in.readLine()));
int y = Integer.parseInt(in.readLine());
System.out.print("The gcd of " + x.getValue()
+ " and " + y + " is ");
System.out.println(x.gcd(y)); }
catch ( Exception e)
{ System.out.println(e); System.exit(1); }
}
}
Chapter 1 K. Louden, Programming Languages 17
Scheme (Figure 1.5, p. 17):Scheme (Figure 1.5, p. 17):
(define (gcd u v)
(if (= v 0) u
(gcd v (modulo u v))))
Chapter 1 K. Louden, Programming Languages 18
Scheme (Figure 11.7, p. 486):Scheme (Figure 11.7, p. 486):(define (euclid) ; sequential!
(display "enter two integers:")
(newline) ; goes to next line on screen
(let ((u (read)) (v (read)))
(display "the gcd of ")
(display u)
(display " and ")
(display v)
(display " is ")
(display (gcd u v))
(newline)))
Chapter 1 K. Louden, Programming Languages 19
Paradigm use is rarely “pure”:Paradigm use is rarely “pure”:
The C program defined the gcd function in a purely functional style, even though C is mainly imperative.
The Java program used some imperative code to compute the gcd, and was not completely object-oriented (integers aren’t objects).
The Scheme code used sequencing to do I/O, an imperative feature.
Chapter 1 K. Louden, Programming Languages 20
Examples of languages that are Examples of languages that are pure (mostly):pure (mostly):
Imperative: (old) FORTRAN
Functional: Haskell
Object-oriented: Smalltalk
Chapter 1 K. Louden, Programming Languages 21
Language definitionLanguage definition Syntax: the structure of a program. Usually
given a formal (i.e., mathematical) definition using a context-free language. (Lexical structure - the structure of the words or tokens - uses regular expressions.)
Semantics: the actual result of execution. Usually described in English, but can be done mathematically (Chapter 13).
Semantics can have a static component: type checking, definition checking, other consistency checks prior to execution.
Chapter 1 K. Louden, Programming Languages 22
Language translationLanguage translation
Compiler: two-step process that translates source code into target code; then the user executes the target code.
Interpreter: one-step process in which the source code is executed directly.
Hybrids are also possible (Java).
Chapter 1 K. Louden, Programming Languages 23
Error classificationError classification Lexical: character-level error, such as
illegal character (hard to distinguish from syntax).
Syntax: error in structure (e.g., missing semicolon or keyword).
Static semantic: non-syntax error prior to execution (e.g., undefined vars, type errors).
Dynamic semantic: non-syntax error during execution (e.g., division by 0).
Logic: programmer error, program not at fault.
Chapter 1 K. Louden, Programming Languages 24
Notes on error reportingNotes on error reporting A compiler will report lexical, syntax, and
static semantic errors. It cannot report dynamic semantic errors.
An interpreter will often only report lexical and syntax errors when loading the program. Static semantic errors may not be reported until just prior to execution. Indeed, most interpreted languages (e.g. Lisp, Smalltalk) do not define any static semantic errors.
No translator can report a logic error.
Chapter 1 K. Louden, Programming Languages 25
Sample Errors (Java):Sample Errors (Java):
public int gcd ( int v# ) // lexical
{ int z = value // syntax - missing ;
y = v; // static semantic - y undefined
while ( y >= 0 ) // dynamic semantic -
// division by zero
{ int t = y; y = z % y; z = t;
}
return y; // logic - should return z
}
Chapter 1 K. Louden, Programming Languages 26
Language designLanguage designGood, consistent set of abstractions.Tie-in to other technology (or clear
single goal):– C : Unix– Java : Internet– C++ : most efficient OO language
Now also:– Ease of interface with other languages
and systems– Good API libraries