Die glorreichen 10 – Programmiersprachen (2)

Loading

Der heutige Teil schließt nahtlos an den ersten Teil an, der gestern erschien. Es geht um 10 Kriterien anhand derer man Programmiersprachen kategorisieren kann.

Maschinennah oder universell, aber komplex

Als eine maschinennahe Sprache bezeichnet man eine Sprache, die nahe den Möglichkeiten von Prozessoren ist. Das Paradebeispiel ist C. Alle Prozessoren haben Befehle um ein Register um 1 zu erhöhen oder zu erniedrigen. Das braucht man für Zählschleifen aber auch Arrayindizierungen. In C gibt es dafür eigene Hochsprachenbefehle , den Operator ++ oder –. C wird daher auch als Superassembler bezeichnet. Mit C kann man zwar im Prinzip alles programmieren, aber gedacht war sie eigentlich für die Systementwicklung. Die zahlreichen Sicherheitslücken die Betriebssysteme haben beruhen zu einem Teil auf Mängel von C in der Stringverarbeitung.

Das genaue Gegenteil ist eine Sprache, die sich von der Maschine löst und dazu geeignet ist unter vielen Computern alle möglichen Probleme zu lösen, egal ob dies Datenverarbeitung, Berechnungen oder Grafik ist. Dieses Ziel gab es schon früh und IBM schuf 1960 PL/I (Programming Langauge 1) als eine Sprache die „alles kann“. PL/I (oder PL/1 Im deutschsprachigen Raum) konnte sich jedoch außerhalb der IBM Welt nie richtig durchsetzen. Neben den Sprachmöglichkeiten also den Befehlen und Datentypen gehört zum Universalismus auch das Abstrahieren der Rechnerhardware. Welche Möglichkeit für die Verarbeitung von Dateien es gibt, hängt stark vom Betriebssystem ab, die Möglichkeiten der Grafik von der verbauten Hardware. Will man auch dies universell machen so wird es aufwendig. Bei den klassischen Programmiersprachen musste man die Grafikroutinen eigentlich immer anpassen. Zu unterschiedlich waren Bildschirmauflösung und Farbzahl. Von Kleinigkeiten das der Ursprung (Koordinate 0,0) mal unten links und mal oben links sein kann mal ganz zu schweigen. True BASIC war ein Ansatz das zu lösen, dafür aber sehr langsam weshalb es sich nicht durchsetzte. Heute hat man das bei Programmiersprachen mit einer virtuellen Maschine gelöst. Deren Möglichkeiten sind fest und bei jedem Rechner gleich. Allerdings sehen dann Java-Programme auf grafischen Oberflächen zwar immer gleich aus, aber eben ziemlich Altbacken, weil sie nur den kleinsten gemeinsamen Nenner abdecken.

Portierbarkeit des erzeugten Codes

Da komme ich schon zum nächsten Unterscheidungsmerkmal. Klassischen Maschinencode kann man nicht zwischen Rechnern mit unterschiedlicher Architektur portieren. Schon Updates reichen oft aus, dass ein Programm nicht mehr läuft. Ich bekam vor einigen Monaten eine Mail von jemand, der ein Programm von mir im Jahr 2026 unter Windows XP einsetzte, das lief gut bis er einen Menüpunkt aufrief und der nutzte den Taskdialog der mit Windows Vista eingeführt wurde und das Programm brach ab.

Die Lösung ist eine virtuelle Maschine, also ein theoretischer Computer mit eigenem Befehlssatz und eigenen Möglichkeiten. Man kann dann Code für diese virtuelle Maschine erzeugen, braucht aber noch eine Laufzeitumgebung die diesen dann in echten Maschinencode übersetzt. Das bekannteste Beispiel dafür ist Java (so benannt nach der Lieblingskaffeesorte der Entwickler, Kaffee gehört bei Programmierern einfach zum Alltag, er vertreibt Müdigkeit und hält die Konzentration hoch). Java hatte um die Jahrtausendwende einen richtigen Hype, weil man so ein Programm auf unterschiedlichen Rechnern laufen lassen konnte, auf einem PC, Apple Mac oder einem Linux System.

Der Nachteil: Java ist interpretiert und damit langsamer als nativer Maschinencode. Vor allem beim Programmstart merkt man das, später kaum noch. Java ist auch als Speicherfresser bekannt und wie schon erwähnt sehen Java Programme dann eben aus wie Windows 95 Programme, denn sie bieten nur die grundlegenden Funktionen für Fenster, die jedes System hat. Das ist zwar durch Bibliotheken abänderbar, doch dann geht auch die Portabilität verloren. Populäre PC Programme, die Java nutzen sind der TV Browser oder Mediathek-Viewer.

Läuft auf einer oder mehreren Computern

Bisher sprach ich von klassischen Programmen. Sie laufen auf einem Computer, heute vielleicht nur als ein Task von vielen. Aber kann ein Programm auch auf vielen Rechnern gleichzeitig laufen? Ja das kann es und das zwar ein weiterer Grund warum Java so erfolgreich wurde. Man konnte damit verteilte Systeme kreieren in dem ein PC mit einem Großrechner sich unterhält ohne das dieser das Quellprogramm zugeschickt bekommt. Es gibt dazu zwei Mechanismen. Das eine sind Remote Procedures, man ruft eine Prozedur auf einem anderen Rechner über das Internet auf, dort wird der Code ausgeführt und man erhält die Ausgabe. Dafür muss man natürlich wissen, wie dies geschieht. Das hat eine gewisse Ähnlichkeit zu DLL compilierten Bibliotheken, die man auf Windows Rechnern aufrufen kann.

Das zweite ist ein Webservice. Dafür stellt der Rechner eine Beschreibungsdatei zur Verfügung die beschreibt, wie man mit ihm korrespondiert und man nutzt diese um Anfragen zu stellen. Auf der Weiterentwicklung basieren fast alle Schnittstellen zu Diensten mit einer API (Application Programm Interface). So kann man Orbits von der NASA berechnen lassen, Kurse von Yahoo abfragen oder Google Suchen durchführen lassen.

Server- oder Clientseitig

Wenn ich mehrere Computer habe, die sich unterhalten, dann sind die selten gleichberechntigt. Es hat sich eingebürgert das es einen Server gibt der Daten liefert und einen Client der sie empfängt. In der Regel ist ein Server ein größerer Rechner, der aber mehrere Benutzer gleichzeitig bedient. Bernd-Leitenberger.de ist nur eine von 50 Domains bei meinem Webhoster pro Server.

Man kann Programme nur für den Server entwickeln oder nur für den Client oder für beide. Seit dem Aufkommen des Internets haben sich Sprachen breit durchgesetzt, die jeweils auf einer Plattform laufen. Der Blog z.b. basiert auf der Programmiersprache PHP bei der HTML mit einer Programmiersprache verknüpft ist und so dynamisch die Seite erstellt, die ihr seht. PHP läuft auf dem Server meines Hosters. Die Alternative dazu ist Javascript. Bei Javascript ist der Code in dem HTML Quelltext eingebettet und wird während die Seite lädt, vom Browser ausgeführt. Man kann dies nutzen für Dinge, die HTML als Seitenbeschreibungssprache nicht bietet, wie Prüfungen der Eingaben in einem Formular oder eine Diashow. Beides wäre auch serverseitig möglich aber z.B. die Prüfung der Eingaben durch den Server würde bedeuten, dass man die Seite neu lädt und alle korrekten Eingaben verlieren würde.

Firmendefinition oder Offenes System

Schon immer wollten Firmen eigene Programmiersprachen schaffen. PL/I von IBM wurde schon erwähnt. Jenseits IBM konnte sie sich nie durchsetzen. Der Vorteil ist natürlich das man die Sprache auf das zuschneiden kann, was man selbst einsetzt, man kann von anderen Sprachen Teile übernehmen, die sinnvoll sind.

Im Prinzip sind die meisten neu erschienen Sprachen die Bedeutung haben, Firmensprachen. Eine einzelne Person konnte noch ein BASIC für einen 8 Bit Rechner oder die erste Turbo Pascal Version programmieren (stammt von Anders Hejlsberg), aber eine heutige Sprache ist viel umfangreicher und man erwartet ja auch eine umfangreiche Bibliothek mit Funktionen zu allem. Viele Firmensprachen wurden aber dann von den Firmen abgegeben. So z.B. Java, ursprünglich entwickelt von Sun. Später an eine Foundation abgegeben, die den Sprachstand weiterentwickelt in der Sun (bzw. nach Übernahme Oracle) viel Gewicht hat aber eben nicht alleine entscheidet. Unter einer Firmensprache verstehe ich eine, in der die Firma praktisch alleine entscheidet, wie die Weiterentwicklung geht und da drängt sich einem geradezu Microsoft auf.

Als Java Ende der Neunziger Jahre einen Siegeszug hatte, brachte auch Microsoft eine Java-Version namens J# heraus. Sehr bald fand Sun heraus das J#-Programme nur unter Windows liefen, also das Grundprinzip der Portabilität von Java verletzten und prozessierte gegen Microsoft und gewann. Microsoft schuf dann eine eigene Laufzeitumgebung mit einer virtuellen Maschine (genannt .NET, die meisten haben mehrere Versionen dieser Umgebung auf dem Rechner entweder über Windows Update oder weil Anwendungsprogramme sie mitbringen) und eine neue Sprache C#, der dann noch zahlreiche mit einem # (ausgesprochen: Sharp) folgten. Über den Sprachstandard entscheidet nur Microsoft, auch wenn es Implementierungen für Linux gibt.

Ernsthafte Sprache oder Spaßsprache

Also bisher habe ich nur von ernsthaften Sprachen gesprochen, mit denen man Probleme lösen kann. Selbst mit einem BASIC der Achtziger Jahre mit beschränkten Fähigkeiten, kann man berechnen, wie viel Geld man seinem Kind am 18. Geburtstag geben kann, wenn man jeden Monat 100 Euro auf ein Konto einzahlt, das monatlich verzinst wird. Aber es gibt auch nicht ernst gemeinte Sprachen, auch esoterische Programmiersprachen genannt, die nicht für den praktischen Einsatz gedacht sind. Brainfuck besteht nur aus Symbolen und dürfte die kleinste Programmiersprache sein, die es gibt – der kleinste Compiler ist gerade mal 98 Bytes lang, Piet besteht aus Bildern mit Quadraten und die Quelltexte der Shakespeare Programming Language ähnelt wie der Name sagt mehr einem Werk von Shakespeare als einem Programm.

Mancher bezeichnet aber auch etablierte Programmiersprachen als nicht ernsthaft. APL arbeitet sehr viel mit mathematischen Operatoren, für die man eine eigene Tastatur braucht und hat den Ruf einer „Write once, Read never“ Sprache, wurde aber z.B. in HP-Computern eingesetzt und COBOL hat unter Programmierer durch sie schwafelige Art, den Ruf einer Programmiersprache für Betriebswirte und andere die zu doof für echte Programmiersprachen sind, zu sein.

Leicht zu erlernen oder schwer

Es ist klar, das je umfangreicher eine Sprache ist, man um so mehr Arbeit in das Lernen stecken muss. Man kann es dem werdenden Programmierer aber auch schwer machen oder leicht. Die esoterischen Sprachen im letzten Punkt weichen so sehr von unserem normalen Denken ab, dass man sie nicht praktisch nutzt. Ersetzt man Befehlsworte durch Symbole wie bei APL ist die Einstiegshürde auch hoch. Umgekehrt sind wir so an bestimmte Symbole gewöhnt, dass wir das Ersetzen der Operatoren für die Grundrechenarten + – * / und = durch englische Wörter in COBOL schwerer verständlich finden.

Viele Sprachen wurden ursprünglich als Lehrsprachen geschaffen, also um Programmieranfänger das Leben leichter zu machen. Pascal war ursprünglich eine Lehrsprache mit einer Ähnlichkeit zu dem damals populären Algol. Sie sollte Studenten mit den Konzepten von Algol vertraut machen in Algol sollten sie dann ernsthaft programmieren. Algol wird heute nicht mehr verwendet, Pascal aber schon. Pascal ist pedantisch, aber dadurch werden Fehler entdeckt. Denn jeder macht Fehler, nur geben das viele Programmierer nicht zu. BASIC war ebenfalls Lehrsprache, es ähnelt mehr FORTRAN, vor allem ist der Sprachumfang recht klein und es gibt eine ganz einfache Programmstruktur – das Programm wird einfach zeilenweise ausgeführt, wobei jede Zeile eine eigene Nummer hat. Sie ist daher enorm einfach zu lernen.

Als ich für ein Projekt eine Programmiersprache brauchte um Abläufe zu automatisieren, habe ich mich daher an BASC orientiert und entsprechend hieß die Sprache dann auch ATS-BASIC, bzw im Nachfolgeprojekt PATS BASIC.

Erstaunlicherweise können Freiheiten die Einstiegshürde erhöhen. Mein Paradebeispiel ist C. Nicht nur dadurch, dass man exzessiv Symbole verwendet (Blockmarkierungen mit {} sind schwerer zu lesen als „begin“ und „end“) man kann dort viel machen was zu schwer findenden Fehlern führt, so in einem Vergleich eine Zuweisung machen: if (a=b) … vergleicht nicht a mit b, sondern weist a den Wert von b zu und vergleicht den Wert mit 0. Warum man für die Zuweisung „=“ und den Vergleich „==“ nahm und in einem Vergleichsstatement eine Zuweisung erlaubt, hat für mich nur einen Grund: Man wollte bewusst einen Fallstrick einbauen. C kann genauso esoterisch wie Brainfuck sein. Beispiel gefällig? Der folgende Code ist korrektes C und bekam einen Preis bei einem „obfusticated C“ Wettbewerb:

#include <stdio.h>

 

main(t,_,a)

char *a;

{return!0<t?t<3?main(-79,-13,a+main(-87,1-_,

main(-86, 0, a+1 )+a)):1,t<_?main(t+1, _, a ):3,main ( -94, -27+t, a

)&&t == 2 ?_<13 ?main ( 2, _+1, „%s %d %d\n“ ):9:16:t<0?t<-72?main(_,

t,“@n’+,#’/*{}w+/w#cdnr/+,{}r/*de}+,/*{*+,/w{%+,/w#q#n+,/#{l,+,/n{n+\

,/+#n+,/#;#q#n+,/+k#;*+,/’r :’d*’3,}{w+K w’K:’+}e#‘;dq#’l q#’+d’K#!/\

+k#;q#’r}eKK#}w’r}eKK{nl]’/#;#q#n‘){)#}w‘){){nl]’/+#n‘;d}rw‘ i;# ){n\

l]!/n{n#‘; r{#w’r nc{nl]’/#{l,+’K {rw‘ iK{;[{nl]’/w#q#\

n’wk nw‘ iwk{KK{nl]!/w{%’l##w#‘ i; :{nl]’/*{q#’ld;r‘}{nlwb!/*de}’c \

;;{nl‘-{}rw]’/+,}##’*}#nc,‘,#nw]’/+kd’+e}+;\

#’rdq#w! nr’/ ‚) }+}{rl#'{n‘ ‚)# }’+}##(!!/“)

:t<-50?_==*a ?putchar(a[31]):main(-65,_,a+1):main((*a == ‚/‘)+t,_,a\

+1 ):0<t?main ( 2, 2 , „%s“):*a==’/’||main(0,main(-61,*a, „!ek;dc \

i@bK'(q)-[w]*%n+r3#l,{}:\nuwloca-O;m .vpbks,fxntdCeghiry“),a+1);}

Hier der Code fürs eigene Compilieren. Lasst euch überraschen…

Früher kam bei solchen Blogs immer mal die Frage auf welche Programmiersprache man lernen soll, wenn man Anfänger ist. Ich gebe dafür heute keine eigene Empfehlung mehr ab. Ich bin bei Pascal hängen geblieben, nachdem ich schon BASIC und Z80 Assembler gelernt habe. Aber das ist 40 Jahre her und viele Programmiersprachen gab es damals noch nicht. Heute sehe ich es pragmatisch: Ich lerne keine neue Programmiersprache, nur um mich weiterzubilden, denn man braucht Jahre bis man richtig effizient in einer Sprache programmieren kann, wenn sie etwas komplexer ist. Zudem muss man oft Projekte in mehreren Sprachen realisieren. Für die Einbindung von .COM Objekten in eine Umgebung von Siemens musste ich Pascal-Code mit C mischen und mein Ölstandmesser arbeitet mit Python-Code der die eigentliche Messung durchführt und Pascalcode für die Auswertung und Generierung der Statusseite. Die Pascal-Entwicklungsumgebung bot für den Raspberry Pi keinen Timer der auf Mikrosekunden genau war und den brauchte ich wegen des Meßprinzips (Der Sensor sendet ein Schallsignal aus und man misst die Laufzeit bis das Echo ankommt – bei der Schallgeschwindigkeit von 343 m/s braucht man eine Genauigkeit von 1/343000 s um auf Millimeter genaue Werte zu kommen.

Die ct’ empfiehlt Python als Einstieg. Sie hat eine rege Community, ist weit verbreitet und der Sprachstandard ist sehr umfangreich und deckt alle wichtigen Konzepte ab. Dazu gibt es viele kostenlose Entwicklungsumgebungen für viele Systeme. Die Langsamkeit wirkt sich bei Anfängerprojekten, die ja selten umfangreich sind nicht so aus und man kann sie mit C koppeln um das auszugleichen.

Schreibe einen Kommentar

Diese Website verwendet Akismet, um Spam zu reduzieren. Erfahre, wie deine Kommentardaten verarbeitet werden.