Verleitet C++ zum komplizierteren denken?
-
volkard schrieb:
Da hat aber jemand die Objektprogrammierung nicht verstanden.
nämlich ?
-
u_ser-l schrieb:
volkard schrieb:
Da hat aber jemand die Objektprogrammierung nicht verstanden.
nämlich ?
Es ging darum Matrizen mit Vektoren zu multiplizieren, natürlich soll auch Matrix*Matrix und Vektor*Vektor gehen. Anscheinend willst Du Vektoren als Matrizen erscheinen lassen und nur die Matrizenmultiplikation anbieten.
Du verlangst dazu eine spezielle Schnittstelle der Matrix mit Zugang zu Interna, statt erstmal das double dispatching auszuführen. Und wirst bereits bei dünn besetzten (sparse) Matrizen voll auf die Schnauze fliegen.
-
~john schrieb:
Ich wußte schon immer, daß die ganzen C++ Nörgler Unwissende sind.
Wenn ich Volkard wäre, käme der Satz in die Signatur.
-
volkard schrieb:
Und wirst bereits bei dünn besetzten (sparse) Matrizen voll auf die Schnauze fliegen.
dünn besetzte Matrize speichert man ja wohl auch in anderen Klassen als Arrays und definiert demzufolge auch andere Methoden - gleichwohl einen do:-Iterator. Wo ist das Problem? Nichts schließt den Zugriff auf Vektorelemente über öffentliche Interfaces aus, sei es als Liste (dünn) oder Array (dicht) - im Gegenteil ist ein öffentliches Interface für Zugriff auf die Elemente eines Vektors sogar vernünftig.
Du weißt schon, daß es in Smalltalk gängig ist, für Objekte aus Klassen, deren "Inhalt" im weitesten Sinne aufzählbar ist, ("Collections"), einen do:-Iterator zu definieren, der die gespeicherten Elemente nacheinander ausspuckt, um dann über einen Block weitgehend unabhängig von der genauen Speicherform nacheinander auf die Elemente zuzugreifen? Das hat nichts mit Verletzung von Datenkapselung zu tun, im Ggt. das ist OOP im besten Sinne.
-
u_ser-l schrieb:
volkard schrieb:
Und wirst bereits bei dünn besetzten (sparse) Matrizen voll auf die Schnauze fliegen.
dünn besetzte Matrize speichert man ja wohl auch in anderen Klassen als Arrays und definiert demzufolge auch andere Methoden - gleichwohl einen do:-Iterator. Wo ist das Problem?
Willst Du bei der sparse matrix die ganzen virtuellen Nullen aufzählen?
Ja? Dann verbrätst Du enorm viel Rechenzeit für absolut nichts. Für sagen wie zwei nxn-Matrizen mit je m Elementen brauchst Du O(n^3) statt O(n*m). Ein Trauerspiel sondergleichen.
Nein? Dann mußt Du jetzt die rausfließenden Daten des do:-Iterators nachträglich ändern und Index-Wert-Paare schicken. Zum Nachteil des gesamten bisherigen Codes.
Obige Komplexitätsangaben bei naiven Implementierungen, bei mehr Programmieraufwand wirds wohl zu O(n^2.38) statt O(m0.7*n1.2+n^2+O(1)), wobei die schnelleren Algos wieder nichts vom do:-Iterator haben.
-
u_ser-l schrieb:
Du weißt schon, daß es in Smalltalk gängig ist, für Objekte aus Klassen, deren "Inhalt" im weitesten Sinne aufzählbar ist, ("Collections"), einen do:-Iterator zu definieren, der die gespeicherten Elemente nacheinander ausspuckt, um dann über einen Block weitgehend unabhängig von der genauen Speicherform nacheinander auf die Elemente zuzugreifen? Das hat nichts mit Verletzung von Datenkapselung zu tun, im Ggt. das ist OOP im besten Sinne.
Nur leider ist eine Matrix nicht eine Aufzählung von Zeilenvektoren. Das ist einfach so nicht der Fall, sondern ist von Dir eine böse Frickelei. Vermutlich ein Implemetierungsdetail, das Du als universelle Tatsache darstellt. Das ist Objektprogrammierung im schlechtesten Sinne.
-
was redest du hier? ...
dünne Matrizen werden als Listen gespeichert, ohne die Nullelemente
Nochmal für Dich: in Smalltalk implementiert man für aufzählbare Klassen einen do:-Iterator, der im Beispiel die Listenelemte, also die Nicht-Null-Elemente einer dünnen Matrix, aufzählt.
-
u_ser-l schrieb:
was redest du hier? ...
dünne Matrizen werden als Listen gespeichert, ohne die NullelementeMuß nicht sein. Ich ging von einer Hashtable aus. Aber für Listen gilt mein Argument gleichermaßen.
u_ser-l schrieb:
Nochmal für Dich: in Smalltalk implementiert man für aufzählbare Klassen einen do:-Iterator, der im Beispiel die Listenelemte, also die Nicht-Null-Elemente einer dünnen Matrix, aufzählt.
Nochmal für Dich: Damit bricht der Multiplikationsalgorithmus zusammen und funktioniert nicht mehr.
-
meinetwegen auch mit Hashtables. Hier mal ein Vektorprodukt:
V := Dictionary new. W := Dictionary new. V at: 1 put: 3; at: 4 put: 1; at: 7 put: 4. W at: 1 put: 2; at: 2 put: 3; at: 7 put: 5; at: 11 put: 3. D := 0. V keys do: [ :v | (W includesKey: v) ifTrue: [ D := D + ((V at: v) * (W at: v)) ] ]. Transcript show: D; cr.
da bricht gar nichts zusammen, das ist OOP++, aus der Zukunft
-
u_ser-l schrieb:
meinetwegen auch mit Hashtables. Hier mal ein Vektorprodukt:
V := Dictionary new. W := Dictionary new. V at: 1 put: 3; at: 4 put: 1; at: 7 put: 4. W at: 1 put: 2; at: 2 put: 3; at: 7 put: 5; at: 11 put: 3. D := 0. V keys do: [ :v | (W includesKey: v) ifTrue: [ D := D + ((V at: v) * (W at: v)) ] ]. Transcript show: D; cr.
da bricht gar nichts zusammen, das ist OOP++, aus der Zukunft
Das ist Objektprogrammierung aus der Fäkaliengrube.
So wäre es vorher nicht implementiert gewesen. Und die zusätzliche Rechenzeit in der Neuimplemetierung will wirklich keiner bei einer dickbesetzten Matrix bezahlen.
Es gibt Fälle, wo double dispatching einfach was Tolles ist, sieh es doch ein, statt Dich weiter lächerlich zu machen.Die Hashtable ist natürlich nicht ein Array von Zeilen-Hashtables, sondern Zeilen- und Spaltenindex werden zum hashkey kombiniert. Wie willste denn da den do:-Iterator über eine Zeile oder Spalte anbieten?
-
volkard schrieb:
Das ist Objektprogrammierung aus der Fäkaliengrube.
ach, eben brach es noch zusammen, jetzt, nach dem Gegenbeweise, ist es Objektprogrammierung
volkard schrieb:
Die Hashtable ist natürlich nicht ein Array von Zeilen-Hashtables, sondern Zeilen- und Spaltenindex werden zum hashkey kombiniert.
das ändert am Prinzip gar nichts.
volkard schrieb:
Wie willste denn da den do:-Iterator über eine Zeile oder Spalte anbieten?
du scheinst es einfach nicht zu kapieren: für jede Klasse, deren Inhalt im weiteren Sinne aufzählbar ist ("Collections") implementiert man do: (ungefähr das, was man in anderen Sprachen "Iterator" nennt) - hat man Elemente einer dünn besetzten Matrix in einer Liste gespeichert, gibt es einen do:-Iterator, der die Listenelemente ausgibt. Braucht man aus Performancegründen direkten Zugriff und speichert in einer Hashtable mit eincodierter Zeile/Spalte, implementiert man eben einen accessor der Form atLine: column: ... wo ist das Problem? Setz' mal die C++-Brille ab, mit der du hier offenbar Typinkompatibilitäten argwöhnst wo keine sind.
-
u_ser-l schrieb:
volkard schrieb:
Das ist Objektprogrammierung aus der Fäkaliengrube.
ach, eben brach es noch zusammen, jetzt, nach dem Gegenbeweise, ist es Objektprogrammierung
Zuerst war ja auch nur von einem do:-Iterator die Rede. Du hast die keys: neu eingeführt, um den Zusammenbruch zu vertuschen.
volkard schrieb:
Die Hashtable ist natürlich nicht ein Array von Zeilen-Hashtables, sondern Zeilen- und Spaltenindex werden zum hashkey kombiniert.
das ändert am Prinzip gar nichts.
Du mußt aber dann den Code schon wieder umfrickeln. Das ist traurig.
volkard schrieb:
Wie willste denn da den do:-Iterator über eine Zeile oder Spalte anbieten?
du scheinst es einfach nicht zu kapieren: für jede Klasse, deren Inhalt im weiteren Sinne aufzählbar ist ("Collections") implementiert man do: (ungefähr das, was man in anderen Sprachen "Iterator" nennt) - hat man Elemente einer dünn besetzten Matrix in einer Liste gespeichert, gibt es einen do:-Iterator, der die Listenelemente ausgibt. Braucht man aus Performancegründen direkten Zugriff und speichert in einer Hashtable mit eincodierter Zeile/Spalte, implementiert man eben einen accessor der Form atLine: column: ... wo ist das Problem?
Nimmst Du jetzt zum Multiplizieren auf einmal den accessor? Nochmal umfrickeln also?
Entscheide doch vorher anhand der Typen, welche Multiplikationsimplementierung gewählt wird, die mit do:, die mit keys do: oder die mit accessor oder noch was cooleres, mehr will ich doch gar nicht. double dispatching halt. und dann muß auch der alte code nie umgefrickelt werden. wäre das nich toll?
Es gibt sogar böse Leute, die lehren das für Geld: http://www.arsnova.de/content/index_fl.php?main=4_Training&sub=3_Smalltalk Kurse&subsub=2_Smalltalk für Fortgeschrittene&file=content.php
-
Wurde schon erwähnt, dass C++ eine aussterbende Sprache ist?
-
volkard schrieb:
Das (void) da ist sehr ungewöhnlich. Das war mal in C nötig, weil () beliebig viele Argumente akzeptierte (Ich hoffe, daß es inzwischen auch in C repariert worden ist.).
Nein, noch gibt es MISRA Regeln und diese schreiben es so vor. Finde ich gut. Genauso wie ein return; bei void Funktionen:
void func(void) { ... return; }
Aber sagt MISRA einem PC Programmierer überhaupt was?
Nur aus Neugier, benutzt jemand (freiwilligoder weil er muss) in seinen Projekten irgendwelche QAC/QAC++ Checker?
-
abc.w schrieb:
Aber sagt MISRA einem PC Programmierer überhaupt was?
mir sagt MISRA schon was. der zwang zu (void) ist eine typische heldentat solcher kommitees. mein beileid. naja, es verursacht ja keinen schaden und wenns in dieser branche alle tun, kann man sich leicht dran gewönen. das return; kann ich mir für C noch vorstellen, ist bei C++ aber sehr seltsam - gilt das auch für C++?
-
dünn besetztes Matrix-Vektor-Produkt:
V1 := Dictionary new. V2 := Dictionary new. V1 at: 1 put: 3; at: 3 put: 1; at: 4 put: 4. V2 at: 1 put: 2; at: 4 put: 11. M := Dictionary new. M at: 1 put: V1; at: 3 put: V2. W := Dictionary new. W at: 1 put: 1; at: 3 put: 1. X := Dictionary new. M keys do: [ :i | d := (M at: i) dotProduct: W. (d = 0) ifFalse: [ X at: i put: d ] ]. "X = M * W " " | 3 0 1 4 | | 1 |" " = | 0 0 0 0 | x | 0 |" " | 2 0 0 11 | | 1 |" " | 0 |"
-
u_ser-l schrieb:
dünn besetztes Matrix-Vektor-Produkt:
V1 := Dictionary new. V2 := Dictionary new. V1 at: 1 put: 3; at: 3 put: 1; at: 4 put: 4. V2 at: 1 put: 2; at: 4 put: 11. M := Dictionary new. M at: 1 put: V1; at: 3 put: V2. W := Dictionary new. W at: 1 put: 1; at: 3 put: 1. X := Dictionary new. M keys do: [ :i | d := (M at: i) dotProduct: W. (d = 0) ifFalse: [ X at: i put: d ] ]. "X = M * W " " | 3 0 1 4 | | 1 |" " = | 0 0 0 0 | x | 0 |" " | 2 0 0 11 | | 1 |" " | 0 |"
Wieder ein Versuch, mich zu veralbern. Aber der ist doch längst schon vorweggenommen.
u_ser-l schrieb:
volkard schrieb:
volkard schrieb:
Die Hashtable ist natürlich nicht ein Array von Zeilen-Hashtables, sondern Zeilen- und Spaltenindex werden zum hashkey kombiniert.das ändert am Prinzip gar nichts.
Anscheinend doch.
Lies auch double dispatching in smalltalk:
http://www.mimuw.edu.pl/~sl/teaching/00_01/Delfin_EC/Patterns/DoubleDispatch.htm
-
abc.w schrieb:
Aber sagt MISRA einem PC Programmierer überhaupt was?
MISRA erinnert mich an "miserabel"
Aber das ist doch so ein Fahrzeug/Auto C Standard, oder? Irgendwo mal gehört, war glaub ich in irgendeiner Vorlesung.Grüssli
-
u_ser-l schrieb:
dünn besetztes Matrix-Vektor-Produkt:
V1 := Dictionary new. V2 := Dictionary new. V1 at: 1 put: 3; at: 3 put: 1; at: 4 put: 4. V2 at: 1 put: 2; at: 4 put: 11. M := Dictionary new. M at: 1 put: V1; at: 3 put: V2. W := Dictionary new. W at: 1 put: 1; at: 3 put: 1. X := Dictionary new. M keys do: [ :i | d := (M at: i) dotProduct: W. (d = 0) ifFalse: [ X at: i put: d ] ]. "X = M * W " " | 3 0 1 4 | | 1 |" " = | 0 0 0 0 | x | 0 |" " | 2 0 0 11 | | 1 |" " | 0 |"
Ich frag mich gerade, was an diese Struktur objektprogrammiert sein soll o_O vielleicht liegt es ja nur an meine nicht vorhanden Wissen über Smalltalk.
-
volkard schrieb:
das return; kann ich mir für C noch vorstellen, ist bei C++ aber extrem schwachsinnig - gilt das auch für C++?
Habe gerade die Meldungen eines QAC++ Checker durchsucht, keine passende Regel gefunden, wahrscheinlich doch schwachsinnig für C++...
Dravere schrieb:
Aber das ist doch so ein Fahrzeug/Auto C Standard, oder?
Ja, so ungefähr, eher eine Zusammenstellung von Regeln. MISRA ist halb so schlimm, schlimm sind die Mitarbeiter (Vorgesetzten) die die Regeln für ein Projekt zusammenstellen