Obliczalność i złożoność
Na co to komu?
Funkcje nie muszą mieć nazw, żeby opisać dowolne obliczenia.
Y = lambda f: (lambda x: x(x))(lambda y: f(lambda *args: y(y)(*args)))
fib = lambda f: lambda n: 0 if n == 0 else (1 if n == 1 else f(n-1) + f(n-2))
>>> [Y(fib)(i) for i in range(10)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
1. Teoretyczny model dla dowolnych obliczeń, podobny do obecnych komputerów.
2. To to samo, co rachunek lambda!
Czyli zdolność (języka programowania) do wyrażenia dowolnych obliczeń. Wystarczy sprowadzić go do Maszyny Turinga.
Wrócimy do tego.
Czy patrząc na program, mogę powiedzieć, czy się nigdy nie "zawiesi" (np. wpadając w nieskończoną pętlę)?
Nie mogę, jeśli język jest Turing-kompletny.
"Jeśli dostanę 10ETH od A, automatycznie przeleję 11ETH do B".
W Ethereum pisane w Solidity.
Jak udowodnić, że program nie robi głupot?
Typy to twierdzenia, programy to dowody.
Potrzeba "fajnych" typów, które potrafią powiedzieć np. "biorę wektor dł. N, wektor dł. M i zwracam wektor dł. (M+N)". W kodzie:
app : Vect n a -> Vect m a -> Vect (n + m) a
app Nil ys = ys
app (x :: xs) ys = x :: app xs ys
Patrząc na taki "fajny" program mogę powiedzieć:
Jak to zrobić, mając na uwadze Problem Stopu?
Umawiamy się, że:
Problem stopu przestaje nas dotyczyć!
[...] Simplicity is finitarily complete, allowing the programming of all finite computations [...], it is Turing incomplete, disallowing unbounded loops and allowing for static analysis.
Możliwość udowodnienia, że program robi to, co chcemy.
Dobre początki: http://learnyouanagda.liamoc.net/pages/introduction.html
Możliwość automatycznego generowania testów!
Możliwość przeczytania wielu wspaniałych książek/artykułów i błyszczenia w towarzystwie.
Przykładowo:
*porada, jak znaleźć towarzystwo, któremu to imponuje, jest poza zakresem wykładu
Znając teorię mnogości, logikę, teorię typów, obliczalności, kategorii, etc. można korzystać z ich synergii i wykorzystać to do bycia "programistą 10x".