FreeBSD in-depth Verständnis

Ich argumentiere einfach mal aus meiner Erfahrung:

Code:
Schule              | Studium Bachelor                     | Studium Master           | Post-Studium
                    |                                      |                          |
QBasic
Pascal ---
           Delphi
           PHP ----------------------------
                     Java -----------------------------      -------
                            MIPS 2000 ASM
                               Scheme
                                      sh -----------------------------------------------------------
                                           C ----              -------------------------------------
                                                awk ------------------------------------------------
                                                  Python--          -------             -----
                                                                       8051/52 ASM
                                                                            C++ --------------------

Angefangen hat es bei mir mit den Üblichen Lehrsprachen und später PHP in meiner Freizeit. Über Java wurde mir die OOP vermittelt. Das hatte Seiteneffekte, die ich heutzutage als schädlich ansehe. Primär, dass ich OO das für ein Sprachfeature hielt und Garbage Collection toll fand.

Die funktionale Progammierung mit Scheme hat mir gar nicht zugesagt. Eine Schleife programmiert man mit Tail-End Rekursion. Der Compiler/Interpreter macht dann wieder eine Schleife draus, weil Rekursion nicht skaliert (rühmliche Ausnahme ist bei O(log(n))) und langsam ist, da man damit Caching aus-hebelt. Das ist natürlich ganz Schick, denn rekursiver Code ist oft sehr einfach und gut verständlich (im Vergleich zur iterativen Variante, gerade wenn man durch Bäume navigiert). Blöderweise muss man dann aber auch wissen, was der Compiler optimieren kann. Denn wenn's nicht klappt fliegt es einem um die Ohren, da programmiere ich lieber gleich iterativ.

Python finde ich eigentlich schön. Inzwischen kommt mir aber immer wieder die Garbage Collection ins Gehege. Genau wie bei meiner letzten Begegnung mit Java. Wenn Java der Speicher aus geht gäbe es 3 Möglichkeiten:
- JVM bittet das OS um mehr Speicher
- JVM stoppt die Ausführung und wirft die Garbage Collection an
- JVM wirt OutOfMemoryException

Java macht natürlich letzteres, selbst wenn der Garbage Collector GB-Weise Daten weg zu räumen hat (KABUMM). Mehr Speicher holt sich Java nie. Python ist da schön flexibel. Es wird halt einfach langsam.

Kommen wir zu C, damit mache ich Low-Level Echtzeit zeug. Auf Plattformen auf denen die einzige Alternative Assembler ist. Wie schon gesagt - alternativlos, das ist einfach nicht wegzudiskutieren.

Dann wäre da noch C++. Damit mache ich Anwendungen bei denen es auf Performance ankommt. Klar kann man das auch in Java oder Python machen, ist dann halt bloß um Faktor 10 langsamer. Die Ausdrucksstärke von C++11 ist wie eine Droge von der man nicht mehr runter kommt. C++14 ergänzt das vielversprechend.

Immer wieder komme ich auf die Idee etwas mit Python zu machen und entscheide mich dann doch für awk. Für Dinge bei denen AWK nicht in Frage kommt, kommt für mich auch Python nicht in Frage. Das Zeug mit GC skaliert einfach nicht ausreichend.

Klar, bei 90% der Anwendungen ist das vollkommen unerheblich. Aber diese Anwendungen schreiben andere Leute.
 
Ich habe mein persönliches (95%) Nirvana nach jahrelangem Suchen und Probieren bei einer formal "alten" Sprache gefunden, Modula-3. Damit bin ich *erheblich* effizienter als mit C++ und das in mehr als einer Hinsicht, z.B. wegen der exzellenten Modularität. Dabei war mir auf meiner Suche immer wichtig, ein gutes Interface zu C zu haben; so sehr, dass ich Sprachen, die das nicht boten, gleich ausschloss. Zum einen wegen der vielen und teilweise ziemlich guten libraries, zum anderen wegen der Option, "hot-spots" in C mit optimaler perfomance machen zu können.
Meine Erfahrung: Ersteres war und ist richtig und nötig, letzteres kaum bis gar nicht; die Performance ist C-ähnlich.

Da in meinem Bereich 3SR (safety, stability, security, reliability) entscheidend ist, kommt mir entgegen, dass ich mit Modula-3 den größten Teil dessen habe, was Ada bietet, das aber ohne dessen viele weniger schöne Stellen (wie z.B. ca. 1000 Seiten Spec.). Dazu noch die sehr umfangreiche und von high-end Profis (noch bei DEC den Älteren unter uns sagt das noch was) geschriebene Standard library, die sehr stark zu Effizienz und Qualität beiträgt.
Bisher der wesentlichste Nachteil: Keine IDE (kratzt mich nicht) und kaum ein Editor, der das Syntax highlighting usw. draufhat. Aber das war eine Kleinigkeit; mein TextAdept kann das mittlerweile (und ich habe ihn auf FreeBSD ans Laufen gebracht).
Und, wer weiss, vielleicht arbeitet ja jemand an einer modernen Version mit DbC, Spec. interface und C backend ... ?

Vielleicht witzig: Auf meiner (noch immer andauernden) Suche nach "meiner" script-Sprache, die ich Dank Python ohne allzu großen Druck betreibe, merke ich immer wieder einen deutlichen Drall in Richtung C-ähnlich. Python ist wunneba, hat mir aber mittlerweile viel zu viel Batterien eingebaut (vulgo: Ist fett geworden).
 
High-Level Sprachen führen zu High-Level-Fehlern, Low-Level Sprachen zu Low-Level Fehlern.
Und es ist keiner per se schlimmer als der andere, da wo ein Low-Level Fehler Speicher rausrückt, der privat sein sollte,
da führt ein High-Level Fehler dazu, dass unberechtigte Nutzer alle Daten sehen können…

Das Problem mit Low-Lewel-Sprachen: man bekommt beides, sowohl Low- als auch High-Level-Fehler.
Für viele Anwendungsfälle ist das auch das große Problem von C: man ist mit so vielen Low-Level-Details beschäftigt, das die Produktivität der Entwickler sehr leidet.

Und dann wird Dir sowieso jeder erzählen, dass das was er kann, das beste ist.

Keineswegs. Ich kenne mich mit Java am besten aus und verdiene momentan mein Geld damit, halte Java aber bei weitem nicht für die beste Sprache (das war sie schon in den 90ern nicht).
Das wäre aber eher ein Thema für einen Weihnachtsurlaub-Monsterthread. ;)

Wenn du Code-Qualität willst, dann kommst du bei größeren Projekten nicht um Maschinen-unterstützte Analyse herum. Und da sieht's bei C mau aus.

Ein Aspekt, den viele Entwickler mit wenig Praxiserfahrung gerne übersehen. Die Sprache ist nur die halbe Miete.

Ein weiteres Problem ist Inkonsistenz. Nimm als Beispiel mal unit-tests. Die sind praktisch immer in der selben Sprache wie der Code geschrieben, was, nun ja, etwas blauäugig ist.

Ich sehe es eher als Vorteil, ein direktes Feedback zwischen Implementierung und Test zu haben, ohne große Schleifen drehen zu müssen. Ich würde eher bei den Integrationstests zu anderen Mitteln greifen, aber das hängt immer stark vom konkreten Einzelfall ab.

Vermutlich noch schlimmer aber ist die Spezifikationsseite. Denn es geht ja nicht nur darum, die Code Qualität zu prüfen, sondern auch darum zu prüfen, ob der Code leistet, was er leisten soll und nicht tut, was er nicht soll.

Stimmt, beim Requirements Engineering noch sehr großer Nachholbedarf besteht. Wobei die Spezifikation in 90% der Fälle auch von Natur aus ein bewegliches Ziel ist. Ich kann mich natürlich 10 Jahre ins stille Kämmerlein zurückziehen und die perfekte Spezifikation schreiben. Nach 10 Jahren wird sie nur höchstwahrscheinlich keinerlei Relevanz mehr besitzen, weil die Welt sich weitergedreht hat (Ausnahmen bestätigen die Regel).

Die nötigen Spezifikationen liegen heute praktisch immer irgendwo im Bereich "Hat jemand innem Editor (oder spreadsheet * grusel) aufgeschrieben" und "ham wir uns mal so ausgedacht" (die Entwickler). Nur: Wie willst du sowas Maschinen-unterstützt testen?

Mach' aus der Not eine Tugend. Entwickele in kurzen Iterationen, sichere deinen Code mit Unit- und Integrations-Tests ab und wenn die Software schließlich tut, was sie soll, hast du das Verhalten der Software mit deinen Tests spezifiziert.
Kein sauberes Vorgehen, aber die Welt ist nunmal dreckig - machen wir das Beste daraus.

Da gibt es noch weitere Probleme, das z.B., das beim unit test so manches emuliert wird, weil der Code halt nicht unter echten Bedingungen läuft.

Man kann es mit Mocks übertreiben, aber in der Praxis hat man nicht immer eine perfekte Testumgebung - das Kunststück ist es ja, trotzdem gute Software zu entwickeln. Das trennt bei den Entwicklern die Spreu vom Weizen.
 
Als Amateur mit geistesgeschichtlichem Hintergrund bin ich an Sprachen allgemein, nicht nur, aber eben auch, an Computersprachen als solche interessiert. Entsprechend habe ich in sicherlich 1-2 Dutzend Programmiersprachen jeweils kleinere Projekte realisiert um sie kennen zu lernen: Das reichte von ASM6800 und Forth (Atari/Mac) bis hin zu Smalltalk. Es ging mir also nicht darum "to get the job done". Natürlich entwickelt man dann im Laufe der Zeit so etwas wie persönliche Vorlieben. Perl würde ich nicht mit der Zange anfassen und wenn ich mal etwas in PHP machen muss, was leider gelegentlich notwendig ist, so mache ich das mit zusammen gebissenen Zähnen. Python habe ich anfangs gemocht aber nachdem mir klar wurde wie langsam und was das für eine Resource-Verschwender das ist, ist das auf den Index gekommen. Als Scriptsprache verwende ich heute ausschließlich Lua: einfacher Syntax, klein, schnell, gutes C-Interface, embedable. Hoffnungslos gescheitert bin ich an Common-Lisp: Die Klammeritis bekomme ich einfach nicht in meinen Kopf herein. Dazu muss man wohl ein anderes Hirn haben. :rolleyes: Ich habe immer noch ein gewissen Faible für Forth ( siehe z.B. http://factorcode.org/ ), stoße aber immer wieder auf interessante neue Projekte wie z.b. http://terralang.org/ .und andere die leider nicht immer unter FreeBSD kompilieren.

Das hat sich insofern geändert als ich heute ein konkretes, etwas umfangreicheres Projekt ins Auge gefaßt habe wozu ich entweder Erlang oder C++11 verwenden werde die ich z.Z. beide untersuche. Erlang ist ungemein interessant da es sich in vielfacher Hinsicht von allem unterscheidet was ich bislang kennen gelernt habe. Aber man kauft sich damit eine umfangreiche Platform ein (im Umfang etwas wie Java ohne GUI) was Vorzüge und Nachteile hat.
 
Das Problem mit Low-Lewel-Sprachen: man bekommt beides, sowohl Low- als auch High-Level-Fehler.
Für viele Anwendungsfälle ist das auch das große Problem von C: man ist mit so vielen Low-Level-Details beschäftigt, das die Produktivität der Entwickler sehr leidet.



Keineswegs. Ich kenne mich mit Java am besten aus und verdiene momentan mein Geld damit, halte Java aber bei weitem nicht für die beste Sprache (das war sie schon in den 90ern nicht).
Das wäre aber eher ein Thema für einen Weihnachtsurlaub-Monsterthread. ;)



Ein Aspekt, den viele Entwickler mit wenig Praxiserfahrung gerne übersehen. Die Sprache ist nur die halbe Miete.



Ich sehe es eher als Vorteil, ein direktes Feedback zwischen Implementierung und Test zu haben, ohne große Schleifen drehen zu müssen. Ich würde eher bei den Integrationstests zu anderen Mitteln greifen, aber das hängt immer stark vom konkreten Einzelfall ab.



Stimmt, beim Requirements Engineering noch sehr großer Nachholbedarf besteht. Wobei die Spezifikation in 90% der Fälle auch von Natur aus ein bewegliches Ziel ist. Ich kann mich natürlich 10 Jahre ins stille Kämmerlein zurückziehen und die perfekte Spezifikation schreiben. Nach 10 Jahren wird sie nur höchstwahrscheinlich keinerlei Relevanz mehr besitzen, weil die Welt sich weitergedreht hat (Ausnahmen bestätigen die Regel).



Mach' aus der Not eine Tugend. Entwickele in kurzen Iterationen, sichere deinen Code mit Unit- und Integrations-Tests ab und wenn die Software schließlich tut, was sie soll, hast du das Verhalten der Software mit deinen Tests spezifiziert.
Kein sauberes Vorgehen, aber die Welt ist nunmal dreckig - machen wir das Beste daraus.



Man kann es mit Mocks übertreiben, aber in der Praxis hat man nicht immer eine perfekte Testumgebung - das Kunststück ist es ja, trotzdem gute Software zu entwickeln. Das trennt bei den Entwicklern die Spreu vom Weizen.

Ich stimme weitgehend zu, aber:

Die Zahl der Fehlerquellen da draussen ist weit größer als die Zahl der Fehlerquellen, die man bei unit tests simulieren kann. Blödes Beispiel: Test einer Funktion, die eine bestehende Netzwerkverbindung braucht und die über irgendeine Art "handle" per Parameter kriegt. Die Fehler, die da in der Realität vorkommen, kannst du nicht simulieren.

Auch: Eine Programmiersprache ist auf Programmierung hin entwickelt. Für unit tests verwende ich, soweit irgend möglich, lieber eine dafür besser geeignete Sprache (Ja, O.K. ist meist Theorie, ich weiss. Aber du siehst, was ich meine).

Und: Ja, die Welt ist schmutzig und wir arbeiten alle nicht im Labor und für's Labor. Und dein Ansatz des "bröckchenweise" coden macht absolut Sinn, aber auch (und gerade bei Bröckchen) macht eine klare - und möglichst Maschinen-auswertbare - Spezifikation Sinn.
Meine persönliche Erfahrung und mein Lösungsansatz (ich arbeite in dem Bereich) ist ganz simpel: Beides.
Bei uns gibt es zu jedem Modul (für C Entwickler: "source file") ein spec.file, das im wesentlichen 4 Dinge leistet:
- Administrivia (Verantwortlicher, VC link, etc)
- plain text spec
- module spec (Maschinen-auswertbar)
- test spec (Maschinen-auswertbar)

Das passt auch ganz gut in den natürlichen Arbeits-Fluss. Im (nur wenig strukturierten) plain text Bereich legen die Nicht-Entwickler und evtl. die Kundenseite ihre "lose" Spezifikation ab. In module und test specs arbeiten architects und senior developer dann das technische Gerüst heraus und legen zugleich klare Rahmenbedingungen fest. Im letzten Schritt entsteht daraus sogar das Grundgerüst der source inkl. DbC, parameter Definition, etc.
 
Zurück
Oben