programowanie funkcyjne w pythonie

36
Programowanie funkcyjne w Pythonie Programowanie funkcyjne w Pythonie Adam Byrtek [email protected] Kraków, 28 stycznia 2008r.

Upload: adam-byrtek

Post on 23-Jan-2015

7.080 views

Category:

Technology


9 download

DESCRIPTION

Talk on functional programming in Python (in Polish) presented at the first Kraków Python Users Group meeting.

TRANSCRIPT

Page 1: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Adam [email protected]

Kraków, 28 stycznia 2008r.

Page 2: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Wprowadzenie

Paradygmaty programowania

Algorytm

algorytm mat. ściśle określony ciąg czynności, którychwykonanie prowadzi do rozwiązania jakiegoś zadania

Jak wytłumaczyć mamie czym jest programowanie?

Najbardziej intuicyjne podejście

Komputer w zasadzie tak właśnie działa

Ale to nie jedyne podejście!

Page 3: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Wprowadzenie

Paradygmaty programowania

Paradygmaty programowania

Imperatywne – lista rozkazów dla komputeraObiektowe – opis interakcji między obiektamiFunkcyjne – bezstanowe operacje na funkcjach

„Jak obliczać?” vs „Co obliczać?”

Page 4: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Wprowadzenie

Paradygmaty programowania

Modele matematyczne

Maszyna Turinga (Alan Turing)

Rachunek lambda λ (Alonzo Church)

TRUE := λxy .xFALSE := λxy .y

Obliczeniowo równoważne (twierdzenie Churcha-Turinga)

Page 5: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Wprowadzenie

Programowanie funkcyjne

Cechy języków funkcyjnych

Funkcje to podstawowe pojęcia (ang. first-class)

Funkcje mogą operować na funkcjach (ang. high-order)

Powszechnie stosowana rekurencja (zamiast pętli)

Listy podstawową strukturą danych (np. LISP)

Brak efektów ubocznych (globalnego stanu)

Page 6: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Wprowadzenie

Programowanie funkcyjne

Zalety bezstanowości

Funkcje są idempotentne

Kolejność obliczeń nie ma znaczenia

„Leniwe” obliczenia (ang. laziness)

Możliwość redukcji i optymalizacji

Możliwość przetwarzania rozproszonego

Łatwość debugowania i testowania

W praktyce efektów ubocznych nie można uniknąć – alemożna je ograniczać i izolować

Page 7: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Operacje na funkcjach

Funkcje jako pojęcia podstawowe

Lambda definiuje anonimowe funkcje

def square(x):return x**2

równoważne

square = lambda x: x**2

Page 8: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Operacje na funkcjach

Funkcje jako pojęcia podstawowe

Lambda definiuje anonimowe funkcje

def square(x):return x**2

równoważne

square = lambda x: x**2

Page 9: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Operacje na funkcjach

Domknięcie (ang. closure)

Funkcja z dołączonym środowiskiem

def get_taxer(rate):def taxer(amount):return amount * (float(rate) / 100)

return taxer

tax1 = get_taxer(22)tax2 = get_taxer(7)

Analogia do obiektu i wzorca command pattern w OOP

Page 10: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Operacje na funkcjach

Domknięcie (ang. closure)

Funkcja z dołączonym środowiskiem

def get_taxer(rate):def taxer(amount):return amount * (float(rate) / 100)

return taxer

tax1 = get_taxer(22)tax2 = get_taxer(7)

Analogia do obiektu i wzorca command pattern w OOP

Page 11: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Operacje na funkcjach

Dekorator jako zastosowanie domknięcia

def log(func):def l(arg):print argreturn func(arg)

return l

@logdef square(x):return x**2

Analogia do wzorca decorator w OOP

Page 12: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Operacje na funkcjach

Dekorator jako zastosowanie domknięcia

def log(func):def l(arg):print argreturn func(arg)

return l

@logdef square(x):return x**2

Analogia do wzorca decorator w OOP

Page 13: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Liczby pierwsze imperatywnie

Liczby pierwsze

Liczba naturalna n jest liczbą pierwszą wtedy i tylko wtedy, gdy

¬∃k ∈ [2, n) : n ≡ 0 mod k

Jak powyższe wyrażenie zapisać w postaci algorytmu?

Page 14: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Liczby pierwsze imperatywnie

Liczby pierwsze imperatywnie

def is_prime(n):k = 2while k < n:if n % k == 0:return False

k += 1return True

Lista poleceń do wykonania

Lokalne efekty uboczne

Page 15: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Liczby pierwsze imperatywnie

Liczby pierwsze imperatywnie

def is_prime(n):k = 2while k < n:if n % k == 0:return False

k += 1return True

Lista poleceń do wykonania

Lokalne efekty uboczne

Page 16: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Funkcje map, filter i reduce

Funkcje map, filter i reduce

Funkcje wyższego rzędu, operujące na listach (sekwencjach)

Zastosowanie funkcji dla każdego elementumap(lambda x: x**2, range(1,5))-> [1, 4, 9, 16]

Wybieranie elementów spełniających predykatfilter(lambda x: x%2==0, range(10))-> [0, 2, 4, 6, 8]

Łączenie elementów listy (tu lepiej użyć sum)reduce(lambda x,y: x+y, [7, 3, 12])-> 22

Page 17: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Funkcje map, filter i reduce

Dlaczego map i reduce są tak użyteczne?

Bardzo wiele problemów można do nich zredukować

Pozwalają uprościć skomplikowane pętle

Możliwość rozproszenia obliczeń (patrz GoogleMapReduce)

Page 18: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Funkcje map, filter i reduce

Liczby pierwsze, podejście drugie

def is_prime(n):len(filter(lambda k: n%k==0, range(2,n))) == 0

def primes(m):filter(is_prime, range(1,m))

„Czy lista nietrywialnych dzielników jest pusta?”

Brak efektów ubocznych (stanu)

return celowo pominięte, dla czytelności

Page 19: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Funkcje map, filter i reduce

Liczby pierwsze, podejście drugie

def is_prime(n):len(filter(lambda k: n%k==0, range(2,n))) == 0

def primes(m):filter(is_prime, range(1,m))

„Czy lista nietrywialnych dzielników jest pusta?”

Brak efektów ubocznych (stanu)

return celowo pominięte, dla czytelności

Page 20: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Funkcje map, filter i reduce

Liczby pierwsze, podejście drugie

def is_prime(n):len(filter(lambda k: n%k==0, range(2,n))) == 0

def primes(m):filter(is_prime, range(1,m))

„Czy lista nietrywialnych dzielników jest pusta?”

Brak efektów ubocznych (stanu)

return celowo pominięte, dla czytelności

Page 21: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Funkcje map, filter i reduce

Liczby pierwsze, podejście drugie

def is_prime(n):len(filter(lambda k: n%k==0, range(2,n))) == 0

def primes(m):filter(is_prime, range(1,m))

„Czy lista nietrywialnych dzielników jest pusta?”

Brak efektów ubocznych (stanu)

return celowo pominięte, dla czytelności

Page 22: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Funkcje map, filter i reduce

Liczby pierwsze, podejście drugie

def is_prime(n):len(filter(lambda k: n%k==0, range(2,n))) == 0

def primes(m):filter(is_prime, range(1,m))

„Czy lista nietrywialnych dzielników jest pusta?”

Brak efektów ubocznych (stanu)

return celowo pominięte, dla czytelności

Page 23: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

List comprehensions

List comprehensions

Można to zrobić jeszcze lepiej!

List comprehensions, zapożyczone z Haskella

[i**2 for i in range(1,10) if i%2==0]-> [4, 16, 36, 64]

Odpowiednik zapisu matematycznego (nie do końca!){i2| i ∈ N, i ∈ [1, 10) : i ≡ 0 mod 2}Zastępuje map i filter (nawet lambda)

Znacznie upraszcza skomplikowane wyrażenia

Page 24: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

List comprehensions

List comprehensions

Można to zrobić jeszcze lepiej!

List comprehensions, zapożyczone z Haskella

[i**2 for i in range(1,10) if i%2==0]-> [4, 16, 36, 64]

Odpowiednik zapisu matematycznego (nie do końca!){i2| i ∈ N, i ∈ [1, 10) : i ≡ 0 mod 2}Zastępuje map i filter (nawet lambda)

Znacznie upraszcza skomplikowane wyrażenia

Page 25: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

List comprehensions

List comprehensions

Można to zrobić jeszcze lepiej!

List comprehensions, zapożyczone z Haskella

[i**2 for i in range(1,10) if i%2==0]-> [4, 16, 36, 64]

Odpowiednik zapisu matematycznego (nie do końca!){i2| i ∈ N, i ∈ [1, 10) : i ≡ 0 mod 2}Zastępuje map i filter (nawet lambda)

Znacznie upraszcza skomplikowane wyrażenia

Page 26: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

List comprehensions

Liczby pierwsze, trzecie podejście

def is_prime(n):True not in [n%k==0 for k in range(2,n)]

def primes(m):[n for n in range(1,m) if is_prime(n)]

Czy w dwóch ostatnich wersjach występuje jakiś problem?

Page 27: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

List comprehensions

Liczby pierwsze, trzecie podejście

def is_prime(n):True not in [n%k==0 for k in range(2,n)]

def primes(m):[n for n in range(1,m) if is_prime(n)]

Czy w dwóch ostatnich wersjach występuje jakiś problem?

Page 28: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Strumienie

Generatory, iteratory i strumienie

Czy musimy przechodzić przez całą listę?

Iteratory to „leniwe” sekwencje

Generator expressions tworzą iteratory

(i**2 for i in xrange(1,10) if i%2==0)-> <generator object at 0x12c4850>

W programowaniu funkcyjnym mówimy o strumieniach

Page 29: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Strumienie

Liczby pierwsze, czwarte podejście

def is_prime(n):True not in (n%k==0 for k in xrange(2,n))

is_prime(100000000)-> False

Leniwe wyznaczanie wartości wyrażeń

Page 30: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Strumienie

Liczby pierwsze, czwarte podejście

def is_prime(n):True not in (n%k==0 for k in xrange(2,n))

is_prime(100000000)-> False

Leniwe wyznaczanie wartości wyrażeń

Page 31: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Kwantyfikatory

Kwantyfikatory

Można jeszcze lepiej! (Python 2.5)

any(seq) zwraca prawdę jeśli co najmniej jeden elementsekwencji jest prawdziwy (istnieje)

all(seq) zwraca prawdę jeśli wszystkie elementysekwencji są prawdziwe (dla każdego)

„Krótkie spięcie” podobnie jak w przypadku operatorówlogicznych

Page 32: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Kwantyfikatory

Liczby pierwsze, finał

def is_prime(n):not any(n%k==0 for k in xrange(2,n))

Czy to coś przypomina?

¬∃k ∈ [2, n) : n ≡ 0 mod k

Tadam!

Page 33: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Kwantyfikatory

Liczby pierwsze, finał

def is_prime(n):not any(n%k==0 for k in xrange(2,n))

Czy to coś przypomina?

¬∃k ∈ [2, n) : n ≡ 0 mod k

Tadam!

Page 34: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Python funkcyjnie

Kwantyfikatory

Liczby pierwsze, finał

def is_prime(n):not any(n%k==0 for k in xrange(2,n))

Czy to coś przypomina?

¬∃k ∈ [2, n) : n ≡ 0 mod k

Tadam!

Page 35: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Podsumowanie

Podsumowanie

Podejście funkcyjne zmienia punkt widzenia naprogramowanie

Warto je poznać, i korzystać z niego tam, gdzie ma tosens

Page 36: Programowanie funkcyjne w Pythonie

Programowanie funkcyjne w Pythonie

Podsumowanie

Dziękuję

λ