Wie Computer Befehle abarbeiten, haben wir im letzten Teil der “Wie Rechner rechnen”-Serie gesehen – Grundlage hierfür waren die Instruktionen, Bitketten, welche die durchzuführende Aufgabe codieren. Da das Programmieren mit Bitketten allerdings nicht sonderlich komfortabel war, wurden die Assemblersprachen eingeführt, die mit sogenannten Mnemonics, kurzen Wörtchen, die Programmierarbeit vereinfachen. Damit konnte man schon ganz vernünftig programmieren, aber etwas umständlich war es immer noch; vor allem mit größer werdenden Programmen ging mit Assembler die Übersicht schnell verloren. Der Weisheit letzter Schluss war Assembler also auch nicht; im Laufe der Jahre wurden daher die verschiedensten höheren Programmiersprachen entwickelt, die das Problem der Übersichtlichkeit lösen sollten. Ich möchte hier keinen geschichtlichen Abriss darüber geben, welche Sprache wann entstanden ist – wen das interessiert, der möge sich selber darüber informieren. Vielmehr soll es in diesem Artikel darum gehen, die grundlegenden Prinzipien von Programmiersprachen im Allgemeinen darzustellen.

Allen Sprachen ist gemein, dass sie einen Aufsatz auf Assembler darstellen und die Assembler-Funktionalität gewissermaßen auf komfortable Art und Weise einkapseln – ähnlich, wie Assembler vorher die Nutzung der Bitketten-Instruktionen vereinfacht hat. Nun war die Entwicklung von Assembler relativ einfach, da es im Grunde lediglich notwendig war, die ohnehin schon vorhandenen Bitketten-Instruktionen durch besser lesbare Befehle zu ersetzen; man konnte also fast eine 1-zu-1-Abbildung durchführen (ganz so einfach ist es natürlich nicht und Assembler kann auch noch mehr Dinge; als Analogie soll es hier aber genügen). Für den nächsten Schritt in der Entwicklung von Programmiersprachen sollte es dann aber schon ein wenig mehr sein.

Das wichtigste zu lösende Problem war die allgemeine Lesbarkeit der Anwendungen. Mit Assembler konnte zwar alles wunderbare ausgedrückt werden, aber wirklich intuitiv war es nicht unbedingt. Schauen wir zum Beispiel einmal auf den folgenden Code:

(1)       mov al, var1
(2)       sub al, var2
(3)       mov var3, al

Hier wird nicht anderes gemacht als zwei im Speicher stehende Zahlen voneinander zu subtrahieren und das erhaltene Ergebnis an einer dritten Stelle zu speichern. Aus der Mathematik kennt man hierfür eine weitaus verständlichere Form der Notation:

var3 = var1 - var2

Ist doch so viel besser lesbar, oder? Gut, in der Mathematik hat obige Schreibweise eine etwas andere Bedeutung, nämlich, dass var3 dem Wert von var1 vermindert um den Wert von var2 entsprechen soll – es ist damit mathematisch gesehen eine Zustandsbeschreibung. Da Computer mit so etwas aber in der Regel nicht klarkommen, wird hier einfach die Bedeutung umdeklariert: var3 soll den Wert annehmen, der sich aus der Subtraktion von var1 und var2 ergibt; damit haben wir eine Anweisungsfolge und keine Zustandsbeschreibung mehr. Wer jetzt der Meinung ist, dass das doch etwas Haarspalterei und am Ende das Gleiche wäre, dem sei dieses Beispiel ans Herz gelegt. Die folgenden beiden Zeilen sind so direkt hintereinander geschrieben in der Mathematik unsinnig:

x = 4

x = x - 1

Die Variable x kann in der Mathematik nicht gleichzeitig den Werten 4 und 3 entsprechen. In der Informatik sieht das allerdings anders aus, da wir es hier mit zwei voneinander getrennten Anweisungen zu tun hätten; zudem ist eine Variable in der Informatik etwas anderes als eine Variable in der Mathematik, da sie bei ersterem eine Stelle im Speicher, bei letzterem aber ein bestimmtes Konzept (etwa einen Wert) symbolisiert. Der folgende Code in der Informatik führt also dazu, dass die Variable x zuerst den Wert 4 und dann den Wert 3 annimmt; man spricht auch von einer Zuweisung. Ich verwende hier übrigens anstatt des in der Informatik oft üblichen Gleichheitszeichens einen Pfeil, um den Unterschied deutlicher zu machen; in gängigen Programmiersprachen wird der Pfeil (leider) durch das Gleichheitszeichen dargestellt (aber das nur am Rande):

(1)       x ← 4;
(2)       x ← x – 1;

Wer sich jetzt fragt, warum ich diesen Unterschied zwischen Mathematik und Informatik so explizit erwähne: eben dieser Unterschied sorgt dafür, dass Mathematiker ohne Informatik-Ausbildung häufig Probleme haben, die Ideen der Programmierung zu verstehen; ebenso ergeht es Programmieranfängern, denen der Unterschied nicht explizit erläutert wird, da sie ihre im Mathematikunterricht erlernten Denkprinzipien auf ein dafür nicht geeignetes Gebiet (eben die Informatik) anwenden wollen.

Damit haben wir gleichzeitig ein wichtiges Verständnisproblem geklärt und unsere ersten Strukturen höherer Programmiersprachen – die Zuweisung und die Notation mathematischer Operationen – kennengelernt. Nur um noch einmal sicherzugehen, dass jeder das eben geschriebene auch verstanden hat, noch einmal die beiden obigen Codezeilen als Assemblercode (ja, ein moderner Assembler würde das wegoptimieren, aber darum geht es hier ja nicht):

(1)       mov x, 4
(2)       mov al, x
(3)       sub al, 1
(4)       mov x, al

An dieser Stelle seien noch schnell zwei wichtige Begriffe eingeführt, die zur Erklärung von Strukturen innerhalb einer Programmiersprache von Bedeutung sind. Der Begriff der Anweisung (engl. statement) wurde bereits erwähnt und bezeichnet eine in sich abgeschlossene Aktion, die unabhängig von den umgebenden Anweisungen ausgeführt werden kann; die Zeilen x ← 4 und x ← x-1 sind Beispiele für derartige Anweisungen. Eine Anweisung setzt sich immer aus einem oder mehreren Ausdrücken (engl. expression) zusammen. Ein Ausdruck stellt dabei eine Operation dar, die einen Wert liefert, etwa das Ergebnis einer Subtraktion; x-1 wäre so ein Ausdruck, aber auch die Konstante 4, da auch sie einen Wert liefert – eben den Wert 4. Ich werde im Folgenden diese beiden Begriffe konsequent nach dieser Definition verwenden; dem Leser sei also geraten, dem gewählten Begriff Aufmerksamkeit zu schenken.

Und wenn wir schon einmal bei Begriffserklärungen sind, können auch gleich zwei weitere häufig verwendete Wörter erklärt werden: Syntax und Semantik. Die sind allerdings weniger spektakulär: mit Syntax ist die Art und Weise gemeint, wie Code aufgeschrieben wird und ist vergleichbar mit der Orthographie und Grammatik einer natürlichen Sprache. Jede Programmiersprache definiert ihre eigene Syntax, also eine bestimmte Form, wie Konstrukte (also zum Beispiel Anweisungen und Ausdrücke) zu notieren sind. Demgegenüber steht die Semantik, welche den Inhalt des notierten Codes beschreibt, etwa, was der Ausdruck x-1 genau bedeuten soll; die Semantik entspricht also ganz einfach dem Bedeutungsinhalt natürlicher Sprache. Beide Begriffe werden uns ab und zu begegnen, sollten also verinnerlicht werden.

So, das liest sich zwar ganz schön, aber allein mit Zuweisungen und Rechnungen ist natürlich kein Blumentopf zu gewinnen (geschweige denn, ein komplexes Programm zu schreiben). Für erfolgreiches Programmieren braucht man natürlich noch etwas mehr; zum Beispiel Möglichkeiten, den Programmfluss zu steuern. Wir erinnern uns: im Assembler-Code gab es die Anweisung jump, mit deren Hilfe unbedingt (immer) oder bedingt (nur bei Gültigkeit einer bestimmten Bedingung) an eine bestimmte Stelle im Programmcode gesprungen werden kann. Nun könnte man diese Anweisung auch in einer höheren Programmiersprachen verwenden (und in der Tat lebt sie hier in Form der goto-Anweisung fort), verzichtet aber in der Regel aus Gründen der Übersichtlichkeit darauf. Stattdessen greift man hier auf sogenannte strukturierte Anweisungen zurück. In der Regel möchte man zwei Dinge mit Sprüngen erreichen (wie es bereits im Assemblercode demonstriert wurde): eine Verzweigung, so dass ein bestimmter Codeteil nur ausgeführt wird, wenn eine bestimmte Bedingung zutrifft; und eine Wiederholung, so dass ein Codeteil mehrere mal ausgeführt wird.

Zuerst zur Verzweigung, der sogenannten if-Anweisung. Sie besteht aus zwei Bestandteilen: der Bedingung und dem Körper. Die Bedingung ist ein Ausdruck, welcher den Wert true (wahr) oder false (falsch) annehmen muss; der Körper ist eine Folge von Anweisungen, die genau dann ausgeführt wird, wenn die Bedingung zu true evaluiert (das heißt, den entsprechenden Wert annimmt). Diese Struktur heißt Verzweigung, da sie den Programmfluss in zwei mögliche Zweige aufbricht, von denen mal der eine, mal der andere durchlaufen wird. Ein einfaches Beispiel sieht so aus:

(1)       if x > 1:
(2)          x ← 1
(3)          y ← 5

Die beiden Zuweisungen in den Zeilen 2 und 3 werden nur dann ausgeführt, wenn die Variable  x einen Wert größer als 1 besitzt. Da es oft auch nötig ist, nicht nur im Fall der zutreffenden Bedingungen, sondern auch im Gegenfall bestimmten Code auszuführen, wird die if-Anweisung um einen else-Zweig erweitert. Erweitern wir obiges Beispiel, ergibt sich dadurch zum Beispiel der folgende Code (der hoffentlich selbsterklärend ist):

(1)       if x > 1:
(2)          x ← 1
(3)          y ← 5
(4)       else:
(5)          x ← 0
(6)          y ← 2

Neben den Verzweigungen sind Wiederholungen, auch Schleifen genannt, ein wichtiges Element der strukturierten Programmierung. Grundlegend werden zwei Arten von Schleifen unterschieden: die bedingungsgeprüften bzw. while-Schleifen und die Zähl– bzw. for-Schleifen. Während
while-Schleifen so lange laufen, wie eine bestimmte Bedingung erfüllt ist, zählen for-Schleifen entsprechend ihrem Namen eine bestimmte Anzahl von Durchläufen. Syntaktisch sieht das etwa so aus:

(1)       while x > 1:
(2)          x ← x – 1
(3)          y ← y + 1
(4)
(5)       for i from x to y:
(6)          z ← z + i

Die erste Schleife läuft so lange, wie die Variable x noch größer 1 ist und reduziert in jedem Durchlauf x um 1 und erhöht y gleichzeitig um 1; die zweite Schleife zählt den Wert i einfach von x nach y hoch und addiert ihn dabei immer auf die Variable z. Wer sich an seine Mathematik-Zeit erinnert: letzteres wurde auch gern mit dem Summenzeichen ∑ notiert.

Nun fehlt nur noch eine Programmstruktur, dann haben wir die wichtigsten und grundlegendsten Dinge für das vernünftige Programmieren zusammen. Glücklicherweise sollte das letzte Konzept allen bereits aus der Mathematik bekannt sein: die Funktionen. In der Mathematik hat es sich als günstig erwiesen, häufig benutzten oder sehr komplizierten Formeln (Ausdrücken) einen Namen zu geben, unter welchem sie schnell und für alle verständlich benutzt werden können. Die bekanntesten Vertreter hierfür sind zweifelsohne die trigonometrischen Funktionen zur Berechnung des Sinus, Cosinus und Tangens. So etwas wie sin(π) hat sicher jeder schon einmal gesehen; hinter dem sin verbirgt sich aber nichts anderes als die reichlich komplexe Sinus-Funktion (für Details bitte hier klicken) – man hat ihr also einen Namen gegeben, um sie einfacher ansprechen zu können. Wichtig ist auch die Beobachtung, dass der Sinus-Funktion ein Wert mitgegeben werden muss, auf welchem sie operiert (zum Beispiel das Pi); natürlich können hier nicht nur konkrete Zahlen eingegeben werden, sondern beliebige Ausdrücke und Variablen; so wird etwa der Tangens gerne folgendermaßen definiert:

tan(x) = sin(x) / cos(x)

In der Informatik wird dieses Konzept der Funktionen aufgegriffen und erweitert. Anstatt nämlich lediglich als kürzerer Name für einen komplizierten Ausdruck zu dienen, können Funktionen in der Informatik ganze Anweisungsfolgen vereinen. Dies wird insbesondere dann benutzt, wenn ein komplexerer Code an verschiedenen Stellen im Programm benutzt werden soll; anstatt ihn immer wieder zu schreiben, wird er einmal als Funktion definiert und kann dann an beliebiger Stelle verwendet werden. Praktisch könnte das etwa so aussehen (die Erklärung folgt wie immer unter dem Code):

(1)       abs(x):
(2)         if x > 0:
(3)           return x
(4)         else:
(5)           return -x

In diesem Beispielcode wird eine Funktion abs definiert (man spricht von einer Funktionsdefinition oder Funktionsdeklaration), welche den Absolutwert eines gegebenen Wertes x (also den immer positiven Wert) berechnen soll; den Wert x nennt man Parameter der Funktion abs; eine Funktion kann beliebig viele Parameter (auch keinen) erfordern. Da eine Funktion in der Informatik anders als in der Mathematik nicht zwangsläufig nur einen Ausdruck, sondern eine ganze Anweisungsfolge markiert, muss explizit erwähnt werden, zu welchem Wert die Benutzung der Funktion führen soll. Das erfolgt folgerichtig über die return-Anweisungen in den Zeilen (3) und (5): sie geben einfach an, dass entweder der übergebene Wert selber oder – falls er negativ ist – die Negation davon zurückgegeben, also als Ergebnis der Auswertung der Funktion verwendet werden soll. Benutzt kann sie nun ganz so werden, wie wir es aus der Mathematik kennen, also etwa folgendermaßen:

(1)       b ← abs(a)
(2)       c ← abs(b)
(3)       d ← abs(42)
(4)       e ← abs(-1337)

Man spricht hier von einem Funktionsaufruf – die Funktion abs wurde in diesem Code 4 mal aufgerufen. Die an die Absolutwert-Funktion übergebenen Werte a, b, 42 und -1337 nennt man Argumente des Funktionsaufrufes. Und weil es so wichtig ist, wiederhole ich es noch einmal: die beim Aufruf einer Funktion übergebenen Werte heißen Funktionsargumente, die bei der Deklaration der Funktion verwendeten Variablen heißen Parameter – das wird gerne durcheinandergebracht, daher der explizite Hinweis. Mitlesende Nichtinformatiker bitte ich an dieser Stelle, den Artikel noch einmal genau zu lesen und alle Begrifflichkeiten und Bedeutungen zu verinnerlichen – sie werden für die Zukunft wichtig sein (außerdem bitte ich, den Bildermangel zu entschuldigen – Programmiergrundlagen sind einfach kein Thema, dass sich gut bebildern ließe).

So, da nun die grundlegenden Begriffe der modernen Programmierarbeit geklärt sind, können wir uns in zukünftigen Artikeln ins Getümmel stürzen und uns den Feinheiten der Informatikwelt widmen. Ich kann schon versprechen, dass es spannend werden wird!

Kommentare (46)

  1. #1 Rudi P aus S
    September 20, 2011

    Danke Marcus,

    für diesen Kurs! Bis jetzt ist es für mich Nichtinformatiker gut verständlich.
    Bin schon gespannt wie es weiter geht.

    lg, Rudi

  2. #2 nihil jie
    September 20, 2011

    @Marcus

    sehr schöne Artikel gibt es immer hier bei dir… ich lese immer fleißig mit, und auch ab und mal muss ich hier ein Lob loswerden 😉 Obwohl ich auch schon seit Jahren am Programmieren bin und viel Dinge für mich eigentlich ein “alter Hut” sind, finde ich die Artikel dennoch spannend.

    lass dich bloß nicht entmutigen weiter zu machen 😉

  3. #3 Marcus Frenkel
    September 20, 2011

    @Rudi P aus S
    @nihil jie
    Danke für das Lob. 🙂

    Entmutigt bin ich keineswegs, es läuft ja gut. 😉
    Und wenn jetzt so langsam die etwas schwierigeren Themen kommen (vor allem, wenn es nachher in Richtung Algorithmen geht), erhoffe ich mir ja sogar noch ein paar Fragen in den Kommentaren. 😉

  4. #4 Jan von nebenan
    September 20, 2011

    Hey, das ist wirklich eine schöne Einführung in die Hochsprachen der Informatik. Wenn mich das nächste mal jemand fragt, was eigentlich eine Programmiersprache ist, verweise ich einfach hierhin. 🙂

    Wer sich für die Entwicklung der verschiedenen Sprachen interessiert, dem empfehle ich übrigens dieses coole O’Reilly-Poster: https://oreilly.com/news/languageposter_0504.html (dort auch als PDF verlinkt). Leider ist es inzwischen nicht mehr ganz aktuell…

  5. #5 Marcus Frenkel
    September 20, 2011

    @Jan von nebenan
    Schöne Grafik, danke für den Link. 🙂
    Sie ist hinreichend aktuell, als dass die schlimmsten Verbrechen an Sprachen noch mit drin sind. 😉

  6. #6 Sven Türpe
    September 20, 2011

    … in gängigen Programmiersprachen wird der Pfeil (leider) durch das Gleichheitszeichen dargestellt …

    Und in einigen davon übersetzt der Compiler klaglos solchen Code in ein ausführbares Programm:

    #include <stdio.h>
    int main(int argc, char *argv[]) {
            int x = 0;
            if (x=x-1) {
                    printf("foo\n");
            }
            else {
                    printf("bar\n");
            }
            if (x=x+1) {
                    printf("foo\n");
            }
            else {
                    printf("bar\n");
            }
            return 0;
    }
    

    Das Programm liefert die Ausgabe:

    foo
    bar
    

    Irgendwie bin ich froh, dass heute niemandem mehr wegen Hexerei der Scheiterhaufen droht.

  7. #7 Marcus Frenkel
    September 20, 2011

    @Sven Türpe
    Das “leider” bezog sich unter anderem genau darauf. 😉

  8. #8 rolak
    September 21, 2011

    Das Problem, das viele Mathematiker und sonstige Anfänger mit ‘=’ haben ist, daß sie davon ausgehen, daß dieses Zeichen aufgrund der hohen Ähnlichkeit mit dem im Rahmen der Schule schon kennengelernten Zeichen bedeutungs-identisch ist. Allerdings ist das in keiner Weise automatisch so (es kann so sein), sondern grundsätzlich ist ein terminales Symbol in einer Programmiersprache durch deren Definition (meist EBNF + Semantik) festgelegt, nicht etwa durch Alltagsgebrauch. Denn eine Programmiersprache ist eine Fremdsprache wie andere auch, nur halt üblicherweise für romantische Lyrik extrem schlecht geeignet.

    Daraus folgt daß Leute -wie oben Sven Türpe- (bei C und Verwandtschaft) die Unterschiede zwischen Zuweisungs-‘=’, Vergleich-‘==’ und Alltags-‘=’ so schlecht lernen können, daß sie immer Probleme haben werden. Bei anderen Fremdsprachen ist diese Thematik jedem klar (hoffe ich ;-), keiner beschwert sich beim großen Sprachschöpfer, daß im Englischen ‘gift’ ein Geschenk, im Deutschen eher eine Heimsuchung ist; daß im Amerikanischen ein ‘,’ die 1000er und ein ‘.’ den ganzzahligen Teil vom Rest trennt, während es hierzulande gerade umgekehrt ist.

    Wie erfolglos der Versuch einer Umgehung dieser sattsam bekannten Fallen sein kann, zeigt das Beispiel APL: Wer will schon zum Programmieren eine Zweittastatur, auch wenn der im post bevorzugte Pfeil tatsächlich implementiert ist… Trotz dieser Umsetzungsschwäche wird die Sprache zwar immer noch benutzt, aber mit Sicherheit nicht wegen dieses tollen Zeichensatzes.

  9. #9 Dr. Webbaer
    September 21, 2011

    Ich kann schon versprechen, dass es spannend werden wird!

    Es wird spannend? – Au ja! – BTW: Überschrift/URL verhunzt.

  10. #10 Marcus Frenkel
    September 21, 2011

    Korrigiert, danke.

  11. #11 Johannes
    September 21, 2011

    Guter Artikel, wobei ich die Sicht auf Variablen etwas einseitig finde.
    x = 4

    x = x – 1
    kann auch in manchen Programmiersprachen nicht sinnvoll sein. Allein die zweite Zeile macht in funktionalen Sprachen schon Probleme.

    Wenn man über Hochsprachen spricht, sollten zumindest die verschiedenen grundlegenden Konzepte der Hochsprachen vorgestellt werden. Wobei der erste logische Schritt von Assembler natürlich Imperative Sprachen sind.

    greatz Johannes

  12. #12 Marcus Frenkel
    September 21, 2011

    @Johannes
    Wir sind ja auch erst einmal bei den imperativen Sachen – funktionales kommt später (da es am Ende nur eine Spezialisierung des imperativen ist). Also alles mit der Zeit. 😉

  13. #13 Johannes
    September 21, 2011

    was mir gefehlt hat ist ein eindeutiger Hinweis darauf, das es sich in dem in diesem Artikel um einen ganz bestimmten Sprachtypen handelt, welcher sich aus der Rechnerarchitektur (bzw. dessen Assemblersprache) ergibt und nicht um einen allgemeinen.
    Insbesondere sind für mich imperative und funktionale Sprachen zwei völlig verschiedene Dinge, da beide ganz eigene Techniken erlauben. Wie zum Beispiel:
    Funktionen als Argumente und Currying in Funktionalen Sprachen sowie Referenzen in Imperativen.
    Weiter unterscheiden sich beide Typen grundlegend in dem Schleifenverhalten (Stichwort Rekursion/ While- und For-Schleife)

    Wenn man einen Sprachtypen als Speziallfall eines anderen bezeichnen möchte, so geht dieses meiner Meinung nach am ehesten bei OO-Sprachen und Imperativen, wobei hier die OOs ganz klar den Speziallfall darstellen. (Selbst dieser Vergleich bereitet mir aber etwas Bauchschmerzen, da sich viele Konstruktionen nicht ohne Aufwand umsetzen lassen).

    Wiederrum andes könnte man natürlich argumentieren, dass jeder turingvollständige Sprachtyp der Speziallfall eines anderen turingvollständigen Sprachtypes ist, da dieser sich im Zweifelsfall emulieren lässt. Dieser Vergleich geht aber am Kern der Programmierspachen vorbei.

    greatz Johannes

  14. #14 Marcus Frenkel
    September 21, 2011

    @Johannes
    Sie gehen hier von Ihrem (vermutlich bereits erweiterten) Standpunkt aus – Sie kennen schon mehrere Konzepte und wissen daher um die Unterschiede des ganzen. Der Artikel ist allerdings eher für Leute gedacht, die (noch) nicht programmieren können und daher auch noch gar keine Ahnung davon haben, das es überhaupt verschiedene Konzepte bringt. Es bringt relativ wenig, gleich zu Anfang zu erzählen, dass es imperatives, funktionales und objektorientiertes gibt, wenn noch nicht einmal klar ist, was programmieren überhaupt bedeutet. Für einen professionellen Programmierer finden sich hier wenige high-level-Informationen, das gebe ich zu – das ist aber auch gar nicht das Ziel. Ich kann ja schlecht das Currying erwähnen, bevor ich erklärt habe, was Funktionen eigentlich sind.

    Und ja, auch OO ist ein Spezialfall des imperativen Paradigmas; das einige Konzepte nur aufwändig umzusetzen sind, steht da ja überhaupt nicht zur Debatte. Strukturierte (imperative) Programmierung ist am Ende auch nur eine Spezialisierung der unstrukturierten Programmierung, indem neue Befehle eingefügt wurden, mit denen Standardstrukturen (z.B. Schleifen) angenehmer notiert werden können – am Ende wird aber trotzdem alles auf Maschinencode heruntergebrochen, und der ist bei strukturierter Programmierung der gleiche wie bei unstrukturierter.

    Übrigens sind Funktionen als Argumente und Currying nun definitiv nicht auf die funktionalen Sprachen beschränkt, genausowenig wie Referenzen auf die imperativen Sprachen – sie kommen dort nur jeweils am häufigsten vor, aber nichts spräche dagegen, sie auch im jeweils anderen Paradigma anzuwenden (was mit Funktionsreferenzen z.B. ohnehin häufig gemacht wird). Warum künstlich Schubladen erzeugen, wo keine notwendig sind?

  15. #15 rolak
    September 21, 2011

    ..wobei noch anzumerken wäre, daß ‘funktional’ nicht das Gegenteil von ‘imperativ’ ist, nicht als Paradigma, schon gar nicht bezüglich irgendeiner Sprache. Wie schön und glatt sich die verschiedenen Ansätze mischen wird im wiki hochverlinkt beschrieben.

    Außerdem geht es hier -wenn ich es richtig interpretiere- um eine einführende Übersicht, nicht um die eierlegende Wollmilchsau des Programmiersprachenlehrgangs.

  16. #16 Marcus Frenkel
    September 21, 2011

    @rolak
    Volle Zustimmung (in allen Punkten). 😉

  17. #17 Johannes
    September 21, 2011

    Natürlich als Einführung wird man eher verwirrt wenn man gleich mit diesen Details konfrontiert wird. Mir ist vollkommen klar, dass der Großteil der von mir erwähnten Dinge in einem Einführungsartikel keine Rolle spielt (spielen sollten). Das geht auch etwas an meiner Kritik vorbei. Mir ging es nur darum klarzustellen, dass es weitere Paradigmen gib und dass man, je nach Ansatz, ein geeignetes Einstiegsparadigma gibt.
    Dass sich aus dem Aufbau der Beiträge der imperative Stil als naheliegend erweist sehe ich genauso. Ein mathematisch motivierter Einsgtieg hätte hingegen eher zu funktionalen Sprachen geführt.

    Mir ging es auch nicht darum Schubladen zu erzeugen, obwohl diese öfters zutreffen. Aber natürlich sind die meisten modernen Hochsprachen Hybridsprachen
    (Python erlaubt fast jedes gewünscte Paradigma, Funktionsreferenzen sind auch wie schon erwähnt weit verbreitet,…).
    Anderseits ist es meiner Meinung nach grade am Anfang sinnvoll diese Paradigmen zu unterscheiden. Einerseits da es auch ‘reine’ Sprachen gibt (z.b. Lisp oder Basic oder ‘historische’ Sprachen), anderseits weil sich viele Dinge nicht auf Assemblerebene erläutern lassen (wie man Funktionszeiger auf einen sehr niedrigen Level mit getrenntem Daten und Programmspeicher realisiert ist mir z.b. auf Anhieb nicht klar).

    Noch ein Wort zu Referenzen, wenn man OO Spachen als Speziallfall der imperativen betrachtet, so sehe ich nicht wo diese (außer in Hybridsprachen) eine Rolle spielen. In funktionalen Sprachen tauchen Referenzen maximal als Verweis auf ein Listenelement auf, wobei es sich aber nicht um eine Referenz im Sinne als Verweis auf eine Speicheraddresse handelt. Ansonsten sehe ich keinen Grund (und keine Möglichkeit) für Referenzen in funktionalen Sprachen.
    Man sollte aufpassen, dass man nicht die Möglichkeiten einer Sprache mit deren Realisierung verwechselt oder gleichstellt.

    greatz Johannes

  18. #18 Marcus Frenkel
    September 21, 2011

    Also ich habe bisher ganz ehrlich noch keine Situation gehabt, wo ich die Unterscheidung der verschiedenen Programmierparadigmen als sinnvoll erachtet hätte. Vielleicht hätten Sie dazu ein kurzes Beispiel?

  19. #19 Johannes
    September 21, 2011

    In der Einführung in die grundlegenden Programmiertechniken sehe ich definitiv Gründe zwischen verschiedenen Paradigmen zu unterscheiden um die jewaligen Stärken und Schwächen der verschiedenen Paradigmen zu lernen.
    Dies hilft meiner Meinung nach um strukturierter an spätere Probleme ranzugehen, da hier nicht mehr Schema F angelegt wird, sondern erst geprüft werden sollte mit welcher Strategie sich das Problem am besten lösen lässt.
    Ob verschiedene Paradigmen nun verschieden Programmierspachen bedeuten, oder aber mit der selben Sprache möglich sind spielt in diesem Fall keine Rolle.

    greatz Johannes

  20. #20 Marcus Frenkel
    September 21, 2011

    Ob verschiedene Paradigmen nun verschieden Programmierspachen bedeuten, oder aber mit der selben Sprache möglich sind spielt in diesem Fall keine Rolle.

    Das spielt meiner Meinung nach schon eine Rolle, und zwar aus dem Grund, weil viele Leute eher “sprachorientiert” sind, heißt, sie loben eine Sprache über alles und finden andere dafür grässlich; dementsprechend ist ihre Paradigmen-Grenze auch eine Sprach-Grenze mit dem Ergebnis, dass wir zum Browser-War und OS-War auch einen Language-War haben.

    Auf der anderen Seite beschneidet man sich auch selber, wenn man sich zur Lösung eines Problems auf ein Paradigma einer Sprache (so sie denn eine Multiparadigmensprache ist) beschränkt und die anderen außen vor lässt, obwohl sie einen wertvollen Beitrag zur Lösung bieten könnten. In dem Moment aber, wo man bei der Vermittlung der Grundlagen schon eine harte Trennung durchführt, hat man meiner Erfahrung nach bei vielen Belehrten einen dauerhaften Zaun im Gehirn festgesetzt, den sie nie wieder loswerden und der immer ihr Denken beeinflusst – Schubladendenken immer. Sicher ist das nicht bei allen so, aber auch nicht bei wenigen.

  21. #21 Salted Polly-Works
    September 21, 2011

    @Sven Türpe: “…übersetzt der Compiler klaglos solchen Code in ein ausführbares Programm”
    @Marcus Frenkel: “Das “leider” bezog sich unter anderem genau darauf”
    @rolak: “…die Unterschiede zwischen Zuweisungs-‘=’, Vergleich-‘==’ und Alltags-‘=’ …”

    Als beruflich mit dem Programmieren befasster finde ich, dass man dieses Handwerk zuerst gründlich erlernen sollte, um zu verstehen, dass Namen und Symbole Schall und Rauch sind und eine ganz eigene Bedeutung zugewiesen bekommen können. Danach, so meine ich, kann man sich sehr schnell mit ‘==’ als Vergleich und auch mit ‘=’ oder ‘=:’ als Zuweisungsoperator versöhnen. Fehlt nur noch eine syntaktische und/oder semantische Einschränkung, um nach Möglichkeit Flüchtigkeitsfehler zu vermeiden.

    Abhilfe schafft unter Umständen die in der Öffentlichkeit meist unbekannte Sprache SALT (JavaScript-artig und proprietär, aber eben nicht die von Telix und auch keine HTML-Erweiterung) oder auch ersatzweise die Skriptsprache Lua in Pascal-ähnlicher Notation, ansonsten fast identisch.

    Die Standardzuweisung in einem Statement notiert sich name = expr und funktioniert auch tupelweise als Mehrfachzuweisung. Als Statement liefert diese Anweisung keinen Rechte-Seiten-Wert als Ergebnis und darf also nicht in Ausdrücken (expressions) eingebettet verwendet werden.

    Für Kettenzuweisung mit einem Ergebniswert gibt es einen Operator, und dies wird notiert als name1 := name2 := expr, und darf also z.B. in einer Bedingung verwendet werden. In if (x := x-1) würde dann das Ergebnis im booleschen Sinne als Wert 0 oder Wert nicht 0 interpretiert (also ähnlich wie das Bsp. in C, oder wie es in JavaScript wäre).

    Eine Vergleichsoperation wird auch hier wie in JavaScript als expr1 == expr2 notiert und liefert einen der boolesch interpretierten Werte 0 oder 1. Mit der Zusammenlegung von numerischen Werten mit Booleschen ist natürlich auch hier die Möglichkeit eines Fallstrickes gegeben.

    Aber im Grunde doch ganz brauchbar, da leistungsfähig.

  22. #22 engywuck
    September 22, 2011

    ich schließe mich der Aussage an, dass es manchmal schade ist, dass die Scheiterhaufen abgeschafft wurden… gerade C ist da ein Paradebeispiel für – idiotische Verwendung von = und == (statt beispielsweise := und =), Boolesche Werte als integer (0 als Wahr, 1 als Falsch, iirc) und so weiter. Wobei spätere Sprachen das dann mit === (wie == nur auch typidentisch) auf die Spitze getrieben haben.

    die Kritik an der Nichtnennung verschiedener Konzepte kann ich nicht nachvollziehen. Wir sind hier schließlich in Richtung zunehender Abstraktion unterwegs und letztlich ist jeder Rechner in seiner Hardware imperativ (Spezialfälle evtl ausgenommen, es soll ja Prozessoren mit OOP-Unterstützung in Hardware gegeben haben…). Damit ist aber automatisch Assembler imperativ und die ersten Hochsprachen, die weite Verbreitung fanden, waren dies auch. Und genau hier stehen wir gerade….

  23. #23 Dr. Webbaer
    September 22, 2011

    Daraus folgt daß Leute -wie oben Sven Türpe- (bei C und Verwandtschaft) die Unterschiede zwischen Zuweisungs-‘=’, Vergleich-‘==’ und Alltags-‘=’ so schlecht lernen können, daß sie immer Probleme haben werden.

    Ob Kollege Türpe dbzgl. unsicher dasteht, darf bezweifelt werden, aber -ein anderer Kommentator hat bereits dementsprechend vorgetragen- Namen, auch Namen von Operatoren sind Schall und Rauch und insofern ist es nur eine ergonomische Frage, wie Operatoren definiert werden. – Die Gleichheit des Zuweisungsoperators ‘=’ mit dem Vergleichsoperator ‘=’ scheint Dr. W unergonomisch, auch wenn der Kontext die Bedeutung immer klarstellt. Das selbe gilt für die Kodierung der Wahrheitsvariablen über 0 und -1.

  24. #24 rolak
    September 22, 2011

    Das WebbAerschen vesteht wie so oft eher gar nichts:

    • Wer sich wundert, daß ein syntaktisch korrektes Programm das aus der Semantik ableitbare Ergebnis liefert, ist unsicher. Keine Frage also bzgl Türpels Zustand, zweifele er lieber an sich selbst.
    • /=/==/.. Wenn er mit wenigstens einem offenen Auge meinen Kommentar nochmals begutachtet, wird er vielleicht höchst überrascht feststellen, daß es dort genau darum ging, daß dies nur Bezeichnungen für irgendeine Operation sind, deren Bedeutung nicht unbedingt mit dem Bekannten übereinstimmen. Auch ohne daß dies erst von wem auch immer noch extra herausgestellt werden müßte.
    • Zuweisungsoperator und Vergleichsoperator sind in diesem Beispiel (und fast überall) eindeutig nicht identisch.
      btw: Der Verfechter von einem Ungetüm wie COBOL redet bei solcherlei Kinkerlitzchen von ‘unergonomisch’? Lachhaft.
    • “boolsch 0/1” Ja was meint der Herr denn, wie in anderen Sprachen die symbolischen Werte ‘TRUE’ und ‘FALSE’ übersetzt werden? In Gummibärchen? Mal ganz abgesehen davon, daß bei derlei Abfragen generell =0/≠0 getestet wird…

    Ist nicht langsam Zeit für den Winterschlaf, auf daß wir wenigstens eine gewisse Zeit lang von diesem unsäglichen Quark verschont bleiben?

  25. #25 Dr. Webbaer
    September 22, 2011

    @rolak
    Könnten Sie mal ein wenig substanzieller werden, anstatt Befindlichkeiten herauszuhauchen?! – Wäre nett. Bisher liest Dr. W nur, dass Sie behaupten, dass Sven Türpe und andere Probleme hätten beim ‘=’ zwischen der Unterscheidung “Vergleichs-/Zuweisungsoperator”.

    Die Kodierung der “Wahrheit” in 0 oder 1 oder -1, je nach Sprache, setzt Dr. W als bekannt voraus. ‘TRUE’ und ‘FALSE’ sind in diesen Sprachen -Sie ahnen es- Konstanten, die mit 0 oder 1 oder -1 belegt sind. Die Kodierung erfolgt in jenen Sprachen über den Zahlenwert.

    Immer bestmöglich an der Sache bleben, rolak (slw. ugs. für ‘Rollkragenpullover’). Ansonsten wird Dr. W Sie auf seine Ignore-List setzen.

    MFG
    Dr. Webbaer

  26. #26 rolak
    September 22, 2011

    Nicht ich behaupte, Türpe zeigt selber auf – denn ohne ein Verständnisproblem würde er sich nicht über die klaglose Übersetzung eines syntaktisch korrekten Programmschnipsels beklagen. Soll ich besser Bildchen malen? look look, see see?

    Ansonsten wird Dr. W…

    ^^Jetzt zittern mir die Knie…

  27. #27 Dr. Webbaer
    September 22, 2011

    Nachtrag:
    Aja, Sie unterstellen stattdessen Türpsche Probleme i.p. Verwechslung beim ‘=’ und beim ‘==’ (Vergleich), ja gut. Und was soll das jetzt? – BTW: Dr. W bezog sich allgemein auf die Operatorenverhunzung und im Speziellen auf Salted Polly-Works’ Kommentar weiter oben.

    Und die Wahrheitskonstanten könnten natürlich so kodiert werden, dass sie nicht numerisch oder andersartig alterbativ ansprechbar sind – eigentlich wäre sowas auch zu erwarten.

  28. #28 Dr. Webbaer
    September 22, 2011

    Türpe hat sich ein Späßchen erlaubt, Kollego.

    MFG
    Dr. Webbaer (der sich jetzt ausklinkt)

  29. #29 Sven Türpe
    September 22, 2011

    Nicht ich behaupte, Türpe zeigt selber auf – denn ohne ein Verständnisproblem würde er sich nicht über die klaglose Übersetzung eines syntaktisch korrekten Programmschnipsels beklagen.

    Er beklagt sich gar nicht. Er stellt lediglich fest, dass eine analoge Konstruktion etwa in Java bereits an der strengeren Typisierung gescheitert wäre. Bereits der Compiler weigert sich dort, im if etwas anderes als boolean zu akzeptieren oder auf Operanden vom Typ boolean die Operatoren + und anzuwenden. Funktionieren würde noch die Verwechslung von Vergleich und Zuweisung, sofern die Typen passen, aber wer vergleicht schon Wahrheitswerte?

  30. #30 Sven Türpe
    September 22, 2011

    Falls sich übrigens jemand an Brainfuck versuchen möchte: https://repl.it/

  31. #31 rolak
    September 22, 2011

    Er stellt lediglich fest, dass eine analoge Konstruktion etwa in Java bereits an der strengeren Typisierung gescheitert wäre.

    Darum geht es ja — ist denn nicht ebenfalls erschütternd, daß ein sinnvoller Text in Farsi an einer auf Deutsch optimierten Maschine (my brain) schon am Zeichensatz scheitert?

    Wer Blödsinn respektive Sinnleeres als TopNews präsentiert, darf sich nicht wundern, wenn am selbstgezimmerten Sockel gesägt wird. Eine Sprache für schlecht lesbar zu halten ist eine des Geschmacks und somit eine Meinung. Im Gegensatz zu dem oben zu lesenden Operatorgeblubber, das nur aufgrund mangelnden Sprachverständnisses (nicht nur bzgl des ‘=’, sondern auch des ‘if’) zu einer aussageartigen Formalbeschwerde hochstilisiert wird.

  32. #32 michael
    September 22, 2011

    > Eine Sprache für schlecht lesbar zu halten ist eine des Geschmacks und somit eine Meinung.

    Man muss ja Herrn Türpe nicht leiden können, aber sein Genörgel, dass man solche C-Programme schreiben kann, ist in Ordnung.

    Habe genügend Fehler, die auf diesem Konstrukt beruhen, suchen dürfen:
    if (retVal = f()) {…} als Abkürzung für ‘if (0!= ((retVal = f())){..}’ ist zwar ok, aber ab und zu war dann halt doch der Vergleich gemeint.

  33. #33 emporda
    September 23, 2011

    @Marcus Frenkel
    hier geht es um Inhalte, die mit der Lösung von (technischen) Problemen auf dem Computer nur wenig zu tung haben. Ich habe die Coputerei 1964 in der TU-Braunschweig auf einer Zuse-23 angefangen, einem Röhren- und Diodenrechner mit 10 kB Kapazität für Compiler, Programm und Daten

    Ich habe über die Jahre in Assembler, Algol, Fortran, C und Basic programmiert, die letzte Sprache war mir die liebste. Was hier überhaupt nicht zum Ausdruck kommt, das sind die notwendigen Grundtechniken um mit Datenmengen umzugehen. Dazu gehören z.B. Sortierroutinen, Indzierungen (direkt, indirekt), statistische Verteilungsfunktion (Gauß, Student, Fisher), Matrixen und deren Invertierung, Regressionen, Funktionsanalysen usw.

    Ohne dieses Grundwerkzeug in der Programmierung kann man heute kein komplexes technische Problem lösen. Nur wenige der endlos vielen Hobbyprogrammierung haben davon einen Ahnung. Deswegen ist das was dann raus kommt, nur bessere Spielerei.

  34. #34 Engywuck
    September 23, 2011

    zum Thema true/false als integer:

    in vielen (modernen) Programmiersprachen sind true und false *explizit* Konstanten vom Typ “boolesch”. Integerwerte sind dagegen logischerweise integer und explizit *nicht* als Ersatz für true/false verwendbar. Je nach Implementierung kann das enorme Vorteile haben, da es dem Interpreter/Compiler freigestellt ist, was er im “Hintergrund” verwendet. Der Einfachheit halber werden auf Maschinenebene ziemlich sicher wieder integer verwendet, aber das muss nicht so sein *und* es könnten prinzipiell auch “27” für true und “35” für false verwendet werden… Ganz abgesehen davon, dass der Compiler prinzipiell auch einfach nur 1 Bit dafür nutzen braucht, eine Variable
    var feld : array[1..8] of boolean
    kann dann beispielsweise bei Optimierung auf minimalen Speicherverbrauch auf die Verwendung *eines* bytes reduziert werden (und bei Zugriff auf feld[3] dann die entsprechende Bitmaske verwenden). mach das mal in C….

    Die Verwendbarkeit von integerwerten als boole-Ersatz in C und verwandten Programmiersprachen ist letztlich das unnötige “leaken” eines Implementierungsdetails, was aber zu schwer auffindbaren üblen Fehlern führt und den Comiplerherstellern dauerhaft auferlegt, an diesem Punkt nichts ändern und vor allem optimieren zu können, egal welche Hardware-Architektur “drunter” liegt. Zumal diese verwendung von integer statt boolean zum Kompilierzeitpunkt abfangbar wäre (wenn es ein runtime-Fehler wäre könnte ich’s ja evtl. verstehen)

    Und weil ich grad am rumhacken auf Programmiersprachen bin: ich “liebe” ja die Fehler, die auftreten, weil in gewissen (Skript-)Sprachen (zuletzt ists mir in PHP passiert) ein Vertipper gleich eine neue Variable erzeugt. Also (pseudocode)
    hallo = “Hallo”;
    hallowelt = hello & ” Welt!”;
    na, was steht in “hallowelt”? 😀

    Es muss ja nicht unbedingt sein, dass man wie in Pascal alle Variaben “oben” deklarieren muss, aber beim erstmaligen Verwenden ein “var” davorhängen, um klarzustellen “hier kommt eine *neue* Variable” wäre gelegentlich ganz praktisch zur Fehlersuche…. Wozu hat man Hochsprachen, wenn nicht, um Fehler zu verhindern?

  35. #35 rolak
    September 24, 2011

    Hi michael, das Genörgel wäre ok, wenn der präsentierte code nicht den Regeln der Sprache C entsprechen würde. So allerdings entspricht es einem Zuschauerzwischenruf ‘Was soll denn das Englisch hier, redet doch {deutsch| französisch| italienisch| rätoromanisch}, wir sind in der Schweiz’ bei jener Podiumsdiskussion.

    Habe genügend Fehler, die auf diesem Konstrukt beruhen, suchen dürfen

    Wer hat denn das Gerücht in die Welt gesetzt, daß C der Kandidat für compiler-unterstütztes Abfangen von typischen Anfängerfehlern ist? Wie kann überhaupt dieser Gedanke aufkommen, wenn es extra ein lint zur Syntaxanalyse und wenigstens partiellen statischen Fehlersuche gibt? Das Designziel war, möglichst kompakt systemnahe Software zu schreiben. Nirgendwo war vor 40 Jahren bei der Entwicklung des unix-development-tools die Rede von Benutzerfreundlichkeit, guter Lesbarkeit, Lernsprache oder irgendetwas in der Richtung.

    if (retVal = f()) {…} als Abkürzung für ‘if (0!= ((retVal = f())){..}’ ist zwar ok, aber ab und zu war dann halt doch der Vergleich gemeint

    ..ist eher sinnleer, da in beiden Fällen der Vergleich mit 0 kodiert ist und nicht etwa ersteres eine Abkürzung darstellt, sondern das Zweite eine unnötige Aufblähung (btw: Vor dem zweiten retVal ist ein ‘(‘ zuviel, hätte lint gefunden ;-). Oder meinst Du “war if (retVal == f()) {…} gemeint” – dann verweise ich Dich auf den vorigen Absatz, nicht ohne zu erwähnen, daß aus dem Kontext oder Kommentar üblicherweise klar ersichtlich ist, ob ‘=’ oder ‘==’ der richtige Operator ist. Das Pascal-Äquivalent wäre die Forderung, statt “if boolVal then..” zu schreiben “if (boolVal=TRUE) then..”; und lach nicht, bisher habe ich unzählige Beispiele dafür gelesen.
    Habe ich es geschafft, den Kern-Mumpitz des Diskussionsaufhängers deutlich zu machen?

  36. #36 tritonus
    September 24, 2011

    @ rolak:

    “Wer hat denn das Gerücht in die Welt gesetzt, daß C der Kandidat für compiler-unterstütztes Abfangen von typischen Anfängerfehlern ist?” […] “Das Designziel war, möglichst kompakt systemnahe Software zu schreiben. Nirgendwo war vor 40 Jahren bei der Entwicklung des unix-development-tools die Rede von Benutzerfreundlichkeit, guter Lesbarkeit, Lernsprache oder irgendetwas in der Richtung.”

    Ich sehe das ähnlich. Benutzerfreundlichkeit ist ein Kriterium für GUIs, nicht für den zugrundeliegenden Code. Die notwendige Komplexität eines Problems läßt sich nicht reduzieren. Das weitere – in welcher Sprache schreiben – ist eine Frage persönlicher Vorlieben.

  37. #37 Dr. Webbaer
    September 24, 2011

    Wobei unklar bleibt, warum eine effiziente Unterstützung des vielleicht auch anfängerhaften Nutzers der Effizienz der SW entgegenstehen soll. – Wenn es um das “Soll” geht, ist die Historie egal. – Und Türpes kleine Nachricht hatte einen klaren Bezugspunkt im Artikeltext.

    MFG
    Dr. Webbaer

  38. #38 michael
    September 25, 2011

    @rolak
    > Wer hat denn das Gerücht in die Welt gesetzt, daß C der Kandidat für compiler-unterstütztes Abfangen von typischen Anfängerfehlern ist? Wie kann überhaupt dieser Gedanke aufkommen, wenn es extra ein lint zur Syntaxanalyse und wenigstens partiellen statischen Fehlersuche gibt?

    Niemand. Ausserdem sind sowas keine Anfängerfehler, sondern Flüchtigkeitsfehler.

    > die Rede von Benutzerfreundlichkeit,

    Benutzerfreundlichkeit? Es geht um Wartbarkeit und um schnelle Fehlersuche durch NichtEntwickler.

    > nicht ohne zu erwähnen, daß aus dem Kontext oder Kommentar üblicherweise klar ersichtlich ist,

    Ist es nicht das Mantra der C-Progammierer, dass ihr Code selbst dokumentierend ist und daß das, was hart zu schreiben war, auch schwer zu verstehen sein muß?

    > Nirgendwo war vor 40 Jahren bei der Entwicklung des …

    Hat niemand gesagt. C hat sich aber auch weiterentwickelt, die Compiler technolgie auch, daher hätte man ruhig die Sprachen etwas aufpolieren können.

  39. #39 michael
    September 26, 2011

    @rolak

    Wider die Kollegen! Sowie der ‘C no Evil’ Link auf der Seite.

  40. #40 rolak
    September 26, 2011

    Hi michael:

    /Anfänger-Flüchtigkeit/ Das Eintippen des Falschen ist ein Flüchtigkeitsfehler, das Nichterkennen des falschen Operators an Auswirkung und allererstem srccheck nach Fehler ist der Anfängerfehler. Denn wenn das nicht ins Auge springt, fehlt entweder Übung oder Grundsätzliches.

    /Es geht um Wartbarkeit und um schnelle Fehlersuche durch NichtEntwickler./ Um was es Dir geht, ist mir längst deutlich geworden, doch das Gewünschte gilt halt nicht für c. Und es ist Unsinn zu erwarten, daß sich eine falsch ausgesuchte Programmiersprache daran hält. Die falsche Wahl ist übrigens schon der erste Anfängerfehler – es gibt ausreichend streng überwachte und auf Sicherheit bedachte Sprachen wie oberon, ada und Konsorten.

    /Ist es nicht das Mantra…/ Das erste ist Blödsinn da nichts automagisch dokumentierend ist, anders gesagt, man kann in jeder Sprache unwartbaren Mist verzapfen. Selbst bei der tangle/weave-Kombination unter {C}WEB ist es nicht der code, sondern eingebettete DokuSchnipsel, die die Dokumentation generieren.
    Das Zweite ist nur ein blöder Spruch, um noobs abzuschrecken. Vielleicht sollte der bzgl c und Ähnlichem wirklich mantraartig abgebetet werden, da die Abschreckung bisher offensichtlich nicht effektiv genug ist.

    /weiterentwickelte Sprachen/ Gibt es zu Hauf, aber das sind eben andere Sprachen, c bleibt auch als c# c.

    /C no Evil/ Was soll das sein? So eine Art Beschwerde, daß ein c-Compiler, der so mächtig sein soll, daß er alles für die Programmierung von Betriebssystemen Nötige kann (also schlicht alles, inkl srcgesteuert sein eigenes Verhalten drastisch ändern) unverschämterweise so mächtig ist, daß sich Random J User ins Knie schießen kann?

  41. #41 Sven Türpe
    September 26, 2011

    … nicht ohne zu erwähnen, daß aus dem Kontext oder Kommentar üblicherweise klar ersichtlich ist, ob ‘=’ oder ‘==’ der richtige Operator ist.

    Das ist noch mal ein ganz eigenes Problem der geringen syntaktischen Distanz von Konstrukten unterschiedlicher Semantik. Wenn man den Code ohne den Kommentar (wird gerne vergessen und gehört auch selten ans einzelne if) und ohne den Kontext (der im Kopf des Programmierers noch ganz klar war) zu lesen bekommt, hat man wenig Anhaltspunkte, ob das so gemeint war oder großer Blödsinn ist. Das macht die Wartung, Weiterentwicklung und Wiederverwendung nicht einfacher.

  42. #42 Sven Türpe
    September 26, 2011

    Benutzerfreundlichkeit ist ein Kriterium für GUIs, nicht für den zugrundeliegenden Code. Die notwendige Komplexität eines Problems läßt sich nicht reduzieren.

    Dann genügt es ja vielleicht, wenn die Entwicklerin über das Problem angestrengt nachdenken muss und nicht auch noch über die Vermeidung von Fehlern, die der Computer ohne weiteres selbst finden könnte, oder über die weniger intuitiven Folgen der Sprachdefinition. Wenn ich jemandem schwere Arbeit gebe, die nicht jeder machen kann, dann wäre ich doch schön blöd, minderwertige Werkzeuge bereitzustellen, oder?

    Aber mir soll’s recht sein, ich verdiene mein Geld mit den Programmierfehlern der anderen.

  43. #43 Dr. Webbaer
    September 27, 2011

    Aber mir soll’s recht sein, ich verdiene mein Geld mit den Programmierfehlern der anderen.

    Zumal der Consultant, hat er seine Ware verkauft, diese immer noch besitzt. – Auf Abnehmerseite ist dagegen Selbstkritik erforderlich und das Wissen um die Möglichkeit, dass der Consultant eine Lusche sein und bei ungünstiger Akzeptanz Schäden verursachen kann, die beträchtlich sind.

    Es ist ganz erstaunlich, was man hier aus Ihrem kleinen Codeschnipsel alles rausgeholt hat. – Schön jedenfalls der Hinweis auf die drei Ws weiter oben. – BTW, man kann auch mit COBOL glücklich werden…

    MFG
    Dr. Webbaer

  44. #44 michael
    September 27, 2011

    @rolak
    > das Nichterkennen des falschen Operators an Auswirkung und allererstem srccheck nach Fehler ist der Anfängerfehler.

    Ne, der Entwickler liest ja das, was er hatte schreiben wollen, nicht das, was er geschrieben hat. Wenn man den Kollegen dazu bittet, der sieht so was sofort, weils eben nicht der eigene Code ist. Ausserdem, wer hat schon Zeit für src-checks.

    >Die falsche Wahl ist übrigens schon der erste Anfängerfehler –

    Seit wann geht es hier um Freizeitprogrammierung.

    > /C no Evil/ Was soll das sein? So eine Art Beschwerde?

    Wenn Du zu faul zum klicken und lesen bist,.. .

  45. #45 rolak
    Oktober 2, 2011

    Frisch angeregt entsende ich ein kleines Photon, nein, kopiere einen der Zettel, die an die Wand hinter dem Monitor gepinnt sind:

    C – a language that combines all the elegance and power of assembly language with all the readability and maintainability of assembly language

  46. #46 michael
    Oktober 7, 2011

    OT und wohl nur für C-programmierer interessant.
    echo.c in unterschiedlichen Varianten.