Ansicht umschalten
Avatar von MetaCircularEvaluator
  • MetaCircularEvaluator

mehr als 1000 Beiträge seit 20.03.2015

Re: Ist doch alles dasselbe

Dr. Faustus schrieb am 30.09.2019 12:47:

MetaCircularEvaluator schrieb am 30.09.2019 09:39:

Naja. Manchmal schon. Schönes Beispiel C++.

Klar gibt es besonders komplizierte Sprachen. Neben C++ wäre Ada2012 ein gutes Beispiel. Aber bei beiden dieser Sprachen kann man die komplizierten Konstrukte einfach weglassen und trotzdem noch nützlichen Code schreiben.

Das Argument wird gerne und oft gebracht, es stimmt aber so nicht.

Denn auch wenn man beschließt, sich nur auf ein Subset an Features zu beschränken, so kommt man nicht umhin die restlichen Features zu kennen und zu verstehen wenn man Code anderer Leute lesen und verstehen will – was Voraussetzung ist diesen Code selbst verwenden zu können. Dabei kann man heutzutage eigentlich nichts sinnvolles entwickeln ohne auf Code anderer Leute zuzugreifen.

Das Problem sind aber sowieso imho nicht primär "komplizierte Konstrukte". Es geht um "Komplexität", weniger um das was man unter "kompliziert" versteht. Eine handvoll wohl strukturierter, zwar durchaus "komplizierter", aber gut aufeinander abgestimmter Konzepte kann "simpler" sein, als viele für sich "einfache" bzw. "unkomplizierte" Konstrukte, die aber jeweils sehr individuell miteinander interagieren. Komplexität ergibt sich meiner Meinung nach zum größten Teil aus der Interaktion von Dingen.

Mich würde trotzdem noch interessieren, welche Elemente in den OO Sprachen (insb. Nim) die Leute als zu kompliziert erachten.

Ich weiß es nicht. Für mich sieht Nim jetzt alles andere als "kompliziert" aus.

Ich würde aber befürchten, dass Nim "komplex" sein könnte. Es hat vergleichsweise viele Features (plus eine recht flexible Syntax, was auch gern nochmal die "accidental Complexity" erhöht), wobei die Features zwar nicht komplett ad hoc wirken (wie z. B. in PHP, oh Graus!), trotzdem aber nicht wirklich auf übergeordneten Grundprinzipen aufzubauen scheinen. Zugegeben, das ist bei praktisch allen Sprachen so die solider theoretischer Grundlagen entbehren. Hier könnte das aber schneller zu einem Problem werden, da es eben viele Features sind, die auch noch Dinge verschiedener Abstraktionslevel umfassen. Imho ist ein Spagat zwischen verschiedenen Abstraktionsleveln auch überhaupt eines der schwierigsten Dinge die man versuchen kann in einer Programmiersprache umzusetzen. So etwas erfordert ein besonders sorgfältiges Design. Zu einem guten Teil sind die Konzepte die man hierfür benötigt auch immer noch Gegenstand von Forschung. Ausgerechnet in dem Bereich hat Nim aber eigentlich nichts zu bieten. Man ist "sehr pragmatisch" an diese Dinge herangegangen. Man will ja diese Dinge für den Anwender nicht "verkomplizieren".

Bezüglich OO Sprachen? Da fragst Du glaube ich den falschen. :-D

Ich halte OOP größtenteils – jedenfalls was die Leute so darunter verstehen, also so Java, C#, C++ Gedöns – für einen rechten Krampf. Die meisten OO Sprachen an sich aber sind nicht "kompliziert", imho. Wobei ich dazusagen muss, dass ich "purely functional" Scala beruflich mache, und z. B. mit so Zeug wie HKTs (Higher-Kinded-Types) oder Type-Lambdas im ganz normalen Alltag hantiere. Zur Zeit schaue ich mir auch wieder mal Idris [1] an (bin da wieder drauf gekommen, als ich gesehen habe, dass Idris Support für "Unique Types" hat, und ich neulich die Idee hatte, dass man "Unique Types" zusammen mit impliziten Object-Capabilities dazu nutzen könnte ein in der Anwendung sehr komfortables Effekt-System zu konstruieren; ist aber bisher nur eine "random Spinnerei"). Aber zurück zu OOP. Auch wenn die Sprachen an sich nicht "kompliziert" sind, so erzeugt "OOP Java-Style" (hier stellvertretend für alles Vergleichbare) automatisch unheimlich viel Komplexität. Das liegt daran, dass wenn man versucht einfach alles als Hierarchie von Klassen zu modellieren man ein Resultat erhält, welches zum berühmt-berüchtigten "You wanted a banana but what you got was a gorilla holding the banana and the entire jungle" führt (im Prinzip hängt alles implizit an allem anderen). Hinzu kommt, dass alle OO Objekte typischerweise Zustand tragen. D. H. nicht nur dass an Deiner Banane ein Gorilla und sein ganzer Dschungel hängt, das nächste mal wenn Du die gleiche Banane haben willst, könnte sie bereits faulig sein – oder Gorilla wütend mit Exceptions und Null-Pointern um sich werfen… ;-) Dann natürlich der semantische Mismatch: Objekte sind "Dinge" also die Nomen in Deiner Sprache, Methoden ergeben die Verben. Man kann aber keine Verben ohne ein "umhüllendes Nomen" definieren, umgekehrt geht das. Dass heißt hier gibt es einen recht starken Bias zu den Nomen, was die Sprache weniger Ausdrucksstark bzw. "umständlich" macht. Will man eigentlich ein neues Verb definieren muss man es als Nomen ausdrücken. Das ist sehr unnatürlich, und eben eine Diskrepanz zwischen dem was man ausdrücken will (z. B. eine "Tätigkeit" beschreiben) und der nötigen Formulierung. Im Ergebnis sind OO Programme ein wilder Dschungel an Objekten die irgendwie miteinander "reden wollen", wobei sie dabei gegenseitig ihren Zustand verändern. Das ist imho eben geradezu ein Paradebeispiel für Komplexität! Viele Dinge die miteinander Interagieren, wobei die Interaktion an sich, und deren individueller Verlauf vom aktuellen Zustand der Dinge abhängen, wobei sich dieser Zustand aufgrund der Interaktion freundlicherweise ändert. Gegeben dass ein normaler Mensch nur drei bis fünf Dinge gleichzeitig im Arbeitsgedächtnis halten kann, ist die Funktionsweise von "typischem" OO Code pures und unverständliches Chaos. Meiner Meinung nach ist zumeist, rein praktisch betrachtet, "typischer" OO Code auch nur wenig besser als rein prozeduraler Code ohne Klassen drumherum. Auch wenn eine "OO" Sprache an sich nicht kompliziert ist, so erzeugt OOP Komplexität aus Prinzip heraus. My 2¢.

Aber bitte nicht falsch verstehen: Ich halte OO nicht für komplett "verkehrt" oder so. Auch wenn "pures OOD" auf dem "technischen" Level keine gute Idee ist (unabhängig von dem schon gesagten, in Hardware gibt es schließlich keine "Objekte", und das Mapping um die semantische Lücke zu überbrücken ist aufwendig und teuer), so hat "Objekt Orientierung" als abstraktes Konzept durchaus seine Berechtigung. Jedenfalls um gewisse Dinge zu modellieren. Will (oder muss) man "von Natur aus" zustandsbehaftete Entitäten mit "Lebenszyklus" beschreiben, so bietet es sich durchaus an dies direkt mithilfe von "echten Objekten" zu bewerkstelligen, welche eben ihren in sich gekapselten Zustand selbst verwalten, und mit der "Außenwelt" nur mithilfe von unveränderlichen und asynchronen (!) Nachrichten interagieren. Das sind aber nicht die "typischen" Objekte der Mainstream OOP Sprachen, sondern viel mehr das was heute "Aktor" genannt wird. Die konkrete Implementierung dieser Abstraktion kann dann natürlich wieder funktional sein. Auch eignen sich Objekte und Klassen (ML Module z. B. sind imho praktisch nichts weiter als "OOP Klassen") zum Teil zur Strukturierung von Code. Solange man jedenfalls keine tief verschachtelten Hierarchien bildet. Den explizite Hierarchien, die auch nur vergleichsweise "simple" Zusammenhänge modellieren sollen, tendieren dazu überaus Komplex zu sein. Dabei sind sie grundsätzlich inflexibel. Vor allem da sie sich (tiefer greifend) strukturell im Nachhinein praktisch nicht mehr ändern lassen, und man meist nur noch Zweige ergänzen kann. Ich würde also sagen, als Modulsystem ist "OOP" durchaus zu gebrauchen, nur halt ohne auf das "übliche" OOD zurückzugreifen. Die Vorstellung von Objekten mit Eigenschaften und Methoden halte ich übrigens auch für eine "gute Idee"™. Sich die Sachen mit denen man beim Programmieren hantiert als "Dinge" vorzustellen, welche man "anfassen" und beschreiben kann, und mit denen man etwas "tun" kann, macht vieles meiner Meinung nach einfacher. Auch wenn man den Code dann nicht direkt so strukturiert, sondern Daten und die darauf ausführbaren Funktionen separat hält (was die Erweiterbarkeit und Flexibilität ungemein erhöht), und die Dinge erst später zu "typischen Objekten" die ein OO artiges Interface implementieren zusammensetzt (z. B. mithilfe von "Type Classes" und "Extension Methods"), ist die Vorstellung von "realen Dingen" hilfreich um einfach verständliche Interfaces zu designen. Ein "Objekt" mit dem man etwas "tun" kann (indem man Methoden darauf aufruft), oder dessen Eigenschaften man inspizieren kann, ist imho einfacher zu handhaben als ein "Modul" welches Daten(-Definitionen) und auf diese Daten anwendbare Funktionen zwar auch bündeln kann, aber eben nicht ein konkretes "Ding" mit dem man etwas tun kann darstellt. Das hat z. B. auch Auswirkungen auf die "Discoverability" z. B. innerhalb einer IDE oder REPL. Hat man nämlich ein Objekt in Händen, kann dessen Typ erfragen, den aktuellen Zustand erforschen, und sich die auf diesem Objekt aufrufbaren Methoden anzeigen lassen. Man kann sich so zusammenreimen was man mit diesem Objekt so alles "anstellen" kann. Hat man hingegen eine Referenz auf ein "typisches" Modul, kann man sich zwar dessen Struktur anschauen, aber wie die vom Modul definierten Funktionen mit den darin definierten Datenstrukturen konkret zusammenspielen sollen darf man sich selbst zusammenreimen. Man wird hier nicht an die Hand genommen (auch wenn Namen oder Typen natürlich zu einem gewissen Grad helfen).

Ich glaube also, dass man sich aus OOP und FP jeweils durchaus die Rosinen herauspicken kann (könnte). Deswegen mache ich ja auch Scala. Ist zwar leider weiterhin alles andere als perfekt. Allein so ein Mix der Paradigmen bring natürlich seine eigene Komplexität mit. Hinzu kommt, dass Scala leider "OOP, the bad parts" auch mit sich trägt. Auf der anderen Seite könnte "FP, the good parts" ruhig noch besser unterstützt werden. Aber alles im Allem eine sehr solide Sprache, mit modernsten und teilweise sogar richtungsweisenden Features. Falls man der Idee FP und OOP zu mischen etwas abgewinnen kann, ist Scala definitiv einen Blick wert.

https://www.scala-lang.org/

NexGen Scala:

http://dotty.epfl.ch/

Ah, hier ein Witz zum Thema:

https://james-iry.blogspot.com/2009/05/brief-incomplete-and-mostly-wrong.html ;-)

[1] https://www.idris-lang.org/

Bewerten
- +
Ansicht umschalten