Академический Документы
Профессиональный Документы
Культура Документы
Principles Of Programming
Languages
-Functional Programming
High level
Principles
Lambda Calculus
Referential Transparency
Can replace function call by function result always
=>
4 + 2 =>
x. x + 2
Means that functions can be evaluated multiple times
Example:
( x. x + 2) ( y. y * y) 4
( x y. x * y + 2) (4+3) == ( y. (4+3) * y + 2)
Principles Of Programming Languages
Work-arounds
Work-arounds
Use diff/patch
int tmp;
int foo(int a) {
tmp = tmp + a * 3;
return tmp + 5;
}
Copy-on-write
Work-arounds
How to do Input/Output ?
Example: Miranda
Pure vs Inpure
Examples
Type Inference
recursion:
// Math notation
fac(x) =
1, iff x = 0
x * fac(x 1), otherwise
|| Miranda
fac :: num -> num
fac x = 1, if x = 0
fac x = x * fac (x 1), otherwise
(* pascal *)
function fac(n : integer) : integer;
var i, r: integer;
begin
r := 1;
for i := n downto 1 do
r := r * i;
fac := r;
end;
// C# type-inference
class A {
static LinkedList<char> fill(int n) { .. }
Lists
Lists
[]
[[0,2,4,6],[1,3,5]]
Miranda:
[1 .. 10]
[1,4,5,9]
['a','b','c']
List Comprehensions
[0,5..20]
{- 0,5,10,15,20 -}
Lists
Miranda: head/tail
hd[1,2,3]
tl[1,2,3]
=> [1]
=> [2,3]
Miranda: 'cons'
Lists
1:[]
1:[2,3]
|| Miranda:
length x = 0
, if x = []
length x = 1 + length (tl x), otherwise
=> [1]
=> [1,2,3]
|| Or
length x = # x
{- Haskell -}
listLength x = if x==[] then 0 else 1+ListLength tail
{- or use the builtin length operator -}
listLength x = length(x)
Lists
Lists
|| Miranda
concatenate x y = y, if x = []
concatenate x y = (hd x) : concatenate (tl x) y, otherwise
{- Haskell -}
concatenate x y = if x == [] then y else ((head x) :
concatenate (tail x) y )
No
No hassle with
{- or: -}
concatenate x y = x ++ y
Next-element-ptr, previous-element-ptr
malloc/new, free/delete
Polymorphic functions
Polymorphic functions
|| Miranda
pair x y = [x, y]
|| .. can be used like:
pair 1 2
pair True False
pair [1] [2]
// C++: overloading
list pair(int a, int b);
list pair(bool a, bool b);
list pair(list a, list b);
|| Miranda
pair :: -> ( -> [] ) || read as: (,)->[], see 'currying' later on
pair x y = [x, y]
pair True 1
|| Miranda:
Foldr, foldl
{- Haskell: -}
tripple x = x * 3
tripplelist x = map tripple x
tripple x = x * 3
tripplelist x = map tripple x
tripplelist [1,2,3]
tripplelist [1,2,3]
|| => [3,6,9]
Folding
{- [3,6,9] -}
|| alternatively using the + operator
sumlist x = foldr (+) 0 x
Folding
Currying
{- Haskell: -}
This delivers a partial function where the leftover parameters still need to be passed
partial parametrization
currying
Lazy Evaluation
Lazy Evaluation
Lazy Evaluation
The I/O list has infinite length and grows with time
Haskell/Miranda:
Lazy Evaluation
sumsum x = x + x
sumsum 4*5
|| Lazy
4*5 + 4*5
20 + 20
40
--------------------------2 mults + 2 adds
|| Eager
sumsum 20
20 + 20
40
------------------------1 mult + 1 add
-- Haskell
zoo a = b * 100
where
tmp = a * 2;
b = tmp * 2;
Pattern Matching
Pattern Matching
f(n + 1) = .. allowed
f(n + m) = .. not allowed, ambiguous !
uniq [] = []
uniq (a:(a:x)) = uniq (a:x)
uniq (a:x) = a:uniq x
unique x = uniq(sort(x))
|| what does this do ?
fac 0 = 1
fac (n + 1) = (n + 1) * fac n
|| Miranda
quicksort [] = []
quicksort (x:rest) = quicksort [a | a <- rest; a <= x]
++ x
++ quicksort[a | a <- rest; a > x]
|| NOTE: ++ is list concatenation
|| NOTE: [a | a <- rest; a > x] is list comprehension:
|| return each element 'a' in rest, where a > x
{- Haskell: -}
quicksort [] = []
quicksort (x:rest) = quicksort([a | a <- rest, a <= x]) ++
[x] ++
quicksort([a | a <- rest, a > x])
len [] = 0
|| will only match if non-empty
|| as there must be atleast a head
len (a:b) = 1 + (len b)
Pattern Matching
Monads / Monoids
For example:
Examples:
Monads
Monads
Unit function
return x = Just x
Binding:
(Just x) >>= f = f x
Type def:
Haskell:
Haskell:
Monads
Monads
a = do x <- [1, 2, 3]
return (Just x)
Monads
X2
X3
X5
merge
Example: Lisp
Properties
Case insensitive
No type-system 8-{
(1 / 34) / 3
I/O
` vs not `
Note:
- setq assigns to symbol
C: int a = ...
- setf assigns a value to a place
C: *a = ...
Symbol properties:
(setq ht (make-hash-table))
Hashtables
(gethash `a ht)
Structures / Records
Lists
Example: OCaML
ML = Meta Language
Functional
Pattern matching
polymorphism
Ocaml = either
OCaml
Adds object-orientation to ML
# let y a b c = a * b * c;;
val y : int -> int -> int -> int = <fun>
# let z a b c = a *. b *. c;;
val z : float -> float -> float -> float = <fun>
# y 1 2 3;;
- : int = 6
# z 1.0 2.0 3.0 ;;
- : float = 6.
OCaml
OCaml
let x a b c = ..
let rec x a b c
OCaml
OCaml
Empty list = []
OCaml
OCaml
X=X+1
OCaml
OCaml
#module Set =
functor (Elt: ORDERED_TYPE) ->
struct
type element = Elt.t
type set = element list
let empty = []
let rec add x s =
match s with
[] -> [x]
| hd::tl ->
match Elt.compare x hd with
Equal
-> s
(* x is already
| Less
-> x :: s
(* x is smaller
| Greater -> hd :: add x tl
let rec member x s =
match s with
[] -> false
| hd::tl ->
match Elt.compare x hd with
Equal
-> true
(* x belongs to
| Less
-> false
(* x is smaller
| Greater -> member x tl
end;;
s *)
than all elements of s *)
OCaml
in s *)
than all elements of s *)
OCaml
# class point =
object
val mutable x = 0 -- declared mutable so its value can change
-- otherwise this would be a 'final' or 'const'
method get_x = x
method move d = x <- x + d
end;;
OCaml
OCaml
Instead of {} as normal