Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Lecture 15: Functional languages • • • • • Wellknown(?) facts about functions Let A and B be sets. A (partial) function f:A → B is a subset of A Χ B such that for every a∈A, there is at most one b∈B such that (a,b)∈f. Functions and variables in mathematics Functional languages LISP (Scheme), ML and HASKELL Lazy evaluation Program verification and transformation 2008-12-16 Lennart Edblom, Inst. f. datavetenskap • A is the domain of the function, and B is its range • The value of the function for an argument a∈A is denoted f(a). It is the b which fulfills (a,b) ∈ f • The value may be undefined (if no b exists) but no ambiguities may occur. • If f(a) always is defined, f is total, otherwise f is partial 1 2008-12-16 Lennart Edblom, Inst. f. datavetenskap Mathematical definition of functions The role of variables in mathematics In mathematics the way a function f is defined is absolutely irrelevant, as long as the definition is exact (and f is a function according to the general definition). A variable like e.g n in fib(n) = … is a placeholder for an arbitrary but fixed value (i.e. n denotes the same value everywhere). The definitionen should be read "For every n : fib(n) = …". (Compare imperative languages where a variable denotes a specific but variable value!) • Expressions, conditions and recursion are the most commons structures used to define functions. 2 • Example: Definition of the Fibonacci function fib(n) = 2008-12-16 n ⇒ There is nothing like an external state which can affect the result – under all circumstances fib(6) equals 8. This property is called referential transparency (swe: betydelsemässig genomskinlighet ) if n ≤ 1 fib(n-1) + fib(n-2) otherwise Lennart Edblom, Inst. f. datavetenskap 3 2008-12-16 In functional languages (also called applicative programming languages) we try to transfer the mathematical function concept to programming. Expressions consisting of function applications are evaluated to get results. • Variables have the same properties as in mathematics • If the value of expressions isn’t affected by context the language is referentially transparent or purely functional (⇒ no side effects whatsoever) • Referential transparency simplifies the semantics considerably (because there is no need to cope with a dynamically changeable state) Lennart Edblom, Inst. f. datavetenskap 4 Functional languages (2) Functional languages 2008-12-16 Lennart Edblom, Inst. f. datavetenskap Important components in a functional language are often • The concept of (and notation for) function application • Some primitive data types and functions, and possibility to combine functions and data types to new d.t & func. • Functions as "first-class citizens”, i.e. the same rights as other data types ⇒ functions may be input/output of other functions, higher-order functions or functional forms, e.g. composition '°': h=f°g ⇒ h(x) = f(g(x)) combination '[…]': h = [f1,…,fk] ⇒ h(x)= (f1(x),…,fk(x)) iteration 'map': h = map f ⇒ h(x1…xk) = f(x1)…f(xk) 5 2008-12-16 Lennart Edblom, Inst. f. datavetenskap 6 1 The first functional language: LISP Scheme • LISP was developed around 1960 by McCarthy, pure LISP may be seen as ”sugared” λ-calculus • Unlike contemporary imperative languages the domain for LISP was not numerical but symbolic computations • The list (of symbols and lists) was the only data type ⇒ expressions, functions, … are represented as lists. The same notation for data and programs! • The universal function EVAL that McCarthy wrote in LISP evaluates LISP-expressions; its implementation was the first LISP interpreter. • The interpreter uses the read-eval-print-loop which has now been part of many interpreters • Variant of Lisp with static scope rules, first class functions, simple syntax & semantics • Ex (member): (DEFINE (member a lst) (COND ((NULL? lst) ’()) ((EQ a (CAR lst)) #T) (ELSE (member a (CDR lst))))) • Compare with ML: fun member a [] = false | member a (h::t) = a=h orelse member a t; 2008-12-16 2008-12-16 Lennart Edblom, Inst. f. datavetenskap 7 ML and HASKELL Lazy evaluation evaluates only the subexpressions whose values are needed to compute the result. Lazy evaluation used => infinite data structures are possible: types and type declarations type inference strongly typed languages possibility to define (parameterized) ADT:s intsfrom n = n : intsfrom (n + 1) ints = intsfrom 1 Filter all primes out of the list of all integers: • Most important differences between ML and HASKELL ML allows imperative programming while HASKELL is completely referentially transparent (no side effects) ML’s evaluation strategy is strict (eager evaluation) while HASKELL employs lazy evaluation Lennart Edblom, Inst. f. datavetenskap 8 Lazy evaluation • ML and HASKELL are (much) newer and are syntactically more similar to other programming languages. • Semantic advantages compared to LISP 2008-12-16 Lennart Edblom, Inst. f. datavetenskap not_multiple_of n m = m mod n <> 0 sieve(x:xs) = x:sieve(filter(not_multiple_of x) xs) sieve(intsfrom 2) 9 2008-12-16 Lazy evaluation (2) Lennart Edblom, Inst. f. datavetenskap 10 More Haskell • Can be used to separate computation and control. Computation: Compute values, put them into a lazy list. Control: Traverse data structure and fetch needed values. Ex: Compute square root of x using Newton-Raphsonʼs method. yn+1 = 0.5 * (yn + x/yn) (ML-notation below) • Type classes ≈OO-classes with only functions, inheritance • ”List comprehensions” Cf set expressions. evens = [n|n<-ints; n mod 2 = 0] • fun apsqr x = let fun from app = app:: from(0.5 * (app + x/app)) in from 1.0 end qsort [] = [] qsort (h:t) = qsort[b|b<-t, b<=h] ++ [h] ++ qsort[b|b<-t, b>h] • fun diff eps (a1:: a2:: as) = if abs (a1-a2) <= eps then a2 else diff eps (a2:: as) • val sqrt = diff 0.0001 o apsqr 2008-12-16 Lennart Edblom, Inst. f. datavetenskap 11 2008-12-16 Lennart Edblom, Inst. f. datavetenskap 12 2 Proofs about programs Program transformations • Thanks to the absence of side effects definitions may be used as equations,which makes proofs of program properties possible fun [] @ ys = ys | (x::xs)@ys = x::(xs@ys) fun rev1 [] = [] | rev1(x::xs)= (rev1 xs)@[x] fun revh [] ys = ys | revh (x::xs) ys = revh xs (x::ys) length [] = 0 length (x::xs) = 1 + length xs fun rev2 xs = revh xs [] Show that, for all lists l, rev1 l = rev2 l 2008-12-16 • New programs or more efficient versions of old programs can be derived in a provably correct way. • Ex: Given length (below), derive a function length2 such that (for all l1, l2) length2 l1 l2 = length l1 + length l2 Lennart Edblom, Inst. f. datavetenskap • Ex 2: Reverse with accumulating parameters can be derived from the stack recursive Reverse (not shown) 13 2008-12-16 Parallelism Lennart Edblom, Inst. f. datavetenskap 14 Parallelism, cont • Functional languages are well suited for parallel execution Easy to ”find” parallelism, evaluation order is limited only by data dependencies. (Remember Church-Rosser!) parallell x = (f1 x, f2 x) f1 y = y+1 f2 z = z*3 No special language features for expressing parallelism are necessary (in principle). • Function composition <=> pipelining • Map <=> data parallelism • To get better control over execution, resource allocation etc. parallel language constructions may be introduced. (f1 x) and (f2 x) may be evaluated in parallel (when x has been assigned a value) g (f1 x) (f2 x) The arguments of g can be evaluated simultaneously Deterministic, no side effects, => deadlock may easily be avoided. Results are independent of scheduling 2008-12-16 Lennart Edblom, Inst. f. datavetenskap 15 Imperative vs functional • • • • • • Lennart Edblom, Inst. f. datavetenskap Lennart Edblom, Inst. f. datavetenskap 16 Funktionella språk • Bygger på det matematiska funktionsbegreppet. Beskriver en lösning, vad programmet ska göra. Syntax Semantics Efficiency Readability / Writability Concurrency Naturalness 2008-12-16 2008-12-16 Variabler - namn på värden Uttrycks/funktionsorienterat Rekursion & funktionskomposition (Ej inbyggd sekventialitet) • Ett funktionellt program = en mängd ekvationer, en specifikation. • Dataobjekt bearbetas ej, utan varje funktionsapplikation skapar ett nytt objekt. 17 18 3 Imperativa språk Mer om funktionella vs imperativa språk • Nära relaterade till traditionell datorarketektur. Ger en följd instruktioner till datorn. Variabler - abstraktion av en minnescell. Tilldelning - uppdatering av minnescell. Värden måste lagras. Kommandoorienterat - effekterna påverkar minnet Sekventialitet & iteration - sekvenser av maskininstruktioner som kan upprepas. • Procedurer bearbetar dataobjekt, som övergår från gammal till ny form genom stegvisa bearbetningar • Vi måste ofta veta hur programmet exekveras för att kunna veta programmets resultat (hur minnescellerna påverkas). • Sidoeffekter - en funktion gör något mer än returnerar ett värde. 19 • Programmeraren måste sköta mer operationella detaljer (”hur”) i imperativa språk • Ex: j:=1; for i:=1 to linelength do if line[i]<10 then begin newline[j]:=line[i]; j:=j+1 end end • Jämför filter (fn x=>x<10) number_sequence • Å andra sidan har programmeraren mer kontroll över vad som görs i imperativa språk, och kan därför ibland skriva effektivare program 20 Fördelar: funktionell programmering Variabler • Imperativa språk - namn på minnesceller • Funktionella språk - namn på värden; matematiska variabler • Variabler i imperativa språk används för a) Lagra input- och outputvärden b) Kontrollera iteration c) Lagra temporära resultat d) Spara ”tillståndet” tex vid anrop av underprogram • I funktionella språk a) Aktuella parametrar & funktionsresultat b) Rekursion (argumentvärdena styr) c) Hanteras oftast automatiskt d) Hanteras av systemet • Ackumulerande parametrar • Anropsstack 21 • Lättare resonera / bevisa saker om funktionella program p.g.a matematisk bas - inga sidoeffekter • Även programtransformationer • ”Referential transparency” - samma uttryck med samma argument har alltid samma värde. • Funktioner är ”first class values”. Högre ordningens funktioner möjliga. Det är sällan möjligt att tex returnera funktioner som resultat av funktioner i imperativa språk • Datatyper på högre abstraktionsnivå, rekursiva datatyper, ingen pekarhantering. • Sammansatta värden kan inte alltid skapas direkt, eller returneras från funktioner i imperativa språk • Fullständig polymorfism (”generisk”). Polymorfism i imperativa /OO-språk är ofta = överlagring / dyn. bindning • Ofta enklare syntax och semantik, kortare program 22 4