| 

.NET C# Java Javascript Exception

2
Wie ist das Wort funktional definiert bzw. wann ist eine C#-Methode funktional wie in F#/Haskell?

static DateTime F1() { return DateTime.Now; } //nicht funktional
static DateTime Plus(DateTime a, TimeSpan b) { return a + b; } //funktional

static int abc;
static DateTime Plus(DateTime a, TimeSpan b) { return (a + b).AddDays(abc++); } //nicht funktional


Das sind ein paar Beispiele aber wie lautet die allgemeine Regel?
News:
06.09.2009
jor 791 2 7
4 Antworten
4
Soweit ich weiss, gibt es keine strenge Definition des Begriffs "funktional" (zumindest keine, an die sich die Anpreiser von "funktionalen" Programmiersprachen gleichermaßen halten würden).
Das ist son bisschen wie bei dem Begriff "lebendig": Es gibt verschiedene Kriterien, je mehr davon erfüllt sind, desto "funktionaler" ist eine Sprache/ein Stück Code.

Die wären zum Beispiel:

  • Pure Funktionen, d.h. wenn ich die Funktion mit den selben Parametern aufrufe, kommt auch immer das selbe raus (Seiteneffektfrei), also wie in der Mathematik, das wäre in deinem Beispiel nur bei der "Plus"-Methode der Fall.
  • Damit verwandt ist die Forderung nach immutablen Objekten. D.h. ich kann eben nicht das Datetime objekt verändern, sondern höchstens eine Operation machen, die mir aus einem Objekt ein neues erzeugt.
    Wenn man zusätzlich Sachen wie Ein-/Ausgabe, Abfrage der Systemzeit etc... verbietet oder geschickt kapselt, hat man automatisch nur noch pure Funktionen.
    Wer schonmal ein bisschen was mit Multithreading gemacht hat, weiss, warum immutable Objekte toll sind ;)
  • Funktionen sind "First-class-citizens", d.h. können wie andere Objekte rumgereicht und in Arrays gespeichert werden. Technisch gesehen gilt das schon für C, weil es da Funktionspointer gibt, die genau das leisten. Dennoch hab ich schon sehr oft bei Programmiersprachen gelesen, dass sie sich dadurch von C unterscheiden wollen, dass Funktionen "First-class-citizens" seien.
  • Wie gfoidl schon gesagt hat: Funktionen, die auf Funktionen arbeiten, wie currying, map, select, etc...
  • Lambda-Funktionen, d.h. Funktionen mal eben so "inline" notieren zu können, ohne dass man ihnen einen Namen geben muss.
  • Closures, d.h. eine verschachtelte Funktion, die Variablen der äußeren Funktion "behält", damit kann zum Beispiel currying realisiert werden
  • Lazy evaluation / Ein "funktionales" Execution Model. Zum Beispiel bei Haskell ist es so, dass es nur pure Funktionen gibt. Diese werden dann nicht "aufgerufen" wie in imperativen Sprachen, sondern das Programm wird als Ausdruck verstanden, der umgeformt wird.

    Beispiel (pseudocode):

    f(a, b) := a / b
    g(a, b) := a
    g(5, f(1, 0))


    das würde in einer imperativen Sprache einen Fehler wegen Nulldivision erzeugen, in Haskell wird das wie folgt umgeformt:

    g(5, f(1, 0)) -> g(5, 1 / 0) -> 5

    erzeugt also keinen Fehler. Dadurch lassen sich so lustige Sachen machen wie unendlich lange Listen / Bäume etc...
07.09.2009
droggelbecher 116 1 2
1
Für mich hängt das stark mit dem Begriff Currying zusammen.

Beispiel:
Func<int, int, int> add = (a, b) => a + b;
Func<int, Func<int, int>> curryAdd = a => b => a + b;
Func<int, int> add5 = curryAdd(5);

Console.WriteLine(add(3,2));
Console.WriteLine(curryAdd(3)(2));
Console.WriteLine(add5(10));

Darin wird in der ersten Zeile eine anonyme Methode erzeugt und einem Delegaten zugewiesen.
In der zweiten Zeile wird eine weitere (anonyme) Methode erzeugt welche die erste "curryied". Das ist für mich funktional.
Der Vorteil ist dass ich ausgehend von einer Basisfunktion beliebige andere Funktionen (wird absichlicht nicht Methode genannt) erzeugen kann - sozusagen dynamisch.

Ich bin mir nicht sicher ob das der allgemeinen Definition entspricht - aber meiner eigenen genügt es ;)
06.09.2009
gfoidl 9,4k 3 5
1
Anforderung an eine Funktion ist,
dass der Rückgabewert nur von den Übergabeparametern abhängig ist.
Und dass keine Seiteneffekte stattfinden.

Das bedeutet

  • Methoden sind im Allgemeinen KEINE Funktionen, da sie per Definition auf this, self zugreifen.
  • "getter" sind keine Funktionen, da sie keine Parameterliste haben
  • "setter" sind keine Funktionen, da sie kein Funktionergebnis haben
  • (static) Klassenmethoden (sind keine Methoden, weil kein this/self existiert, zumindest bei C++,Java, C#)
  • Klassenmethoden sind am ehesten Funktionen wenn sie Parameter und Rückgabewert haben, aber nicht auf anderen Variablen (z.B. Klassenvariablen) zurückgreifen.
  • z.B. Klasse Math in Java besteht praktisch nur aus Funktionen.


Die strenge Definition einer Funktion spielt innerhalb der Softwareentwicklung keine Rolle
11.09.2009
stefan.bachert 395 4
0
Funktional ist eine Methode, wenn dessen Ergebnis NUR aus seine Parameter errechnet werden kann. Anders formuliert, wenn das Ergebnis mit den gleichen Parameter IMMER gleich ist, unabhängig von andere evtl. globale Variablen:

1)
static DateTime F1() { return DateTime.Now; }
nicht funktional weil Zeitlich bedingt (liefert je nach Zeitpunkt andere Ergebnisse)

2)
static DateTime Plus(DateTime a, TimeSpan b) { return a + b; }
funktional, Ergebniss hängt NUR von "a" und "b" ab.

3)
static int abc;
static DateTime Plus(DateTime a, TimeSpan b) { return (a + b).AddDays(abc++); }

nicht funktional, wenn sich abc ändert, ändert sich der Rückgabewert der Methode auch, ohne, dass dafür sich "a" oder "b" ändern.

Übringens tut der "static" eigentlich nichts direktes zur Sache. Aber wenn eine Methode funktional ist, kann man es hinzufügen können. Umgekehrt gilt es nicht: wenn man "static" hinzufügen kann heißt es nicht automatisch, dass die Methode funktional ist (Siehe 1)!
07.09.2009
jdehaan 434 2 7
jdehaan 434 2 7
1
Meinst Du vielleicht referentielle Transparenz?
http://en.wikipedia.org/wiki/Referential_transparency_%28computer_science%29
andre 07.09.2009

Stelle deine Java-Frage jetzt!