Was sind Skriptsprachen?
Skriptsprachen sind eine beliebte Familie von Programmiersprachen, mit denen sich häufig gestellte Anforderungen schnell erfüllen lassen. Frühe Skriptsprachen wurden eher für Nischenanwendungen genutzt, sowie als sogenannte „Glue-Sprachen”, also zum „Zusammenkleben” bestehender Systeme. Mit dem Aufkommen des World Wide Web etablierten sich eine Reihe von Skriptsprachen für den Einsatz auf Webservern. Da Skriptsprachen die Verarbeitung von Text vereinfachen, eignen sie sich zur dynamischen Erzeugung von HTML-Seiten.
Heutzutage machen Skriptsprachen laut TIOBE-Index ca. ein Drittel der weltweit am häufigsten genutzten Programmiersprachen aus. JavaScript ist nahezu die einzige klientenseitig im Browser laufende Skriptsprache. Aber auch die serverseitigen Sprachen PHP, Python, Ruby und Perl sind allesamt Skriptsprachen.
Wie unterscheiden sich Programmier- und Skriptsprachen?
Um zu verstehen, was Skriptsprachen ausmacht, hilft es, die Unterschiede zu herkömmlichen Programmiersprachen, wie C, C++ und Java, zu kennen. In diesen Sprachen schreibt der Programmierer einen Quelltext, welcher in einem getrennten Schritt in Binärcode umgewandelt wird. Es kommen also zwei Dateien zum Einsatz: die Quelltext-Datei, in welcher der Programmierer arbeitet und eine daraus erstellte Binärdatei, die sich direkt auf dem Computer ausführen lässt. Als Übersetzer zwischen den beiden Dateien dient ein spezielles Programm, der so genannte Compiler.
Die Umwandlung von Quelltext in Binärcode heißt „Kompilierung”. Während der Kompilierung wird der Quelltext auf seine Plausibilität hin überprüft: Sind alle verwendeten Variablen tatsächlich definiert, passen die Typen von Funktionsargumenten zu den Funktionsdefinitionen, hat der Programmierer irgendwo ein Zeichen vergessen? Diese Überprüfung findet bei jeder Kompilierung für den gesamten Quelltext statt und kann so einige Zeit in Anspruch nehmen. Der aus der Kompilierung resultierende Binärcode ist stark optimiert, um bei der Ausführung möglichst fehlerfrei und schnell zu arbeiten. Kompilierte Sprachen eignen sich daher besonders für rechenintensive Aufgaben und größere Systeme.
Bei der Ausführung eines in einer Skriptsprache geschriebenen Programms gibt es keine Kompilierung. Es wird also keine Binärdatei aus dem vom Programmierer geschriebenen Quelltext erzeugt. Als Folge davon sind in Skriptsprachen geschriebene Programme für gewöhnlich weniger effizient in der Ausführung. Diese Einbuße an Effizienz ist jedoch kein reiner Nachteil, sondern es handelt es sich um eine bewusste Abwägung: Skriptsprachen entlasten den Programmierer, indem Sie den Prozessor stärker belasten. Skriptsprachen eignen sich daher besonders gut für kleinere bis mittelgroße Programme.
Die Idee, dem Programmierer die Arbeit zu erleichtern, zieht sich als roter Faden durch die Architektur vieler Skriptsprachen. So verzichten diese auf die manuelle Speicherverwaltung, eine besonders effiziente, jedoch fehleranfällige Technik. Ferner ist es in den meisten Skriptsprachen nicht notwendig, den Typ einer Variable anzugeben. Da in Skriptsprachen geschriebene Programme nicht kompiliert werden, gibt es auch keinen Bedarf für eine main()-Funktion. Mit Skriptsprachen kann Software direkter und mit weniger Quelltext geschrieben werden. Vergleichen Sie die nachfolgenden Beispiele. Beide dargestellten Programme liefern dasselbe Ergebnis:
// "Hallo Welt" Beispiel in Java
class HalloWelt {
static public void main( String args[] ) {
System.out.println( "Hallo Welt!" );
}
}
# "Hallo Welt" Beispiel in Python
print "Hallo Welt!"
Merkmale von Skriptsprachen
Wie eingangs erwähnt, werden Skriptsprachen-Programme nicht vor der Ausführung durch einen Compiler in Binärcode umgewandelt. Statt des Compilers kommt ein Interpreter genanntes Programm zum Einsatz. Konzeptuell können Sie sich vorstellen, dass der Interpreter den Quelltext von oben nach unten abliest und dabei Stück für Stück den Binärcode generiert und ausführt.
Sollten Ihnen die Begriffe „Quelltext”, „Binärcode” und „Interpreter” noch etwas schwammig vorkommen, dann nutzen Sie folgendes Analogbeispiel: Stellen Sie sich den Quelltext als musikalische Noten für ein Orchester vor. In diesem Beispiel entspricht der Binärcode einer fertigen Aufnahme des gesamten Musikstücks, gespeichert auf einer CD. Das Musikstück auf der CD lässt sich in jedem beliebigen CD-Player abspielen, kann jedoch im Nachhinein nicht mehr verändert werden. Der Interpreter entspricht dem Orchester, welches das Musikstück live vorträgt.
Mit Skriptsprachen per REPL interaktiv programmieren
Bei vielen Skriptsprachen ist es möglich, den Interpreter interaktiv auszuführen. Dies wird als REPL-Modus bezeichnet, aus dem Englischen für „read-eval-print-loop”, in etwa „lesen-ausführen-ausgeben-wiederholen”. Der Programmierer übergibt Quelltext an den Interpreter, welcher diesen liest und ausführt. Der Interpreter zeigt daraufhin das Ergebnis an (ausgeben) und wartet die nächste Eingabe ab (wiederholen).
Wird im REPL-Modus ein Fehler ausgegeben, kann sich der Programmierer die Inhalte von Variablen anzeigen lassen, um so den Fehler zu lokalisieren. Ferner ist es möglich, den Wert einer Variable zu überschreiben und Teile des Quelltextes mit dem neuen Wert zu testen. So lässt sich ein Programm aus kleineren, für sich getesteten Stücken komponieren. Entwicklung und Fehlerbehebung laufen in einem Zug ab. Das macht es besonders einfach, schnell ein arbeitsfähiges Programm zu schreiben.
Komplexe Datenstrukturen in Skriptsprachen als Literale definieren
Skriptsprachen zielen darauf ab, dem Programmierer die Arbeit zu erleichtern. Dafür geben diese Sprachen dem Programmierer eine Reihe von Werkzeugen an die Hand. Dazu zählen komplexe Datenstrukturen, wie Zeichenketten, Listen, Felder und Objekte. Diese lassen sich in Skriptsprachen als so genannte „Literale” schreiben. Das ermöglicht es, komplexe Datenstrukturen direkt abzubilden, anstatt diese mittels mehrerer Befehle aufzubauen. Der Programmierer kann die benötigten Datenstrukturen einfacher ausdrücken und wird dadurch entlastet.
// Beispiel für ein Objekt-Literal in JavaScript
kunde = {
'vorname': "Hans",
'nachname': "Mustermann",
'alter': 40,
'aktiv': true,
'adressen': {
'privat': {},
'firma': {},
},
}
# Beispiel für HTML Generierung per Template-Literal in JavaScript
seiten_titel = 'Was sind Skriptsprachen?'
h1 = '<h1>${seiten_titel}</h1>'
# gibt zurück "<h1>Was sind Skriptsprachen?</h1>"
Dynamische Typisierung in Skriptsprachen
In den obigen Code-Beispielen ist Ihnen vielleicht aufgefallen, dass keinerlei Typen wie "String", "int" oder "bool" angegeben wurden. Jedoch benötigt das Programm für die Ausführung die Typinformationen. Woher stammen diese also?
Skriptsprachen setzen in der Regel auf „dynamische Typisierung”: Der Interpreter schließt aus dem Kontext auf den Typ einer Variable. In Skriptsprachen ist der Typ einer Variable auch nicht fest, sondern kann sich je nach Kontext ändern. Ein Beispiel:
# Beispiel für dynamische Typisierung in Python
# ein Name, dargestellt als Liste von Vorname, Nachname
name = ['Hans', 'Mustermann']
# der Typ der Variable "name" ist "list"
type(name)
# wir benötigen im Folgenden nur noch den Vornamen
name = name[0]
# der Typ der Variable "name" ist nun "str"
type(name)
Verwendung von Skriptsprachen
Skriptsprachen werden nach Verwendung und Einsatzort kategorisiert. Manche Skriptsprachen werden auf der Kommandozeile eingesetzt, um Abfolgen von Befehlen zusammenzufassen. Sie dienen damit der Automatisierung. Zu diesen Sprachen zählen Bash und PowerShell.
Eine ähnliche Funktion erfüllen VBA und AppleScript. Mit diesen Sprachen lassen sich auf Anwendungsebene Abläufe automatisieren.
Auf dem Webserver werden PHP, Perl, Ruby, Python und JavaScript eingesetzt, um dynamische Websites und Webanwendungen zu realisieren. JavaScript läuft ferner als einzige Skriptsprache im Webbrowser. Ursprünglich nur für die Programmierung interaktiver Elemente vorgesehen, werden heutzutage ganze Webanwendungen in JavaScript geschrieben.
Auch in der Statistik und Wissenschaft werden Skriptsprachen verwendet. Hier kommen vor allem die Sprachen R und Python zum Einsatz.