Java in C++ programmieren - Programmier- und Designunterschiede
-
Ich hab mir Gestern mal nach Lesen dieses Threads Erlang angeschaut und anfangs dachte ich mir bei der Syntax schon ein wenig "WTF??", aber wenn man ein Schrittweises Tutorial durchgeht, dann erkennt man tatsächlich wie einfach die Syntax eigentlich ist.
An das Programmiermodell muss man sich natürlich gewöhnen, aber wer schon einmal etwas in das funktionale Programmieren reingeschaut hat wird schnell zurecht kommen.Ich frage mich nur immer wieder ob solche Operationen wie die Länge einer Liste über abzählen und das Invertieren einer Liste wirklich effizient in solchen Sprachen sind.
In meinen vertrauten Sprachen hat man für gewöhnlich doppelt verkettete Listen und ein Attribut das die Länge speichert.Dazu kommt, dass Erlang in einer VM läuft und ich nicht weiß wei ausgereift diese ist.
-
Ich glaub nicht daran, dass das Paradigma entscheidet ist. Der Vorteil in Erlangen ist das Synchronisationskonzept. C++ bietet nix, Java Monitore mit JCSP sorgar synchrone Messageverarbeitung. Erlangen hat asynchrone Messageverarbeitung.
-
Zeus schrieb:
Ich glaub nicht daran, dass das Paradigma entscheidet ist. Der Vorteil in Erlangen ist das Synchronisationskonzept. C++ bietet nix, Java Monitore mit JCSP sorgar synchrone Messageverarbeitung. Erlangen hat asynchrone Messageverarbeitung.
Der Unterschied ist, dass du in diesen Sprachen immer über globale Variablen/Objekte Daten austauschen kannst. Bei Erlang hast du gar nicht erst diese Möglichkeit, es gibt also keinen globalen State der irgendwie manipuliert werden kann.
Somit gibt es einfach keine Möglichkeit auf verborgene Art und Weise auf andere Threads einfluss zu nehmen.Das ist schon eine ganze Menge, denn so lange man die Möglichkeit hat einen globalen State zu haben und zu manipulieren wird es auch gemacht, aus Bequemlichkeit, Gewohnheit, etc.
Von daher hat die neue Sprache und das neue Paradigma (bezogen auf eine Umstellung) den Effekt, dass man quasi die alte Herangehensweise wegwerfen muss und gar nicht erst in die Falle tappt so zu programmieren wie man es bisher gewohnt war (siehe C+ statt C++).
Gegen Lernresistenz ist natürlich kein Kraut gewachsen, so im Sinne von dem Spruch "You can program Fortran in any language".
-
Oder machen wir es einfacher:
Es gibt keine bessere Antwort auf das Multicore Problem (und auch Power Prozessoren bringen hier keinen entscheidenden Vorteil gegenüber x86 da das Problem nicht der Prozessor sondern die Software ist - Power macht ein paar Sachen einfacher, aber das wirkliche Problem dass wir haben ist Shared State) als Shared State zu eliminieren. Oder einfacher ausgedrückt: pure funktionen.
Nur sind pure funktionen in Sprachen wie C++ nicht wirklich integriert - man verwendet sie zwar aber es gibt das Konzept nicht. Funktionale Sprachen haben idR nur pure Funktionen und dann wenige Funktionen die auf shared state zugreifen.
DAS ist der Vorteil.
-
Shade Of Mine schrieb:
Oder machen wir es einfacher:
Es gibt keine bessere Antwort auf das Multicore Problem (und auch Power Prozessoren bringen hier keinen entscheidenden Vorteil gegenüber x86 da das Problem nicht der Prozessor sondern die Software ist - Power macht ein paar Sachen einfacher, aber das wirkliche Problem dass wir haben ist Shared State) als Shared State zu eliminieren. Oder einfacher ausgedrückt: pure funktionen.
Nur sind pure funktionen in Sprachen wie C++ nicht wirklich integriert - man verwendet sie zwar aber es gibt das Konzept nicht. Funktionale Sprachen haben idR nur pure Funktionen und dann wenige Funktionen die auf shared state zugreifen.
DAS ist der Vorteil.
Pah! Das geht in Java auch. Siehe Java Monitor
-
!!! schrieb:
...wie vor Urzeiten programmieren?...
Kleiner Tipp: Nicht alles, was man auch früher schon gemacht hat, ist "veraltet" (im Sinne von "ist heutzutage unnötig/schlecht/falsch/...").
Beispiel: Atmen
Ansonsten hat es IMHO rüdiger gut auf den Punkt gebracht:
rüdiger schrieb:
...Jede Programmiersprache bringt eigene Strategien, Ideen und Konzepte mit...
Deswegen ist es ziemlich quatschig zu fragen, ob man mit Java besser C++ oder mit C++ besser Java programmieren kann. (lediglich Fortran ist dafür bekannt, dass man es in jeder Programmiersprache schreiben kann.
)
Z.B.: Ich würde als Trend (aus meiner Erfahrung heraus) sagen, dass
- C++ eher compilezeitverliebt ist, wo Javaisten stärker auf die Laufzeit vertrauen,
- C++ eher min- und Java eher maximalistisch beim Thema "Standardfunktionsumfang" ist ("Nur, was wirklich jeder braucht" <-> "Alles, was irgendjemand brauchen könnte")
- ...
Das hat nichts mit "gut"/"schlecht" zu tun, sondern sind einfach unterschiedliche Philosophien, denen man sich tunlichst unterwerfen sollte.
Wer krampfhaft versucht, in Java soviel RAII einzusetzen wie in C++ oder Reflection in C++ wie in Java, der bricht sich übelst und in 99% unnötig die Finger.
... und kommt am Ende (für niemanden überraschend) zu dem Schluss, die jeweils andere PG-Sprache sei total unbrauchbar und werde nur von Idioten benutzt.Gruß,
Simon2.
-
fricky schrieb:
Pah! Das geht in Java auch. Siehe Java Monitor
Bemüh dich beim trollen wenigstens...
Ich habe nie gesagt dass funktionale Sprachen das beste sind was es gibt. Aber ich habe das Gefühl dass sobald neue Informationen kommen viele Leute einfach automatisch abblocken.
Natürlich können Java Montors verwendet werden um das Problem des shared state zu umgehen, aber wie funktionen die denn? Das weisst du natürlich nicht, oder? Du kannst nicht pro Funktion einen eigenen Monitor bauen.
Monitors sind auf Thread ebene recht nett, aber sind sie es auch auf function ebene? In funktionalen Sprachen kann ich zB ohne probleme folgendes automatisch parallelisieren:
let f = add(x, 7) * foo()oder viel lustiger:
let f = fib(100)
ich kann DAS parallelisieren. (wobei fibonacci zahlen jetzt n doofes beispiel sind, aber man kann rekursion einfach parallelisieren ohne irgendwelche probleme und zwar AUTOMATISCH).Das ganze geht in Java nicht. Denn Monitors, was sind sie denn genau: nichts anderes als automatisch synchronisierte Blöcke. Und das ist schonmal das essentielle Problem: synchronisation.
Man will aber nicht synchronisieren. denn das bedeutet dass man wieder engstellen hat. indem man aber keinen shared state hat, hat man _keine_ synchronisierung notwendig.
das ganze läuft dann soweit, dass man nur sehr sehr sehr wenige shared resources hat auf die man uU sogar block-free zugreifen kann...
-
Wo du gerade Fibonacci-Zahlen ansprichst, hier verwendet man normalerweise ja dynamisches Programmieren um einen effizienten Algorithmus zu implementieren.
Wie würde man die Fibonacci-Zahl(en) in einer funktionalen Sprache berechnen?
-
Rekursiv, wie alles in funktionalen Sprachen. Wenn du Glück hast, optimiert der Compiler sogar das primitive
fib(x) = if x > 1 then fib(x-1) + fib(x-2) else 1
, ansonsten schleifst du immer zwei Werte mit, hab dazu sogar noch was in Erlang:-module(fib). -export([fib/1]). fib(0) -> 1; fib(N) when N >= 0 -> {Res, _} = fib_helper(N), Res . fib_helper(1) -> {1, 1}; fib_helper(N) when integer(N) -> {N_min1, N_min2} = fib_helper(N-1), {N_min2 + N_min1, N_min1} .
-
.filmor schrieb:
Aber du wirst auf absehbare Zeit keinen nicht-x86er auf dem normalen PC-Markt durchsetzen können.
Auch x86 CPUs kann man besser entwerfen, denn das Problem hat nichts mit dem Befehlssatz zu tun. Von der Vorstellung was anderes als x86 auf dem Desktop hätte eine Chance habe ich mich verabschiedet.
.filmor schrieb:
Abgesehen davon, hast du einen Link (oder eine eigene Erklärung), was da der wichtige Unterschied ist?
In Kurzform ein zentraler Bus vs. viele IO-Kanäle und ein MCM mit LPAR Hypervisor Stack.
Bei IBM gibt es meist ausführliche Artikel, nur findet man die so leicht, wenn man nicht weiß wonach man konkret suchen muß. Die beiden Links sind in diesem Zusammenhang ganz brauchbar.
http://www.research.ibm.com/journal/rd51-6.html
http://www.research.ibm.com/journal/rd/494/sinharoy.html
-
@.filmor wieso nicht in der uns allen liebsten funktionalen sprache?
template<int I> struct Fibonacci { enum { value = Fibonacci<I-1>::value + Fibonacci<I-2>::value }; }; template<> struct Fibonacci<1> { enum { value = 1 }; }; template<> struct Fibonacci<0> { enum { value = 1 }; };
das ganze habe ich aus reiner faulheit mal hier
http://knanshon.blogspot.com/2006/05/c-meta-programming-fibonacci-and-phi.html
kopiert.
-
Prokkrammierer schrieb:
Wo du gerade Fibonacci-Zahlen ansprichst, hier verwendet man normalerweise ja dynamisches Programmieren um einen effizienten Algorithmus zu implementieren.
Wie würde man die Fibonacci-Zahl(en) in einer funktionalen Sprache berechnen?
das ist das tolle:
let fib 1 = 1
let fib 0 = 1
let fib n = fib(n-1) + fib(n-2);;und das war es. denn fib(7) liefert immer das selbe ergebnis. man hat somit automatisch memoization als optimierung. und je nachdem wie gut die compiler optimieren kann ein fib(100) bereits zur compiletime gelöst werden. denn eine pure funktion liefert für den selben eingabwert immer den selben ausgabewert und hat keine seiteneffekte.
das interessante dabei:
let x=fib(100)
let y=fib(200)das kann parallelisiert werden und auf einen gemeinsamen cache zurück greifen so dass fib(7) nur _einmal_ berechnet werden muss. die frage in wie weit das in der praxis umgesetzt ist, ist natürlich etwas anderes. aber pure funktionen bieten dir genau diese möglichkeit. (unabhängig von funktionaler programmierung oder nicht. es sind die pure funktionen die so wertvoll sind, nicht das funktionale paradigma)
-
ghorst schrieb:
@.filmor wieso nicht in der uns allen liebsten funktionalen sprache?
template<int I> struct Fibonacci { enum { value = Fibonacci<I-1>::value + Fibonacci<I-2>::value }; }; template<> struct Fibonacci<1> { enum { value = 1 }; }; template<> struct Fibonacci<0> { enum { value = 1 }; };
das ganze habe ich aus reiner faulheit mal hier
http://knanshon.blogspot.com/2006/05/c-meta-programming-fibonacci-and-phi.html
kopiert.Und wie kann ich damit den Benutzer nach der gewünschten Zahl fragen und diese dann berechnen?
-
damit gar nicht. wozu will man auch den nutzer irgendetwas fragen???
-
Er meint wie Benutzer er das Gerüst um etwas zu berechnen.
-
Shade Of Mine schrieb:
Es gibt keine bessere Antwort auf das Multicore Problem als Shared State zu eliminieren.
Wenn da statt "eliminieren" "minimieren" stünde, könnte man das ja unterstützen. Aber die meisten wichtigen Anwendungen leben von Shared State, siehe DBMS. Da ist in den letzten Jahrzehnten so ziemlich alles parallelisiert worden, was möglich ist. In Großrechner sind SMP-Knoten eine alte Geschichte.
-
Zeus schrieb:
Er meint wie Benutzer er das Gerüst um etwas zu berechnen.
int a=Fibonacci<10>::value;
-
Schreiben sie eine Anwendung welche den Anwender nach der i-ten Fibonacci-Zahl fragt, berechnen sie diese und geben sie diese anschließend aus.
Wie mache ich das mit deiner Methode?
-
schlagen sie einen nagel in die wand.
wie machen sie das, wenn sie nur einen schraubendreher habe?
ich besorge mir ein passendes werkzeug.die funktionale programmierung in c++ ist nicht für benutzerinteraktion ausgelegt...
-
@Shade, der naive Ansatz mit fib(n)=fib(n-1)+fib(n-2) versagt aber bereits bei 100mio bei 1,5Ghz und 768MB Ram (wird heftig geswappt, habe nach 3min abgebrochen).
Mit .filmors Variante (die aus der dynamischen Programmierung) versuche ich gerade mal 1mrd, aber dauert auch seine Zeit, aber die Speicherverbrauch steigt nur sehr sehr langsam an).