Rachunek Lambda, Typy i Logika Intuicjonistyczna
Prowadzący: Radosław Rowicki
[11.05.2020 – zmiany w zadaniu 3.2 oraz 4.3]
Rachunek Lambda
Wszyscy znamy słynną maszynę Turinga, a nawet jeśli nie, to na tych warsztatach zobaczymy coś dużo ciekawszego! Rachunek lambda to system formalny o identycznej mocy obliczeniowej co wspomniana maszyna, lecz realizujący swój cel w zupełnie innym paradygmacie. O ile maszyna Turinga definiuje obliczenia poprzez budowanie pewnego grafu stanów z pamięcią, to rachunek lambda przyjmuje podejście bardziej "funkcyjne" i skupia się na wykorzystywaniu pewnego abstraktu funkcji do definiowania wszystkiego co tylko się da.
Na warsztatach zapoznamy się ze wspomnianym systemem i nauczymy definiować obliczenia w nowym języku. Poznamy jego możliwości oraz ograniczenia, ale dowiemy się też jak sobie sprawnie z tymi ograniczeniami radzić poprzez wyrobienie pewnych wzorców.
Teoria Typów
Czym byłby javascript bez typów? ...wait, chyba zły przykład.
Czym byłby dobry język programowania bez typów? O ile istnieją języki z tzw dynamicznymi typowaniami, to zazwyczaj większą wydajnością i odpornością na głupie błędy cieszą się jednak języki statycznie typowane*. Okazuje się niestety że nasz surowy rachunek lambda należy do tych pierwszych i pozwala robić bardzo złe rzeczy nie oferując przy tym żadnej kontroli nad tym czy dana zmienna jest liczbą, wartością logiczną czy listą (bo tych pojęć w zasadzie tam nie ma). W tym celu stworzono tzw simply typed lambda calculus – rachunek lambda poszerzony o system typów pozwalający zachować pewną względną kontrolę poprawności. Dowiemy się czym tak naprawdę są typy i formalnie zdefiniujemy reguły typowania wyrażeń naszego języka. Zobaczymy też jakie nakłada to na nas ograniczenia i jakie możliwości zamyka nam bezwzględna restrykcja typecheckera.
Po tym wszystkim dowiemy się jak sobie radzić z polimorfizmem – w tym celu wprowadzę dużo mocniejszy system F na którym zbudujemy sobie bardziej zaawansowane i uniwersalne mechanizmy obliczeniowe. W tym celu będziemy musieli się zapoznać z typami wyższych rzędów oraz typami wyższej rangi.
* dynamiczne typowanie – kontrola typów (można by rzec, dziedzin zmiennych) odbywa się ad hoc w trakcie działania programu, statycznie – check jest wykonywany raz a dobrze przed wykonaniem. Od wspomnianej reguły oczywiście są wyjątki.
Logika Intuicjonistyczna
No i na koniec – co ma do tego wszystkiego logika? Okazuje się że bardzo, bardzo dużo. W tej części poznamy izomorfizm Curry'eg-Howarda który traktuje o związku logiki z powyższymi zagadnieniami. Ponadto, nie będzie to zwykła logika – będzie to jej specjalne wydanie w której wszystko jest konstruktywne i która w naturalny sposób dopuszcza brak możliwości oceny prawdziwości pewnych zdań, a także zależność stanu naszej wiedzy od pewnego kontekstu. Definitywnie odrzuca ona prawo wyłączonego środka – tutaj nie jest prawdą że każde zdanie jest prawdziwe lub fałszywe. Prawo eliminacji podwójnej negacji również idzie do lamusa, a w związku z tym odrzuca się wszelkie dowody nie-wprost. Wartość zdania nie zależy już od (jak w logice klasycznej) od wartości składowych, lecz od fizycznej obecności dowodu na to zdanie. I takimi dowodami będziemy właśnie żonglować w naszym systemie!
Wymagania
Wiedza licealna, niekoniecznie informatyczna (ale zadania kwalifikacyjne mocno zachęcają do ogarnięcia podstaw programowania). To są warsztaty których tematyka stanowi most między matematyką a informatyką, więc wypada mieć jakieś podstawowe pojęcie w obu dziedzinach.
Wymagane cechy i umiejętności:
- Znajomość logiki klasycznej
- Znajomość podstaw teorii zbiorów
- Znajomość pojęcia funkcji
- Brak strachu przed funkcjami które przyjmują funkcje jako argumenty i zwracają funkcje które przyjmują funkcje które...
Nie trzeba umieć dodawać liczb.
Przydatne rzeczy
- Zawsze możesz do mnie napisać, chętnie pomogę wyjaśnić wszelkie wątpliwości i trudności, w szczególności te związane z programowaniem
- Jako prosty i łopatologiczny język programowania mogę polecić JavaScript, jest do niego pełno tutoriali w internecie. Jako punktowany język myślę że najwygodniej użyć OCamla lub Haskella. Przykładowy tutorial do pierwszego: https://learnxinyminutes.com/docs/ocaml/ i do drugiego: https://www.tryhaskell.org/ (ten jest interaktywny!).
- Podstawowe listy w wielu językach funkcyjnych to tak naprawdę stosy
- Zmianę wartości zmiennej można zastąpić wrzuceniem jej do argumentu funkcji i wywoływanie się rekurencyjnie z nową wartością tej zmiennej. Przykład: