2014-02-24 11:44:57 +01:00
%!TEX root = Programmierparadigmen.tex
2014-02-01 14:39:16 +01:00
\chapter { Programmiersprachen}
Im folgenden werden einige Begriffe definiert anhand derer
Programmiersprachen unterschieden werden können.
2014-02-14 09:23:58 +01:00
\begin { definition} \xindex { Programmiersprache} \xindex { Programm} %
Eine \textbf { Programmiersprache} ist eine formale Sprache, die durch eine
Spezifikation definiert wird und mit der Algorithmen beschrieben werden
können. Elemente dieser Sprache heißen \textbf { Programme} .
\end { definition}
Ein Beispiel für eine Sprachspezifikation ist die \textit { Java Language Specification} .\footnote { Zu finden unter \url { http://docs.oracle.com/javase/specs/} } Obwohl es kein guter Stil ist, ist auch
eine Referenzimplementierung eine Form der Spezifikation.
Im Folgenden wird darauf eingegangen, anhand welcher Kriterien man
Programmiersprachen unterscheiden kann.
\section { Abstraktion}
Wie nah an den physikalischen Prozessen im Computer ist die Sprache?
Wie nah ist sie an einer mathematisch / algorithmischen Beschreibung?
\begin { definition} \xindex { Maschinensprache} \xindex { Befehlssatz} %
Eine \textbf { Maschinensprache} beinhaltet ausschließlich Instruktionen, die direkt
von einer CPU ausgeführt werden können. Die Menge dieser Instruktionen
sowie deren Syntax wird \textbf { Befehlssatz} genannt.
\end { definition}
\begin { beispiel} [Maschinensprachen]
\begin { bspenum}
\item \xindex { x86} x86:
\item \xindex { SPARC} SPARC:
\end { bspenum}
\end { beispiel}
2014-03-08 13:16:08 +01:00
\begin { definition} [Assembler]\xindex { Assembler} %
Eine Assemblersprache ist eine Programmiersprache, deren Befehle dem
Befehlssatz eines Prozessor entspricht.
2014-02-14 09:23:58 +01:00
\end { definition}
\begin { beispiel} [Assembler]%
2014-03-08 13:16:08 +01:00
Folgendes Beispiel stammt von \url { https://de.wikibooks.org/wiki/Assembler-Programmierung_ für_ x86-Prozessoren/_ Das_ erste_ Assemblerprogramm} :
\inputminted [linenos, numbersep=5pt, tabsize=4, frame=lines, label=firstp.asm] { nasm} { scripts/assembler/firstp.asm}
\end { beispiel}
\begin { definition} [Höhere Programmiersprache]\xindex { Programmiersprache!höhere} %
Eine Programmiersprache heißt \textit { höher} , wenn sie nicht ausschließlich
für eine Prozessorarchitektur geschrieben wurde und turing-vollständig ist.
\end { definition}
\begin { beispiel} [Höhere Programmiersprachen]
Java, Python, Haskell, Ruby, TCL, \dots
\end { beispiel}
\begin { definition} [Domänenspezifische Sprache]\xindex { Sprache!domänenspezifische} %
Eine domänenspezifische Sprache (engl. domain-specific language; kurz DSL)
ist eine formale Sprache, die für ein bestimmtes Problemfeld
entworfen wurde.
\end { definition}
\begin { beispiel} [Domänenspezifische Sprache]
\begin { bspenum}
\item HTML
\item VHDL
\end { bspenum}
2014-02-14 09:23:58 +01:00
\end { beispiel}
2014-02-01 14:39:16 +01:00
\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}
2014-02-01 15:32:13 +01:00
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}
2014-02-24 11:44:57 +01:00
In der logischen Programmierung baut auf der Unifikation auf.\todo { genauer!}
2014-02-01 15:32:13 +01:00
\end { definition}
2014-02-01 14:39:16 +01:00
\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.
2014-02-01 15:32:13 +01:00
\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}
2014-02-24 11:44:57 +01:00
\begin { definition} [Seiteneffekt]\xindex { Seiteneffekt} \index { Nebeneffekt|see{ Seiteneffekt} } \index { Wirkung|see{ Seiteneffekt} } %
2014-02-01 15:32:13 +01:00
Seiteneffekte sind Veränderungen des Zustandes.\todo { Das geht besser}
\end { definition}
Manchmal werden Seiteneffekte auch als Nebeneffekt oder Wirkung bezeichnet.
2014-02-24 11:44:57 +01:00
\begin { definition} [Unifikation]\xindex { Unifikation} %
Die Unifikation ist eine Operation in der Logik und dient zur Vereinfachung
prädikatenlogischer Ausdrücke.
2014-03-12 21:07:00 +01:00
Der Unifikator ist also eine Abbildung, die in einem Schritt dafür sorgt, dass
auf beiden Seiten der Gleichung das selbe steht.
2014-02-01 15:32:13 +01:00
\end { definition}
2014-02-24 11:44:57 +01:00
2014-03-12 21:07:00 +01:00
\begin { beispiel} [Unifikation\footnotemark ]
Gegeben seien die Ausdrücke
\begin { align*}
A_ 1 & = \left (X, Y, f(b) \right )\\
A_ 2 & = \left (a, b, Z \right )
\end { align*}
Großbuchstaben stehen dabei für Variablen und Kleinbuchstaben für atomare
Ausdrücke.
Ersetzt man in $ A _ 1 $ nun $ X $ durch $ a $ , $ Y $ durch $ b $ und in $ A _ 2 $
die Variable $ Z $ durch $ f \left ( b \right ) $ , so sind sie gleich oder
\enquote { unifiziert} . Man erhält
\begin { align*}
\sigma (A_ 1) & = \left (a, b, f(b) \right )\\
\sigma (A_ 2) & = \left (a, b, f(b) \right )
\end { align*}
mit
\[ \sigma = \{ X \mapsto a, Y \mapsto b, Z \mapsto f ( b ) \} \]
2014-02-24 11:44:57 +01:00
\end { beispiel}
2014-03-12 21:07:00 +01:00
\begin { definition} [Allgemeinster Unifikator]\xindex { Unifikator!allgemeinster} %
Ein Unifikator $ \sigma $ heißt \textit { allgemeinster Unifikator} , wenn
es für jeden Unifikator $ \gamma $ eine Substitution $ \delta $ mit
\[ \gamma = \delta \circ \sigma \]
gibt.
\end { definition}
\begin { beispiel} [Allgemeinster Unifikator\footnotemark ]
Sei
\[ C = \Set { f ( a,D ) = Y, X = g ( b ) , g ( Z ) = X } \]
eine Menge von Gleichungen über Terme.
Dann ist
\[ \gamma = [ Y \text { \pointer } f ( a,b ) , D \text { \pointer } b, X \text { \pointer } g ( b ) , Z \text { \pointer } b ] \]
ein Unifikator für $ C $ . Jedoch ist
\[ \sigma = [ Y \text { \pointer } f ( a,D ) , X \text { \pointer } g ( b ) , Z \text { \pointer } b ] \]
der allgemeinste Unifikator. Mit
\[ \delta = [ D \text { \pointer } b ] \]
gilt $ \gamma = \delta \circ \sigma $ .
\end { beispiel}
\footnotetext { Folie 268 von Prof. Snelting}
\footnotetext { \url { https://de.wikipedia.org/w/index.php?title=Unifikation\_ (Logik)& oldid=116848554\# Beispiel} }