Brief History of "Programming"
Brief History of "Programming"
(Borrowed from
Peyton Jones & John Mitchell)
Language Evolution
Lisp
Algol 60
Algol 68
Pascal C
Smalltalk
ML Modula C++
Haskell Java
Many others: Algol 58, Algol W, Scheme, EL1, Mesa (PARC), Modula-2,
Oberon, Modula-3, Fortran, Ada, Perl, Python, Ruby, C#, Javascript, F#…
C Programming Language
Dennis Ritchie, ACM Turing Award for Unix
1,000,000
10,000
100
Geeks
1,000,000
10,000
100
The slow death
Geeks
1,000,000
10,000
The complete
100 absence of death
Geeks
1,000,000
10,000
100
The slow death
Geeks
100
The second life?
Geeks
• Strings
“Ron Weasley”
• Floats
1.0, 2, 3.14159, … --type classes to disambiguate
Haskell Libraries
Simple Compound Types
Tuples
(4, 5, “Griffendor”) :: (Integer, Integer, String)
Lists
[] :: [a] -- polymorphic type
Records
data Person = Person {firstName :: String,
lastName :: String}
hg = Person { firstName = “Hermione”,
lastName = “Granger”}
Patterns and Declarations
• Patterns can be used in place of variables
<pat> ::= <var> | <tuple> | <cons> | <record> …
• Value declarations
–General form: <pat> = <exp>
–Examples
myTuple = (“Flitwick”, “Snape”)
(x,y) = myTuple
myList = [1, 2, 3, 4]
z:zs = myList
–Local declarations
•
let (x,y) = (2, “Snape”) in x * 4
Functions and Pattern Matching
• Function declaration form
<name>
<pat1> = <exp1>
<name> <pat2> = <exp2> …
<name> <patn> = <expn> …
• Examples
f (x,y) = x+y --argument must match pattern (x,y)
length [] = 0
length (x:s) = 1 + length(s)
More Functions on Lists
• Append lists
–
append ([], ys) = ys
append
– (x:xs, ys) = x : append (xs, ys)
• Reverse a list
–
reverse [] = []
–
reverse (x:xs) = (reverse xs) ++ [x]
• Questions
– How efficient is reverse?
– Can it be done with only one pass through list?
More Efficient Reverse
reverse xs =
let rev ( [], accum ) = accum
rev ( y:ys, accum ) = rev ( ys, y:accum )
in rev ( xs, [] )
1 3
2 2 2 2
3 3 1 3 1 1
List Comprehensions
• Notation for constructing new lists from old:
myData = [1,2,3,4,5,6,7]
4
Node(4, Node(3, Leaf 1, Leaf 2),
Node(5, Leaf 6, Leaf 7))
3 5
1 2 6 7
Recursive function
sum (Leaf n) = n
sum (Node(n,t1,t2)) = n + sum(t1) + sum(t2)
Case Expression
Datatype
data Exp = Var Int | Const Int | Plus (Exp, Exp)
Case expression
case e of
Var n -> …
Const n -> …
Plus(e1,e2) -> …
ev ( Var n) = Var n
ev ( Const n ) = Const n
ev ( Plus ( e1,e2 ) ) =
case ev e1 of
Var n -> Plus( Var n, ev e2)
Const n -> case ev e2 of
Var m -> Plus( Const n, Var m)
Const m -> Const (n+m)
...with a strange-looking
type
Demo QuickCheck
QuickCheck
• Generate random input based on type
– Generators for values of type a has type Gen a
– Have generators for many types
• Conditional properties
– Have form <condition> ==> <property>
– Example:
ordered xs = and (zipWith (<=) xs (drop 1 xs))
insert x xs = takeWhile (<x) xs++[x]++dropWhile (<x) xs
prop_Insert x xs =
ordered xs ==> ordered (insert x xs)
where types = x::Int
QuickCheck
• QuickCheck output
– When property succeeds:
quickCheck prop_RevRev OK, passed 100 tests.
– When a property fails, QuickCheck displays a counter-example.
prop_RevId xs = reverse xs == xs where types = xs::[Int]
quickCheck prop_RevId
Falsifiable, after 1 tests: [-3,15]
• Conditional testing
– Discards test cases which do not satisfy the condition.
– Test case generation continues until
• 100 cases which do satisfy the condition have been found, or
• until an overall limit on the number of test cases is reached (to
avoid looping if the condition never holds).
See : http://www.cse.chalmers.se/~rjmh/QuickCheck/manual.html
Things to Notice
No side effects. At all.
reverse:: [w] -> [w]