H. Conrad Cunningham
24 August 2017
Acknowledgements: These slides accompany section 1.3, “Primary Programming Paradigms” from Chapter 1 “Fundamental Concepts” of “Introduction to Functional Programming Using Haskell”.
Advisory: The HTML version of this document may require use of a browser that supports the display of MathML. A good choice as of August 2017 is a recent version of Firefox from Mozilla.
Timothy A. Budd. Multiparadigm Programming in Leda, Addison-Wesley, 1995, page 3:
"a way of conceptualizing what it means to perform computation, of
structuring and organizing how tasks are to be carried out on a
computer."
Historical programming language paradigms
imperative
declarative
Recent programming languages blur distinctions
But concept of programming paradigm meaningful
Imperative program
Imperative language
Imperative program
int count = 0;
int maxc = 10;
while (count <= maxc) {
System.out.println(count) ;
count = count + 1
}
State includes
count
and maxc
State changes (side effects)
count
valueprintln
adds line to output int count = 0;
int maxc = 10;
while (count <= maxc) {
System.out.println(count) ;
count = count + 1
}
Execution in sequence
while
causes execution zero or more timescount
, maxc
int count = 0;
int maxc = 10;
while (count <= maxc) {
System.out.println(count) ;
count = count + 1
}
State implicit because state assumed from context
Variable count
mutable because value can change
count
yields different values at different timesVariable maxc
also mutable
, but does not change here
Imperative languages well suited for traditional computer architectures
Examples: Fortran, C, C++, Java, C#, Python, JavaScript, Lua
Object-oriented languages?
Declarative program
Declarative program
Declarative language
Declarative programs
Declarative paradigm subdivided into
Underlying computational model is mathematical function
counter :: Int -> Int -> String
counter count maxc
| count <= maxc = show count ++ "\n" ++ counter (count+1) maxc
| otherwise = ""
Above Haskell fragment similar in meaning to earlier Java fragment
counter
count
and maxc
count
to maxc
one per lineFunction “call” (application) of counter
count
and maxc
, explicit parameters of call counter :: Int -> Int -> String
counter count maxc
| count <= maxc = show count ++ "\n" ++ counter (count+1) maxc
| otherwise = ""
Repetition of counter
by recursive call
State of counter
explicit because passed in arguments
Values of arguments immutable within body
Names like count
and maxc
(in pure functional language)
Referential transparency very important
In functional languages, functions often are
Higher-order functions very important
Pure examples: Haskell, Idris, Elm. Miranda, Hope, Backus’ FP.
Hybrid examples: Scala, F#, OCaml, SML, Erlang, Elixir, Lisp, Clojure, Scheme
Mainstream imperative language with functional subsets: Java 8+, C#, Python, Ruby, Groovy, Rust, and Swift
Underlying computational model is mathematical relation (or predicate)
counter(X,Y,S) :- count(X,Y,R), atomics_to_string(R,'\n',S).
count(X,X,[X]).
count(X,Y,[]) :- X > Y.
count(X,Y,[X|Rs]) :- X < Y, NX is X+1, count(NX,Y,Rs).
Above SWI-Prolog code similar in meaning to earlier Java amd Haskell code
X
to Y
, one per lineDefines database consisting of clauses
count(X,X,[X]).
defines a fact
X
and list [X]
consisting of single value X
, count(X,X,[X])
is asserted as truecount(X,Y,[]) :- X > Y.
defines a rule
:-
is true if right-side is also truecount(X,Y,[])
is true when X > Y
counter(X,Y,S) :- count(X,Y,R), atomics_to_string(R,'\n',S).
count(X,X,[X]).
count(X,Y,[]) :- X > Y.
count(X,Y,[X|Rs]) :- X < Y, NX is X+1, count(NX,Y,Rs).
Can query database for missing components
count(1,1,Z).
yields value Z = [1]
count(X,1,[1].
yields value X = 1.
Imperative and functional languages run computation in one direction yielding one answer
Prolog can run computation in multiple directions yielding multiple answers
Example relational languages: Prolog, Parlog, and miniKanren.
Most Prolog implementations not pure, have imperative features (cut, assert and retract clauses)