Wie funktional ist C++11?
-
ipsec schrieb:
C++ ist definitiv keine funktionale Programmiersprache, trotzdem kann man mehr oder weniger gut funktional in C++ programmieren. Also kann man nicht sagen, C++ hätte keinerlei funktionalen Eigenschaften.
Und wo ist die Grenze um funktional zu sein?
-
@Zeus & ipsec:
Ich glaube hier liegt ein Misverständnis vor.Man kann bei der Einteilung von Programmiersprachen entweder Schubladen machen, und dann jede Sprache in genau eine Schublade tun. Wenn man es so macht, dann landet C++ nicht in der "funktional" Schublade, sondern z.B. in der "multi paradigm" Schublade.
Man kann aber auch Checkboxen machen, und für jede Sprache sämtliche Checkboxen markieren, die für die jeweilige Sprache passen. In dem Fall könnte man C++ ein "funktional" Hakerl verpassen (neben "imperativ" und noch vielen anderen).
"Wie funktional ist C++" ist klar eine Checkboxen-Frage (mit "analogen Checkboxen", hihi), die Antwort "gar nicht" wäre daher falsch.
"Ist C++ eine funktionale Programmiersprache" kann man aber sowohl als Schubladen-Frage als auch als Checkboxen-Frage verstehen.
Du, ipsec, hast sie wohl als Schubladen-Frage verstanden, und du, Zeus, vermutlich als Checkboxen-Frage.
-
hustbaer schrieb:
@Zeus & ipsec:
Ich glaube hier liegt ein Misverständnis vor.Ja, aber am Maßstab, wieviel funktionale Aspekte ein Programmiersprache spielt keine Rolle, sondern ihre Integration zum Paradigma. C#, D, F# und Scala sind funktional (als CheckBox-Frage). Bei C# und D versteh ich es nicht ^^.
-
ipsec schrieb:
Wäre die Frage "ist C++ eine funktionale Programmiersprache", wäre die Antwort ganz klar nein.
Wie ihr alle Unrecht habt!
Die Antwort ist ganz klar ja:<a href= schrieb:
C++-Artikel in Wikipedia">Paradigmen: Multiparadigmen (imperativ, strukturiert, objektorientiert, generisch, funktional)
</ironie>
hustbaer schrieb:
"Wie funktional ist C++" ist klar eine Checkboxen-Frage (mit "analogen Checkboxen", hihi), die Antwort "gar nicht" wäre daher falsch.
Gut. Und was ist die Antwort auf "Wie funktional ist Assembler"? C++-Code macht das gleiche wie Assemblercode, also ist Assembler funktional. Und Brainfuck? Analog dazu ebenfalls funktional. Du kannst das für jede Sprache machen, die nur turing-vollständig ist. Wenn du mir folgen konntest, dann sag mir: Gibt es eine turing-vollständige Sprache, die irgendein Programmierparadigma (das von einer anderen turing-vollständigen Sprache unterstützt wird) nicht erlaubt? Nein.
Das Problem ist, dass je nach dem, wie man den Begriff Paradigma versteht, eine andere Antwort herauskommt.
Wenn man das Wort so versteht, wie es in der englischen Wikipedia steht, ein fundamentaler Programmierstil, dann muss man sagen: C++ kann funktional sein, aber der Stil ist nicht fundamental in der Sprache verankert. Daher gehört in der Checkbox ein "gar nicht" hin und der Eintrag in der – wohlgemerkt deutschen – Wikipedia gehört raus.
-
@Zeus:
Tut mir leid, aber den Satz verstehe ich nicht
-
Tyr schrieb:
Die Antwort ist ganz klar ja:
<a href= schrieb:
C++-Artikel in Wikipedia">Paradigmen: Multiparadigmen (imperativ, strukturiert, objektorientiert, generisch, funktional)
Im englischen Artikel dazu ist das nicht vermerkt. Und er ueberrascht micht auf der deutschen Seite. Die Diskussion zu diesem Punkt laesst vermuten, dass funktional besser weggelassen werden sollte.
Leider macht sich kaum jemand ausser mir die Muehe darzustellen, was er unter funktional versteht. Ich beziehe mich der Einfachheit halber auf:
programming paradigm that treats computation as the evaluation of mathematical functions and avoids state and mutable data
Durch die Anlehnung an mathematische Funktionen kann ich den Wert eines Ausdrucks durch sukzessive Substitution ermitteln. In imperativen Sprachen wie C++ ist das nicht moeglich, da ich nur Befehle oder Instruktionen substituieren kann, aber der Wert eines Ausdrucks nur durch die Abarbeitung der Instruktionen ermittelt werden kann.
Gehen wir weiter zu map, filter und fold und schauen uns diese in C++ an: http://www.cplusplus.com/reference/std/numeric/accumulate/ . Zeile 5: Zuweisung, also Zustandsaenderung! Dabei haben wir die Sprachebene von C++ nicht verlassen. Zwar wird fuer map, filter und fold in funktionalen Sprachen wie SML sicher auch das Assembleraequivalent einer Schleife generiert, doch wird dabei die Sprachebene von SML verlassen. Grund dafuer ist die vorherrschende Rechnerachitektur.
Fazit: Auch wenn Closures oder funktionen hoeherer Ordnung Elemente der Sprache sind, heisst das noch lange nicht, dass die Sprache das funktionale Programmierparadigma unterstuetzt.
der/das Schild
An sowas habe ich auch schon gedacht und lasse mich gern belehren. Also der Kalkuel.
Es basiert nur oberflächlich darauf. Er hat sich inspirieren lassen, es aber nicht richtig umgesetzt.
Ich gebe dir recht. Lisp ist sowieso so eine Sache und wird von Lispern nicht als funktionale Sprache angesehen.
-
knivil schrieb:
Im englischen Artikel dazu ist das nicht vermerkt.
Dann wirds aber Zeit.
-
Fazit: Auch wenn Closures oder funktionen hoeherer Ordnung Elemente der Sprache sind, heisst das noch lange nicht, dass die Sprache das funktionale Programmierparadigma unterstuetzt.
Natürlich unterstützt sie es.
Es ist nur in C++ wesentlich einfacher auszubrechen als in anderen funktionalen Sprachen.
Wenn man sich strikt nach "avoids state and mutable data" richtet, bleiben kaum mehr Sprachen übrig. Alle praktikablen funktionalen Sprachen erlauben das auf die eine oder andere Weise.
-
Tyr schrieb:
C++-Code macht das gleiche wie Assemblercode, also ist Assembler funktional.
Das ist ja mal Quatsch. Beim Paradigma geht es doch nicht um die Mächtigkeit, sondern, ich wiederhole mich, um den Stil. Mit Assembler bekommt man keinen funktionalen Stil hin, mit C++ schon. Also unterstützt C++ das funktionale Programmierparadigma, aber da wie du sagtest dieses nicht fundamental in der Sprache verankert ist, ist C++ keine funktionale Programmiersprache.
knivil schrieb:
Gehen wir weiter zu map, filter und fold und schauen uns diese in C++ an: http://www.cplusplus.com/reference/std/numeric/accumulate/ . Zeile 5: Zuweisung, also Zustandsaenderung!
Na und? C++ erzwingt funktionale Programmierung nicht. Hier wäre eine funktionale Version von accumulate:
template <class InputIterator, class T> T accumulate ( InputIterator first, InputIterator last, T init ) { return first == last ? init : *first + accumulate(next(first), last, init); }
next
bekommst du wahrscheinlich allgemein nicht ohne Seiteneffekte hin, das liegt aber nicht an C++, sondern am Konzept der Iteratoren.Die Rekursion natürlich auch das Problem des evntl. Stackoverflows, für den funktionalen Stil spielt das aber keine Rolle (das ist auch ein Kompromiss, den man in C++ eingehen muss, weshalb man nahezu immer die imperative Variante mit der Schleife wählen wird - aber wenn man will, kann man).
-
ipsec schrieb:
Na und? C++ erzwingt funktionale Programmierung nicht. Hier wäre eine funktionale Version von accumulate:
template <class InputIterator, class T> T accumulate ( InputIterator first, InputIterator last, T init ) { return first == last ? init : *first + accumulate(next(first), last, init); }
Also ist C++ funktional, weil in C++ StatementExpr unterstützt ? Ein anderen Sinn seh ich in diesen Beispiel nicht.
btw ich finds intressent dass die Leute sagen, C++ ist funktional dies anhand sehr konkreten Stellen machen während die es nicht, nur eine Leitsatz zu hand haben um dies zu entscheiden.
-
Zeus schrieb:
ipsec schrieb:
Na und? C++ erzwingt funktionale Programmierung nicht. Hier wäre eine funktionale Version von accumulate:
template <class InputIterator, class T> T accumulate ( InputIterator first, InputIterator last, T init ) { return first == last ? init : *first + accumulate(next(first), last, init); }
Also ist C++ funktional, weil in C++ StatementExpr unterstützt ? Ein anderen Sinn seh ich in diesen Beispiel nicht.
btw ich finds intressent dass die Leute sagen, C++ ist funktional dies anhand sehr konkreten Stellen machen während die es nicht, nur eine Leitsatz zu hand haben um dies zu entscheiden.
Der Sinn des Beispiels: nur weil auf c-plusplus.com/reference eine imperative Implementierung von accumulate steht, heißt das keineswegs, dass man es nicht auch funktional implementeiren kann.
Hast du irgendeinen Algorithmus, der in C++ nicht funktional zu implementieren geht?
-
ipsec schrieb:
Hast du irgendeinen Algorithmus, der in C++ nicht funktional zu implementieren geht?
Du weiß ganz genau, dass wegen den nicht obligatorischen Tail-Recursion Optimierung die einfachsten mathematische Funktionen nicht portable genug sind um sie funktional implementiert bereitzustellen.
-
Zeus schrieb:
ipsec schrieb:
Hast du irgendeinen Algorithmus, der in C++ nicht funktional zu implementieren geht?
Du weiß ganz genau, dass wegen den nicht obligatorischen Tail-Recursion Optimierung die einfachsten mathematische Funktionen nicht portable genug sind um sie funktional implementiert bereitzustellen.
Damit ist nur gesagt, dass es nicht sinnvoll ist, in C++ funktional zu programmieren (dem stimme ich auch zu), aber nicht, dass es nicht ginge.
-
ipsec schrieb:
Zeus schrieb:
ipsec schrieb:
Hast du irgendeinen Algorithmus, der in C++ nicht funktional zu implementieren geht?
Du weiß ganz genau, dass wegen den nicht obligatorischen Tail-Recursion Optimierung die einfachsten mathematische Funktionen nicht portable genug sind um sie funktional implementiert bereitzustellen.
Damit ist nur gesagt, dass es nicht sinnvoll ist, in C++ funktional zu programmieren (dem stimme ich auch zu), aber nicht, dass es nicht ginge.
Damit werden wir nie Grün, weil das Paradigma ein Leitgedanke ist, dass du nicht anhand von detailierten Kleinkram festmachen kannst.
-
Zeus schrieb:
btw ich finds intressent dass die Leute sagen, C++ ist funktional dies anhand sehr konkreten Stellen machen während die es nicht, nur eine Leitsatz zu hand haben um dies zu entscheiden.
Du findest meine Argumentation schlecht? Was sollte ich denn verbessern?
Angenommen Closures und Funktionen hoeherer Ordnung sind einziges Kriterium. In C++ sind Closures und Funktionen hoeherer Ordnung im Vergleich zu funktionalen Sprachen sehr, sehr beschraenkt. Also unterstuetzt C++ das funktionale Programmierparadigma sehr, sehr beschraenkt.
heißt das keineswegs, dass man es nicht auch funktional implementeiren kann
Aber darum geht es nicht. Es geht nicht darum was so alles moeglich ist, sondern in wiefern mich die Sprache unterstuetzt. Was also wirklich gemacht wird. Schauen wir uns doch mal die STL an. Alle Datenstrukturen sind mit Seiteneffekten behaftet.
avoids mutable state/data
? Selbst dasMinibeispiel
accumulate macht Schwierigkeiten. Um funktional zu sein, muss ich in C++ ziemlich viel ignorieren/wegschmeissen und neu implementieren. Klar ist das moeglich, aber das nennst du Unterstuetzung? Quatsch!dass es nicht sinnvoll ist, in C++ funktional zu programmieren
Genau deswegen unterstuetzt C++ nicht das funktionale Programmierparadigma.
-
knivil schrieb:
Angenommen Closures und Funktionen hoeherer Ordnung sind einziges Kriterium. In C++ sind Closures und Funktionen hoeherer Ordnung im Vergleich zu funktionalen Sprachen sehr, sehr beschraenkt. Also unterstuetzt C++ das funktionale Programmierparadigma sehr, sehr beschraenkt.
Das ist ja schonmal besser als "gar nicht"
Um funktional zu sein, muss ich in C++ ziemlich viel ignorieren/wegschmeissen und neu implementieren.
Oder vom funktionalen Paradigma Dinge weglassen.
-
knivil schrieb:
Zeus schrieb:
btw ich finds intressent dass die Leute sagen, C++ ist funktional dies anhand sehr konkreten Stellen machen während die es nicht, nur eine Leitsatz zu hand haben um dies zu entscheiden.
Du findest meine Argumentation schlecht? Was sollte ich denn verbessern?
Eigentlich dachte wir sind im selben Boot.
-
Zeus schrieb:
Eigentlich dachte wir sind im selben Boot.
Dachte ich auch!
-
Zeus schrieb:
ipsec schrieb:
Hast du irgendeinen Algorithmus, der in C++ nicht funktional zu implementieren geht?
Du weiß ganz genau, dass wegen den nicht obligatorischen Tail-Recursion Optimierung die einfachsten mathematische Funktionen nicht portable genug sind um sie funktional implementiert bereitzustellen.
Tail Call Optimization ist ein Compiler Problem, kein Sprachproblem.
http://drdobbs.com/184401756Moderne Compiler koennen teilweise Tail Call Optimization. Es ist in C++ halt ein komplexes Thema und bringt nahezu nie etwas, deshalb wird es nicht mit aller Kraft verfolgt.
Beispiel:
int add(int a, int b) { if (b == 0) return a; return add(1 + a, b - 1); }
Das macht mein VC++ zu
PUBLIC _add ; Function compile flags: /Ogtpy ; File d:\code\tailrecursiontest\tailrecursiontest\main.c _TEXT SEGMENT _a$ = 8 ; size = 4 _b$ = 12 ; size = 4 _add PROC ; 24 : if (b == 0) ; 25 : return a; ; 26 : return add(1 + a, b - 1); mov eax, DWORD PTR _a$[esp-4] mov ecx, DWORD PTR _b$[esp-4] inc eax dec ecx je SHORT $LN8@add mov DWORD PTR _b$[esp-4], ecx mov DWORD PTR _a$[esp-4], eax jmp _add $LN8@add: ; 27 : } ret 0
Also ist C++ jetzt funktional weil wir Tail Call Optimzation haben?
-
int add(int a, int b) { if (b == 0) return a; return add(1 + a, b - 1); }
macht gcc 4.5 (mingw) mit -O3 -march=native auf AMD Sempron 3000+ zu
pushl %ebp movl %esp, %ebp movl 8(%ebp), %eax addl 12(%ebp), %eax leave ret
Also ist C++ funktional.