###### tags: `MP`
# III tercja wykład 1
## O czym będziemy mówić
W III tercji będziemy (wstępnie) mówić o tym, jak rozumieć (głębiej) konstrukcje językowe. Przede wszystkim będziemy patrzeć na Racketa i Plaita.
Podstawowe 3 aspekty języka:
1. składnia (konkretna / abstrakcyjna)
2. semantyka (wiedza o tym, jakie jest znaczenie konstrukcji)
3. pragmatyka (jak się języka używa, nie będziemy o tym mówić)
Będziemy się zajmować przede wszystkim semantyką (wyrażona w terminach interpreterów). Być może będziemy pisać coś zgadującego typy. Interpretery będziemy pisać w języku Plait (to będzie nasz meta-język).
## Informacje
Wszystkie pliki z wykładu, o których będzie opowiadane
"Rozszerz" oznacza, że należy rozszerzyć:
1. składnię abstrakcyjną
2. interpreter
3. składnię konkretną (poprzez rozszerzenie parsera)
## Parser
Ostatnio mieliśmy parser Racketa w Plaicie (chyba).
Mamy w Plaicie statyczne typy danych.
Budowanie parserów jest odrębną rzeczą i się tego nie robi (są programy do automatycznej budowy parserów na podstawie gramatyki).
## Język wyrażeń arytmetycznych:
Składnia abstrakcyjna:
1. Wyrażenia to:
* stała (numer)
* operator (binarny) z dwoma wyrażeniami
Parser: zamienia postać "liniową" z wejścia na drzewko
Parser zawsze działa na S-wyrażeniach (atomy i zagnieżdzone listy).
Przyjmiemy konwencję, że będziemy użuwać nawiasów figurowych, czyli {}.
## Testowanie
Plait ma mechanizm na tworzenie modułu do testowania:
```plait
(module+ test
(test (parse '2); poprawne wyniki
(numE 2))
...
(test/exn (parse '{{+ 1 2}}) ;upewniamy się, że jak powiny być błędy to są
"invalid input"))
```
Ważne: testowanie możemy zrobić na początku pliku i to i tak będzie działać.
## Interpretowanie
1. Ustalenie dziedziny wartości interpretera (dla wyrażeń arytmetycznych trywialne)
alias typu: nadanie nowej nazwy istniejącemu typowi
## Inne sposoby pisania interpretera
Można zbudować maszynę abstrakcyjną interpretującą rzeczy (jak wyglądają przejścia pomiędzy stanami). Wtedy obliczenie to pewien ciąg przejść po którym (liczymy, że) dojdziemy do stanu końcowego.
Można w interpreterze ogarnąć wstawianie rzeczy na stos za Plaita (bo i tak by to sam zrobił).
Taka wersja jest prostsza do zrobienia niskopoziomowo, bo poprzednia była bardziej wysokopoziomowa.
Tutaj nasze stany są postaci:
1. <wyrazenie, stos>
2. <inne_wyrazenie, inny_stos>
3. <nowy_stos, wartosc>
## Kompilatory
Interpretery są spoko do zrozumienia jak działa język itp, ale jest powolne i lepiej jest używać kompilatora.
Byte code - kod w postaci listy prostych instrukcji, coś podobnego do assemblera ale "wersja idealna"
**"Od tej pory wszyscy będą cytować ten kod. Cały świat."**
`cond` to lukier syntaktyczny na kaskadę `if`-ów.
"Tak się oczywiście tego nie robi. Ja pozwolę Państwu naprawić to w ramach listy zadań"
"Jak nie wiadomo co zrobić to można dać 42."
Moglibyśmy napisać też 42/0 bo wtedy byłby błąd. Nie chcemy wyrzucać błędu, ponieważ w tym momencie dopiero interpretujemu kod, dopóki nie jest uruchomiony wurzucanie errorów nie ma sensu. Później będzie jak to można inaczej zrobić.
Generalnie piszemy Racketa w Plaicie ale bez zmiennych.
Monady:
Na poziomie programowania to sposób na narzucenie programowi struktury i określenie co i jak się policzy:
1. jak wygląda ...
2. funkcja return
3. funkcja bind (jak złożyć ze sobą obliczenia)