Follow my new blog

Freitag, 3. Januar 2014

Eklektische Programmierung

Jetzt hab ich genug. Mir hängt das ganze Gerede über Für und Wider von Objektorientierter Programmierung (OOP) und Funktionaler Programmierung (FP) zum Hals raus. Ich mag nicht mehr.

Es ist zwar nicht egal, ob OOP oder FP. Der eine Ansatz hat für manche Szenarien Stärken, der andere Ansatz für manche Szenarien Stärken. Und? Warum sollte ich mich deshalb entscheiden müssen? Warum sollte OOP gewinnen, warum FP die Welt erobern? Das ist doch alles Quatsch. Solche Überlegungen binden geistige Kapazität, die wir besser einsetzen können.

Es geht nicht um die Frage, ob OOP oder FP. Es geht nicht um entweder-oder. Es gibt keinen Grund, warum es nicht ein sowohl-als-auch geben sollte.

Und schon gar nicht geht es um eine bestimmte Programmiersprache. Vorgestern Java, gestern C#, Python, Ruby, nun Go, Clojure, Erlang, Elixir – und natürlich gestern wie heute JavaScript? Gott ist das langweilig.

Ich mag mich nicht mehr entscheiden müssen. Ich will beides: OOP + FP. Das ist die Frage, die ich an Sprachen in Zukunft stellen werden: Kannst du mir volle OOP-Power geben und (!) kannst du mir volle FP-Power geben? [1]

Deshalb beschäftige ich mich gerade auch mit F#. Das ist eine hybride Sprache, allerdings geboren aus der FP. Da kommt für mich vieles eklektisch zusammen. Ich kann z.B. einen Stack à la FP implementieren und nutzen:

image

Oder ich kann ihn à la OOP definieren und nutzen:

image

Das sieht dann ähnlich einer Implementation in C# aus – ist nur etwas knapper formuliert, weil F# Typinferenz und eine leichtgewichtigere Syntax bietet. Hier zum Vergleich C#:

image

Oder ich kann in F# Objekte aus C# (bzw. aus .NET Assemblies) nutzen – und umgekehrt.

Mit F# muss ich mich nicht mehr entscheiden. Ich habe die volle Power von OOP und FP “at my fingertips”.

Nun kann ich frei überlegen, wann ich welchem Paradigma den Vorzug gebe. Ist ein Stack besser mit FP- oder OOP-Mitteln implementiert? Wie steht es mit der Logik für ein Spiel? Wie steht es mit einem View Model? Wie mit einem EventStore? Wie mit dem Domänendatenmodell?

An den Grenzen meines Codes stoße ich dann allerdings auf Infrastruktur. Mit der muss ich mich arrangieren, die präsentiert sich mir in Form von APIs. Natürlich muss meine Sprache mir den Zugriff erlauben.

Und ansonsten… Freiheit!

Denn erst wenn wir beide Paradigmen gleichwertig zur Verfügung haben, können wir zum Wesentlichen kommen: Was denn in welchem Fall der geeignete Ansatz sei.

Solange Sprachen noch beim einen oder anderen Paradigma zurückstehen, verlieren wir uns schnell in Rechtfertigungen. Dann ist das kein Defizit, sondern ein Feature, weil das andere Paradigma es einfach nicht bringt.

Doch das ist Quatsch. Die Frage nach dem richtigen, wichtigen, seligmachenden Paradigma ist die falsche Frage. Nicht das eine oder das andere Paradigma ist seligmachend, sondern die Vielfalt. Pluralismus statt Monokultur.

Ich will eklektisch programmieren, d.h. mich aus einem Bauchladen bedienen. Was mir taugt, wird benutzt. Fertig.

imageDas mag Lernaufwand für mich bedeuten. Ok, dann wende ich den eben auf. So wie ich es gerade mit F# tue und in einem Buch dokumentiere: F# lernen Kata für Kata. (Damit mache ich es Ihnen dann vielleicht ein wenig leichter, wenn Sie sich auch für die eklektische Programmierung entscheiden.)

Lernaufwand zur Ermöglichung von Eklektizismus ist Aufwand. Aber Rechtfertigungen für das eine oder andere Paradigma und Workarounds, wo es eben nicht optimal passt, Sie jedoch darauf festgenagelt sind… das ist auch Aufwand. Und zwar kein unbeträchtlicher.

Klar, C# bietet schon einiges in Richtung FP. Aber eine wirklich hybride Sprache ist C# noch nicht und wird es auch nicht. F# hingegen wurde mit dieser Absicht entworfen.

Für mich ist 2014 das Jahr, in dem ich meine eigenen Entwicklungen auf F# umstellen werde. Damit kann ich eklektisch arbeiten, bleibe dem .NET-Universum aber verbunden.

Wer mit Java arbeitet, der hat ähnliche Möglichkeiten. Scala und Clojure scheinen mir auch den hybriden Ansatz zu verfolgen. Für meinen Geschmack ist das JVM-Universum jedoch zu weit weg. Außerdem hat mir Scala einen Grandiositätsanspruch, der mich ermüdet. Und Clojure ist mir syntaktisch dann doch im Moment zu anders.

Wie gesagt, am Ende geht es auch nicht um einzelne Sprachen, sondern um Paradigmen. Wenn ich mich über Softwareentwurf unterhalten will, dann interessiert mich die konkrete Syntax nicht sonderlich. Wichtig ist vielmehr, dass mein Gegenüber Paradigmen und Konzepte zur Verfügung hat.

Soviel zu meinem Vorsatz für 2014: Eklektische Programmierung mit F#.

Und was ist Ihr Vorsatz?

PS: Achso, dynamische Programmierung (DP) will ich übrigens auch :-) Von der steckt in C# etwas drin; F# ist in der Hinsicht schwachbrüstiger. Derzeit ist mir jedoch mehr FP-Power wichtiger. Mit etwas weniger DP kann ich leben. Oder ich werde noch eklektischer: Ich wechsle nicht nur das Paradigma in einer Sprache, ich wechsle gleich zwischen den Sprachen. Da C# und F# auf der CLR/BCL laufen, muss ich mich nicht mal zwischen ihnen entscheiden.

Endnoten

[1] Ich ahne es, irgendwer wird fragen, was denn “volle Power” für die beiden Paradigmen ist. Und darüber lässt sich womöglich trefflich streiten. Aber ich denke, es gibt da einen gewissen Konsens. Zu OOP gehören Interfaces, Polymorphie, Kapselung von veränderbarem Zustand, einfache Vererbung. Zu FP gehören Funktionen als Werte & höhere Funktionen, tail recursion, unveränderbare Werte/Datenstrukturen, pattern matching.

Kommentare:

Ralf Peine hat gesagt…

Das sehe ich genauso. In Perl 5 ist OOP für Massendaten nicht optimal, aber dafür sind FP und dynamische Programmierung dank "eval" ganz stark. Ideal für Scripting per API. Nicht ideal für Domänenmodelle mit großen Datenmengen. Dafür kann man die Namen von Funktionen zur Laufzeit definieren / ändern / umhängen. Gut für das Testen von FP Code.

Stephan Roth hat gesagt…

Hallo Ralf,

das Problem bei den meisten Betrachtungen bzw. Gegenüberstellungen von OOP und FP ist, dass die Perspektiven gleich voll ins Extreme gehen.

Pures OO ist widernatürlich, weil es eben Konzepte in der realen Welt gibt, die nun mal keine Objekte sind. Natürlich kann man auch einen Algorithmus in eine Klasse wrappen und dann so tun, als sei es ein Objekt, aber das ist cheating!

Auf der anderen Weise ist die reine, funktionale Programmierung ebenso widernatürlich. Man muss sich nur mal in seiner Umwelt umschauen um sehr schnell festzustellen, dass so gut wie alles, was wir tun, Nebenwirkungen und Seiteneffekte hat. Wozu hat ein Computer denn Speicher, egal ob RAM oder nicht-transiente Festplatte? Vielleicht damit er sich Dinge, wie Werte und Zustände, merken kann?

Das Ideal ist eine Hybridsprache, die beide Konzepte zur Verfügung stellt. Auch wenn sie sehr unbeliebt ist, spielt für mich C++ als Multiparadigmen-Sprache diesbezüglich immer noch in der obersten Liga - erst Recht seit des neuen Standards C++11.

Oliver Funke hat gesagt…

Hallo Ralf,

Ich sehe das ähnlich. Man sollte sich nicht auf ein Werkzeug beschränken sondern je nach Anwendungsfall das geeignete Werkzeug aus seinem Werkzeugkasten verwenden. Ich selbst nutze zurzeit gern eine Kombination aus C# und F#. C# eignet sich meiner Meinung nach besser für Präsentations- und Logikschicht, während F# sehr passend für die Entwicklung der Datenschicht ist. Somit bestehen meine aktuellen Anwendungen meist aus einer Mischung aus C# und F# Assemblies. Klar steigt der Einarbeitungsaufwand wenn man mehrere Programmiersprachen nutzt, aber dieser Aufwand amortisiert sich relativ schnell wenn die Sprachen dann besser zum jeweiligen Anwendungsfall passen.

Mike Bild hat gesagt…

+1 Um das gewünschte Ziel zu erreichen, die nützlichste Sprache zum Werkzeug machen.

Doch weiter gehts...

Für mich heißt das ebenfalls

1) die Platform zum Werkzeug machen
2) Micro-Services als App-Standard-Bausteine zu konstruieren

=> Software Engineering unabhängig von Sprache und Platform



Ralf Westphal - One Man Think Tank hat gesagt…

Klar, µServices sind der Weg. Habe darüber hier auch schon geschrieben:

http://blog.ralfw.de/2013/03/software-als-web-of-services.html

Mike Bild hat gesagt…

+2 !!! Für meine Geschmack gerade etwas "weit weg" vom praktischen aber GROSSARTIG!

...

"SOA ist mir da schon zuviel. Aber Actors sind mir zuwenig."

"Deshalb plädiere ich dafür, Software aus mehr, viel mehr Prozessen zusammenzusetzen als heute üblich."

"Das ist für mich der Weg für die effizientere Herstellung von evolvierbarer Software"