Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Programowanie funkcyjne w Pythonie
1. Programowanie funkcyjne w Pythonie
Programowanie funkcyjne w Pythonie
Adam Byrtek
adambyrtek@gmail.com
Kraków, 28 stycznia 2008r.
2. Programowanie funkcyjne w Pythonie
Wprowadzenie
Paradygmaty programowania
Algorytm
algorytm mat. ściśle określony ciąg czynności, których
wykonanie 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!
3. Programowanie funkcyjne w Pythonie
Wprowadzenie
Paradygmaty programowania
Paradygmaty programowania
Imperatywne – lista rozkazów dla komputera
Obiektowe – opis interakcji między obiektami
Funkcyjne – bezstanowe operacje na funkcjach
„Jak obliczać?” vs „Co obliczać?”
5. 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)
6. 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ąć – ale
można je ograniczać i izolować
7. 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
8. 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
9. 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
10. 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
11. Programowanie funkcyjne w Pythonie
Python funkcyjnie
Operacje na funkcjach
Dekorator jako zastosowanie domknięcia
def log(func):
def l(arg):
print arg
return func(arg)
return l
@log
def square(x):
return x**2
Analogia do wzorca decorator w OOP
12. Programowanie funkcyjne w Pythonie
Python funkcyjnie
Operacje na funkcjach
Dekorator jako zastosowanie domknięcia
def log(func):
def l(arg):
print arg
return func(arg)
return l
@log
def square(x):
return x**2
Analogia do wzorca decorator w OOP
13. 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?
14. Programowanie funkcyjne w Pythonie
Python funkcyjnie
Liczby pierwsze imperatywnie
Liczby pierwsze imperatywnie
def is_prime(n):
k = 2
while k < n:
if n % k == 0:
return False
k += 1
return True
Lista poleceń do wykonania
Lokalne efekty uboczne
15. Programowanie funkcyjne w Pythonie
Python funkcyjnie
Liczby pierwsze imperatywnie
Liczby pierwsze imperatywnie
def is_prime(n):
k = 2
while k < n:
if n % k == 0:
return False
k += 1
return True
Lista poleceń do wykonania
Lokalne efekty uboczne
16. 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 elementu
map(lambda x: x**2, range(1,5))
-> [1, 4, 9, 16]
Wybieranie elementów spełniających predykat
filter(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
17. 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 Google
MapReduce)
18. 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
19. 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
20. 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
21. 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
22. 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
23. 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!)
{i 2 | i ∈ N, i ∈ [1, 10) : i ≡ 0 mod 2}
Zastępuje map i filter (nawet lambda)
Znacznie upraszcza skomplikowane wyrażenia
24. 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!)
{i 2 | i ∈ N, i ∈ [1, 10) : i ≡ 0 mod 2}
Zastępuje map i filter (nawet lambda)
Znacznie upraszcza skomplikowane wyrażenia
25. 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!)
{i 2 | i ∈ N, i ∈ [1, 10) : i ≡ 0 mod 2}
Zastępuje map i filter (nawet lambda)
Znacznie upraszcza skomplikowane wyrażenia
26. 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?
27. 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?
28. 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
29. 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ń
30. 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ń
31. Programowanie funkcyjne w Pythonie
Python funkcyjnie
Kwantyfikatory
Kwantyfikatory
Można jeszcze lepiej! (Python 2.5)
any(seq) zwraca prawdę jeśli co najmniej jeden element
sekwencji jest prawdziwy (istnieje)
all(seq) zwraca prawdę jeśli wszystkie elementy
sekwencji są prawdziwe (dla każdego)
„Krótkie spięcie” podobnie jak w przypadku operatorów
logicznych
32. 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?
33. 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
34. 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!
35. Programowanie funkcyjne w Pythonie
Podsumowanie
Podsumowanie
Podejście funkcyjne zmienia punkt widzenia na
programowanie
Warto je poznać, i korzystać z niego tam, gdzie ma to
sens