Funktionales Programmieren und DRY-Prinzip

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
bastian.weber
User
Beiträge: 15
Registriert: Montag 4. August 2008, 23:30
Wohnort: Dresden

Wie kann ich funktionales Programmieren (also rekursive Funktionsaufrufe) mit dem DRY-Prinzip vereinbaren?

Normalerweise mache ich es sowas:

Code: Alles auswählen

def fakultaet(n):
    if n == 0 : return 1
    else: return fakultaet(n-1)

Was mich aber daran stört ist, dass ich wenn ich die Funktion umbenenne, dies an zwei Stellen tun muss, und dabei bestimmt die innere vergesse.

Wie kann ich dieses Problem verhindern?
BlackJack

@bastian.weber: Solange eine Sprache nicht ein Symbol anbietet was immer gleich bleibt und sich auf die aktuelle Funktion bezieht, denke ich kann man das nicht verhindern.

Wobei die Frage sowieso ein wenig theoretisch ist in Python, weil es eben keine funktionale Sprache in diesem Sinne ist. Wenn die Sprache selbst keine "tail call optimization" garantiert, würde ich da nicht auf rein funktionale Programmierung ohne Schleifen setzen.

Deine Fakultät ist keine -- die gibt für positive, ganze `n` immer 1 zurück. Aber eine echte Fakultätsfunktion in Python würde man eher mit einer Schleife implementieren.
lunar

Dieses Problem kannst Du nur umgehen, Indem Du auf explizite Rekursion verzichtest. Rein funktional Sprachen bieten viele Hilfsfunktionen zur Vermeidung expliziter Rekursion, insbesondere Faltungsoperationen über Listen. In Haskell würde man die Fakultät daher wie folgt implementieren:

Code: Alles auswählen

factorial n = foldr (*) 1 [1..n]
Dieses Prinzip lässt sich auch in Python umsetzen:

Code: Alles auswählen

from operator import mul
def factorial(n):
    return reduce(mul, xrange(1,n+1))
Allerdings ist Python seiner Natur nach keine funktionale Sprache, daher ist die idiomatische Lösung in Python eher eine Schleife. Generell sollte Rekursion in Python vermieden werden, da die Sprache rekursive Aufrufe nicht optimiert.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

2x factorial würde ich jetzt noch nicht als un-DRY (WET?) bezeichnen. Jede bessere IDE wollte das gebundene Umbenennen von Namen beherrschen. Somit ist das kein Aufwand. Wenn das aber unbedingt vermieden werden soll, ist das richtige Stichwort Y-Kombinator. Siehe z.B. http://www.python-forum.de/viewtopic.php?p=127961

Stefan
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

bastian.weber hat geschrieben:Was mich aber daran stört ist, dass ich wenn ich die Funktion umbenenne, dies an zwei Stellen tun muss, und dabei bestimmt die innere vergesse.
Du musst sie sogar noch an viel mehr Stellen umbenennen, nämlich überall da wo du sie benutzt. Da hilft nur eins: Keine Funktionen verwenden. Aber ob das dann noch DRY ist…
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

BlackJack hat geschrieben:@bastian.weber: Solange eine Sprache nicht ein Symbol anbietet was immer gleich bleibt und sich auf die aktuelle Funktion bezieht, denke ich kann man das nicht verhindern.
Ja, in Clojure gibt es da als Krücke ``recur``, aber das ist weniger als DRY-Gründen sondern eher um den Compiler einfach zu halten.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Antworten