Ich beginne damit mal, dass Scala eine objekt-funktionale Programmiersprache ist. Es verbindet somit OOP und FP. Da Scala auf der JVM läuft und Java Code integrieren kann, kann das auch mal ähnlich aussehen. Doch FP und OOP sind grundverschiedene Sachen.
Fangen wir mit OOP an: Hier steht klar das Objekt im Vordergrund und die Eigenschaften, die damit verbunden werden. Diese Eigenschaften können nach belieben verändert werden und mit ihnen gearbeitet werden. (Jetzt in Java gesehen
Klassen zählen als Baupläne und deklarieren, was die Eigenschaften (State + Operationen). Hier ist das WIE entscheidend. WIE abstrahiert eine Klasse die Realität und WIE löst sie Probleme. Ich brech hier mal ab, denn OOP ist so viel mehr und behandelt so viele Themen (hier empfehle ich einfach mal im Internet nach Büchern und Definitionen zu suchen).
FP: Hier steht die Funktion im Vordergrund und das kann man auch Mathematisch sehen (wenn man Haskell etc. betrachtet). Man hat Eingabeparameter und aufgrund dieser wird - idealerweise immer das gleiche Ergebnis bei gleicher Eingabe - ein Ergebnis errechnet. Diese Funktionen können jetzt auch als Argumente an andere Funktionen weitergereicht werden. So können Standardoperationen (wie z.B. Filtern/Sortieren/Iterieren/...) abstrahiert und Allgemein gehalten werden. Es geht auch noch weiter, denn Funktionen können auch Funktionen zurückliefern und das ist eine der wichtigsten Eigenschaften von FP.
(Bitte wieder hier selbst nachlesen, denn das ist auch nur ein ganz kleiner Ausschnitt aus FP)
Nehmen wir das Beispiel des Quicksort Algorithmus aus dem Scala-Lang-Doc her.
[code=Scala]def sort2(xs: Array[Int]) {
def swap(i: Int, j: Int) {
val t = xs(i); xs(i) = xs(j); xs(j) = t
}
def sort1(l: Int, r: Int) {
val pivot = xs((l + r) / 2)
var i = l;
var j = r
while (i <= j) {
while (xs(i) < pivot) i += 1
while (xs(j) > pivot) j -= 1
if (i <= j) {
swap(i, j)
i += 1
j -= 1
}
}
if (l < j) sort1(l, j)
if (j < r) sort1(i, r)
}
sort1(0, xs.length - 1)
}[/code]
Diese Impelemntierung würde auch in Java ähnlich aussehen. Eventuell wäre die Rekursion jetzt noch Iterativ, aber das kann ja als Übung gesehen werden.
Hier wird explizit mit States gearbeitet (was nicht sehr dem FP Konzept entspricht). Das heißt explizite Iteration und Laufvariablen. Man muss auch Grenzfälle uvm. berücksichtigen.
Jetzt zu dem FP Code:
[code=Scala]def sort(xs: Array[Int]): Array[Int] = {
if (xs.length <= 1) xs
else {
val pivot = xs(xs.length / 2)
Array.concat(
sort(xs filter (pivot >)),
xs filter (pivot ==),
sort(xs filter (pivot <))
)
}
}[/code]
Grundsätzlich hilft Rekursion bei FP oftmals mehr als Iteration. Also: Hier wird nicht das WIE beschrieben sondern das WAS, denn Iteration ist implizit gestaltet und Verhalten wird mit Funktionen (Lambdaexpressions) beschrieben.
Ausgeschrieben (mit Lambda) sieht die Funktion so aus:
[code=Scala]def sort(xs: Array[Int]): Array[Int] = {
if (xs.length <= 1) xs
else {
val pivot = xs(xs.length / 2)
Array.concat(
sort(xs.filter(x => pivot > x)),
xs.filter(x => pivot == x),
sort(xs filter (pivot < _)))
}
}[/code]
Hier sieht man die Stärke von OFP. Alle Operatoren sind selbst Funktionen und können auch so verwendet werden. Alle Zwischenergebnisse (Arrays nach dem Filtern) sind Immutable und nur ein Snapshot, somit könnte dieser Algorithmus auch leicht parallelisiert werden, da der Urzustand des Arrays nie verändert wird. Grenzfälle braucht man keine abzudecken, denn es wird nur der Algorithmus implementiert mit divide-and-conquer.
Konkret kann ich deine Frage nicht beantworten, denn beide Konzepte OOP und FP (respektive OFP) sind gleichmächtig und die Stärken sind woanders anberaumt. Was einem jetzt besser liegt und gefällt ist Geschmackssache und muss jeder für sich selbst entscheiden. Ich hoffe ich konnt dir mit diesem kleinen Exkurs ein wenig die Unterschiede aufzeigen. Bei Weitem kann ich dir hier nicht alle Stärken von OFP aufzeigen, wie Pattern-Matching, Case Classes, ADTs, simple DSL Implementierungen, ... .
Kann man fast so sehen. Sie erlaubt eben gängige Muster zu abstrahieren und Verhalten zu injezieren (kann mit OOP simuliert werden).
Nein. Aber vorhandene Syntax erleichtert vieles - sieht man am obigen Beispiel mit impliziten Lambdaexprssions, Infix-Notation, ... - am Programmieren und am Lesefluss (für ein geübtes Auge auf jedenfall!). Vorhandene Bibliothek ist schon sehr mächtig, die man auch sehr oft nutzen kann und für 99% aller Probleme verwenden kann.
Am besten du versuchst Projekte in Scala (oder OFP/FP) zu lösen und erkennst, das vieles einfacher ist, wenn man auch die Logik etwas funktionaler gestaltet (ist teilweise in Java 8 eingeführt worden)!
XSL ist eine Progammiersprache, dass Templatematching-Techniken einsetzt und ist nicht funktional, sondern baut darauf auf (HIER).