Ist es noch funktionale Programmierung, wenn ein Pointer oder eine Referenz übergeben wird?

Antwort vom

**Ja – das kann immer noch funktionale Programmierung sein. Entscheidend ist nicht, *dass* du eine Referenz oder einen Pointer übergibst, sondern ob der referenzierte Zustand unveränderlich ist und die Funktion dadurch für dieselben Eingaben immer dasselbe Ergebnis liefert.** Ein Pointer ist zunächst nur eine Art, auf einen Wert zu zeigen. Das verletzt funktionale Prinzipien nicht automatisch. Problematisch wird es erst, wenn über diese Referenz veränderbarer Zustand gelesen oder geschrieben wird und das Ergebnis der Funktion deshalb von versteckten Änderungen abhängt. ## Der entscheidende Unterschied Wenn die Referenz auf **immutable Daten** zeigt, ist das funktional unkritisch: ```cpp int sum(const std::vector<int>& xs) { int s = 0; for (int x : xs) s += x; return s; } ``` Hier wird zwar eine Referenz übergeben, aber die Funktion verändert nichts. Für denselben Inhalt von `xs` kommt immer dasselbe Ergebnis heraus. Nicht mehr funktional im engeren Sinn wird es hier: ```cpp int next(int* x) { (*x)++; return *x; } ``` Diese Funktion hat einen Seiteneffekt. Sie verändert Zustand außerhalb ihrer selbst. Genau das ist der Bruch mit funktionaler Programmierung, nicht die Pointer-Übergabe an sich. ## Warum die Adresse selbst nicht das Problem ist Die Speicheradresse ist für die funktionale Betrachtung meist irrelevant. Entscheidend ist die **semantische Eingabe**, also der Wertinhalt. Ob ein Wert kopiert, per Referenz oder per Pointer übergeben wird, ist erst einmal eine Implementierungsfrage. Anders gesagt: - **funktional:** „Diese Funktion arbeitet auf einem Wert.“ - **nicht funktional:** „Diese Funktion hängt an veränderlichem Speicherzustand.“ Dass „an derselben Adresse später etwas anderes liegen könnte“, ist nur dann ein Problem, wenn dieser Wechsel für die Funktion beobachtbar oder ausnutzbar ist. ## Wichtiger Sonderfall Wenn Pointer-Identität selbst Teil der Logik wird, entfernst du dich oft von funktionalem Denken: ```cpp bool equal(int* a, int* b) { return a == b; } ``` Das vergleicht nicht Werte, sondern Identität bzw. Speicherlage. Das ist technisch erlaubt, aber konzeptionell eher kein typisches funktionales Modell, weil funktionale Programmierung normalerweise Wertgleichheit wichtiger nimmt als Objektidentität. ## Praktische Faustregel **Referenz gut, mutierbarer Zustand schlecht.** Genauer: - Pointer/Referenz auf **konstante, unveränderliche Daten**: funktional kompatibel - Pointer/Referenz zum **Mutieren von Zustand**: nicht funktional - Zugriff auf **globale/versteckte mutable Daten** über Referenzen: nicht funktional - Referenzen nur zur **Effizienz**, ohne beobachtbare Mutation: weiterhin funktional Der Kern ist also: **Nicht die Adresse macht ein Programm un-funktional, sondern veränderlicher, beobachtbarer Zustand.**