\chapter{Programmiersprachen}
Im folgenden werden einige Begriffe definiert anhand derer
Programmiersprachen unterschieden werden können.

\section{Paradigmen}
Die grundlegendste Art, wie man Programmiersprachen unterscheiden
kann ist das sog. \enquote{Programmierparadigma}, also die Art wie
man Probleme löst.

\begin{definition}[Imperatives Paradigma]\xindex{Programmierung!imperative}
    In der imperativen Programmierung betrachtet man Programme als
    eine folge von Anweisungen, die vorgibt auf welche Art etwas 
    Schritt für Schritt gemacht werden soll.
\end{definition}

\begin{definition}[Prozedurales Paradigma]\xindex{Programmierung!prozedurale}
    Die prozeduralen Programmierung ist eine Erweiterung des imperativen
    Programmierparadigmas, bei dem man versucht die Probleme in 
    kleinere Teilprobleme zu zerlegen.
\end{definition}

\begin{definition}[Funktionales Paradigma]\xindex{Programmierung!funktionale}
    In der funktionalen Programmierung baut man auf Funktionen und
    ggf. Funktionen höherer Ordnung, die eine Aufgabe ohne Nebeneffekte
    lösen.
\end{definition}

Haskell ist eine funktionale Programmiersprache, C ist eine
nicht-funktionale Programmiersprache.

Wichtige Vorteile von funktionalen Programmiersprachen sind:
\begin{itemize}
    \item Sie sind weitgehend (jedoch nicht vollständig) frei von Seiteneffekten.
    \item Der Code ist häufig sehr kompakt und manche Probleme lassen
          sich sehr elegant formulieren.
\end{itemize}

\begin{definition}[Logisches Paradigma]\xindex{Programmierung!logische}
    In der logischen Programmierung baut man Unifikation.\todo{genauer!}
\end{definition}

\section{Typisierung}
Eine weitere Art, Programmiersprachen zu unterscheiden ist die stärke
ihrer Typisierung.

\begin{definition}[Dynamische Typisierung]\xindex{Typisierung!dynamische}
    Bei dynamisch typisierten Sprachen kann eine Variable ihren Typ ändern.
\end{definition}

Beispiele sind Python und PHP.

\begin{definition}[Statische Typisierung]\xindex{Typisierung!statische}
    Bei statisch typisierten Sprachen kann eine niemals ihren Typ ändern.
\end{definition}

Beispiele sind C, Haskell und Java.

\section{Kompilierte und interpretierte Sprachen}
Sprachen werden überlicherweise entweder interpretiert oder kompiliert,
obwohl es Programmiersprachen gibt, die beides unterstützen.

C und Java werden kompiliert, Python und TCL interpretiert.

\section{Dies und das}
\begin{definition}[Seiteneffekt]\xindex{Seiteneffekt}\xindex{Nebeneffekt}\xindex{Wirkung}
    Seiteneffekte sind Veränderungen des Zustandes.\todo{Das geht besser}
\end{definition}

Manchmal werden Seiteneffekte auch als Nebeneffekt oder Wirkung bezeichnet.

\begin{definition}[Unifikation]\xindex{Unifikation}
    \todo[inline]{Was ist das?}
\end{definition}
