Discussion:
Wirkliche Einschränkungen von JAVA
(zu alt für eine Antwort)
Thomas Thiele
2007-07-20 12:27:58 UTC
Permalink
Hallo,

ich wollte mal Nachfragen, welche Nachteile oder besser Fehler ihr in
Java in Vergleich zu anderen Programmiersprachen seht. Ich meine nicht
Sachen die in Java und der Philosophie begründent liegen,
sondern Eigenschaften, die es unmöglich machen etwas bestimmtes zu
programmieren.

C++ Programmierer mögen Operatorüberladung und Mehrfachvererbeung
vermissen. Das meine ich z.B.
nicht. Denn beide Dinge kann man mehr oder weniger hübsch mit anderen
Konstrukten lösen.
Auch das Java als Programmierparadigma Objektorientierung (scheinbar)
erzwingt ist keine Einschränkung in dem Sinne.

Was ich meine sind harte Einschränkungen die es unmöglich machen etwas
bestimmtes zu programmieren oder wirklich zu schlimmeren Fehlern
führen.

Meine Beispiele:

1. Zerstörung von Objekten nicht "just in time".
--------------------------------------------------------------------
Garbagecollection und die Nichtnotwenigkeit sich um Aufräumarbeiten zu
kümmern mag ein Vorteil sein. Aber die Java-Garbagecollection
garantiert eben nicht - wie bei Python beispielsweise - die sofortige
Zerstörung (bzw. wenigstens den sofotigen Aufruf eines Destruktors)
wenn das Objekt den Sichtbarkeitsbereich verlässt.
D.h. durch verspätete destruierung bzw. der Unmöglichkeit einer
automatischen Destruierung entstehen Ressourcenleaks! Entgegen dem
Java-Versprechen...

2. Kein impliziter Copycontructor.
------------------------------------------------
Aus Bibliothek gibt es eine Klasse: (aufs wesentliche gekürzt)

class A{
private int a;
int getA(){return a;}
}

Also unspannend. Ein simpler Datencontainer.
Jetzt benöge ich dazu eine Erweiterung, weil ich zusätzlich Daten
brauche:

class B extends A{
private int b;
int getB(){return b;}
void setB(int b){ this.b = b;}
}

Sieht auch unspektakulär aus.
Die Probleme beginnen wenn ich nur ein A Object bekomme aber ein B
Objekt für eigene Zwecke brauche:

Z.B.

// get A from the library function, that can only return an A
A a = libClass.createA();

// now I need the B...
B b = new B(a); //geht nicht!!!!!!!*
myClass.machwasmitB(b);

*ja, ja, syntaktisch geht das schon, ich kann einen solchen
Konstruktor schreiben.

B(A a){}

Aber was habe ich gekonnt? Mein B Objekt was per Vererbung ein A
Object _ist_ wird niemals
die private Variable a übernehmen.

3. Aufruf einer Funktion einer höheren Basisklasse nicht möglich
---------------------------------------------------------------------------------------------

Kein super.super.function(); möglich. Das ist Mist.

class A(){
void function1(){ /* ....*/};
void function2(){ /* ....*/};
}

class B extends A(){
void function2(){
/* ...was B-spezifisches... */
super.function2(); //die benötigte A funktionalität
};
void function3(){/*....*/}
}

class C extends B(){
void function2(){
/* ...was C-spezifisches... */
//super.function2(); //nein!!!!, ich will nix B-spezifisches!!!!
super.super.function2(); //aber das geht nicht
}
};


Fällt euch noch mehr ein?
Jochen Theodorou
2007-07-20 14:14:26 UTC
Permalink
Post by Thomas Thiele
Hallo,
ich wollte mal Nachfragen, welche Nachteile oder besser Fehler ihr in
Java in Vergleich zu anderen Programmiersprachen seht. Ich meine nicht
Sachen die in Java und der Philosophie begründent liegen,
sondern Eigenschaften, die es unmöglich machen etwas bestimmtes zu
programmieren.
[...]

Eine solche Diskussion ist in der Regel relativ sinnlos, weil sich alles
irgendwie simulieren lässt. Kommt nur auf den Aufwand an.

[...]
Post by Thomas Thiele
1. Zerstörung von Objekten nicht "just in time".
um dich zu zitieren: "Sachen die in Java und der Philosophie begründent
liegen". Warum gilt das für das "zerstören" von Objekten plötzlich nicht?
Post by Thomas Thiele
--------------------------------------------------------------------
Garbagecollection und die Nichtnotwenigkeit sich um Aufräumarbeiten zu
kümmern mag ein Vorteil sein. Aber die Java-Garbagecollection
garantiert eben nicht - wie bei Python beispielsweise - die sofortige
Zerstörung (bzw. wenigstens den sofotigen Aufruf eines Destruktors)
wenn das Objekt den Sichtbarkeitsbereich verlässt.
D.h. durch verspätete destruierung bzw. der Unmöglichkeit einer
automatischen Destruierung entstehen Ressourcenleaks! Entgegen dem
Java-Versprechen...
Ressourcen kann man auch schliessen ohne einen Destruktor zu benutzen.
Das Problem ist ja nicht so sehr das explizite Zerstören, sondern dass
das auch gemacht werden muss, wenn niemand den Destruktor im Code
aufruft. Übrigens werden in Java Objekte meist auch sofort collected,
wenn du sie in einer Methode angelegt hast und nach verlassen der
Methoden nicht mehr referenzierst. Das Problem sind doch eher langlebige
Objekte. Garantiert denn C++ dass der Destruktor aller Objekte
aufgerufen wird, wenn die Anwendung abstürzt?

Ich finde überhaupt mit finalize angefangen zu haben war ein Fehler.
Aber man wollte wohl die C++-Leute nicht so extrem vergraulen.. wegen
denen hat man ja auch primitives eingeführt. Ja gut, ich will es nicht
auf C++ schieben, das waren sicher noch genug andere ;)
Post by Thomas Thiele
2. Kein impliziter Copycontructor.
wie das zu Fehlern führt bin ich ja mal gespannt.

[...]
Post by Thomas Thiele
// get A from the library function, that can only return an A
A a = libClass.createA();
// now I need the B...
B b = new B(a); //geht nicht!!!!!!!*
myClass.machwasmitB(b);
*ja, ja, syntaktisch geht das schon, ich kann einen solchen
Konstruktor schreiben.
Zitat: "die es unmöglich machen etwas bestimmtes zu programmieren."

also meinst du ja was anderes ;)
Post by Thomas Thiele
B(A a){}
Aber was habe ich gekonnt? Mein B Objekt was per Vererbung ein A
Object _ist_ wird niemals
die private Variable a übernehmen.
ja und? Warum muss ich auch ein B konfigurieren mittels eines A? Und
vielleicht hast du ja mal die Diskussionen zu clone() verfolgt, das
stösst doch in die exakt gleiche Richtung, oder nicht? Ausserdem wer
sagt denn das in a ein A gespeichert ist und nicht eine Subklasse davon.
Wenn dem aber so ist, dann verliere ich ja informationen, zum Beispiel
überschriebene Methoden. Ich würde eher eine Art Adapter oder Proxy
verwenden. Wenn überhaupt einen Copy constructor, dann ja wohl mit B(B),
nicht mit A. Und dann würde ich persönlich noch eine Exception
schmeissen wenn this.getClass() != b.getClass().

In C++ macht das in Kombination mit der Zuweisung vielleicht mehr Sinn,
aber in einer Sprache in der ich nicht zwischen Pointer auf einen Wert
und den Wert direkt wählen kann?

Und zu guter letzt... mit Reflection kann ich auch den Wert für a kopieren.
Post by Thomas Thiele
3. Aufruf einer Funktion einer höheren Basisklasse nicht möglich
---------------------------------------------------------------------------------------------
Kein super.super.function(); möglich. Das ist Mist.
class A(){
void function1(){ /* ....*/};
void function2(){ /* ....*/};
}
class B extends A(){
void function2(){
/* ...was B-spezifisches... */
super.function2(); //die benötigte A funktionalität
};
void function3(){/*....*/}
}
class C extends B(){
void function2(){
/* ...was C-spezifisches... */
//super.function2(); //nein!!!!, ich will nix B-spezifisches!!!!
super.super.function2(); //aber das geht nicht
}
};
es mag ja sein, dass dies nicht geht, aber in welchen Fällen braucht man
das überhaupt? Normalerweise kann man durch eine Änderung des Design dem
entgegen wirken. Den normalerweise hatte man dann Klassen die schlecht
strukturiert sind. Oder hast du einen konkreten, realistischen Fall wo
man sowas wirklich braucht?

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Thomas Thiele
2007-07-20 20:49:25 UTC
Permalink
Post by Jochen Theodorou
Ressourcen kann man auch schliessen ohne einen Destruktor zu benutzen.
Das Problem ist ja nicht so sehr das explizite Zerstören, sondern dass
das auch gemacht werden muss, wenn niemand den Destruktor im Code
aufruft.
Aufrufen _kann_.
Post by Jochen Theodorou
Übrigens werden in Java Objekte meist auch sofort collected,
wenn du sie in einer Methode angelegt hast und nach verlassen der
Methoden nicht mehr referenzierst.
Meist...
Post by Jochen Theodorou
Garantiert denn C++ dass der Destruktor aller Objekte
aufgerufen wird, wenn die Anwendung abstürzt?
Bei ordentlichem Design: ja.
Aber das erfordert wirklich ordentliches Design insbsondere bei
Exeptionhandling.
Post by Jochen Theodorou
Ich finde überhaupt mit finalize angefangen zu haben war ein Fehler.
Aber man wollte wohl die C++-Leute nicht so extrem vergraulen.. wegen
denen hat man ja auch primitives eingeführt.
Stimme ich dir zu. Java hätte weniger Rücksicht auf C++ nehmen sollen.
Die Ähnlichkeit ist in keine Weise gut.
Post by Jochen Theodorou
Zitat: "die es unmöglich machen etwas bestimmtes zu programmieren."
also meinst du ja was anderes ;)
Nä. Ich will ganz einfach eine Funktion aus der Ur-Basis aufrufen.
Das geht nur solange sie in der Basis nicht redifiniert wird.
Ein expliziter Aufruf via Scope-Operator ist nicht möglich.
Post by Jochen Theodorou
Ausserdem wer
sagt denn das in a ein A gespeichert ist und nicht eine Subklasse davon.
Der Debugger.
Post by Jochen Theodorou
Ich würde eher eine Art Adapter oder Proxy
verwenden.
Ähnliche Antworten ala "das Design ist schlecht" kamen auch von anderen
hier. Leider übersehen diese das Entscheidende: das Design stammt nicht
von mir. Ich muss es benutzen! Aus Fremdbibliotheken! Aus anderen
projekten die historisch so gewachsen sind.
Das ideale Design ist graue Theorie. In der Theorie habt ihr recht.
Post by Jochen Theodorou
Und zu guter letzt... mit Reflection kann ich auch den Wert für a kopieren.
Nein, kann ich nicht (immer).
Wann genau nicht müsste ich dir raussuchen. Weiss ich nicht mehr.
Post by Jochen Theodorou
es mag ja sein, dass dies nicht geht, aber in welchen Fällen braucht man
das überhaupt? Normalerweise kann man durch eine Änderung des Design dem
entgegen wirken. Den normalerweise hatte man dann Klassen die schlecht
strukturiert sind. Oder hast du einen konkreten, realistischen Fall wo
man sowas wirklich braucht?
Der konkrete Fall, war eine (nicht von mir) so "schlecht strukturierte"
Klasse. Aber ich hätte es höchstwahrscheinlich selber so gemacht, denn
das was ich machen wollte war so nie vorgesehen. Ein Redesign kam schon
aus Zeitgründen nicht in Frage.
Bernd Eckenfels
2007-07-20 20:52:32 UTC
Permalink
Post by Thomas Thiele
Post by Jochen Theodorou
Ressourcen kann man auch schliessen ohne einen Destruktor zu benutzen.
Das Problem ist ja nicht so sehr das explizite Zerstören, sondern dass
das auch gemacht werden muss, wenn niemand den Destruktor im Code
aufruft.
Aufrufen _kann_.
Entweder der Aufrufer ruft den Destruktor auf wenn er so weit ist (und das
geht auch in Java, siehe dispose() und close()) oder man überlässt es dem GC
es irgendwann zu tun. Welchen anderen Ansatz vermisst du und welche Sprache
hat diesen?

(und ich hab schon Funktionale Interpreter mit einem konventionellen GC
gesehen)
Post by Thomas Thiele
Die Ähnlichkeit ist in keine Weise gut.
Ja, die Generics sind haesslich und unnötig.

Gruss
Bernd
Thomas Thiele
2007-07-20 21:06:58 UTC
Permalink
Post by Bernd Eckenfels
Welchen anderen Ansatz vermisst du und welche Sprache
hat diesen?
Sofortige Zerstörung des Objects bei Verlassen des Scopes.
-> Python

Bei Exceptions müssen Ressourcen explizit freigegeben werden.

Was gerne passiert ist z.B. dass Connections aus einem
Connection-Pool nicht schnell genug freigegeben werden.
Jochen Theodorou
2007-07-20 21:53:11 UTC
Permalink
Post by Thomas Thiele
Post by Bernd Eckenfels
Welchen anderen Ansatz vermisst du und welche Sprache
hat diesen?
Sofortige Zerstörung des Objects bei Verlassen des Scopes.
-> Python
Bei Exceptions müssen Ressourcen explizit freigegeben werden.
Was gerne passiert ist z.B. dass Connections aus einem
Connection-Pool nicht schnell genug freigegeben werden.
mischt du da nicht 2 Dinge? Im Connection-Pool hast du keine Methode die
du verlassen würdest um den GC automatisch anzuweisen die Objekte
aufzuräumen. Mach doch nicht aus langlebigen und kurzlebigen Objekte
einfach eins. Denn wenn wir nur Objekte aufräumen müssten, wenn eine
Methode verlassen wird, dann bräuchte man gar keinen GC wie er bei Java
zur Anwendung kommt.

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
kilian heckrodt
2007-07-22 01:26:11 UTC
Permalink
Post by Bernd Eckenfels
Ja, die Generics sind haesslich und unnötig.
Gruss
Bernd
Wieso das?
Wanja Gayk
2007-07-22 11:30:33 UTC
Permalink
Bernd Eckenfels said...
Post by Bernd Eckenfels
Ja, die Generics sind haesslich und unnötig.
Hässlich vielleicht, aber mir haben mir das eine oder andere mal den
Arsch gerettet - besonders beim Debuggen/Refactorn von altem Code mit
komplexen Datenstrukturen: da klatscht man erstmal Generics dran, um
besser zu sehen, was wohin gehört (ggf. fällt dort dann schon der erste
Fehler auf) und dann baut man das so um, dass man es vorzeigen kann.
Und den einen oder anderen Flüchtigkeitsfehler haben sie mir auch schon
erspart.

Gruß,
-Wanja-
--
Ada Byron, die Lochkarten für Babbages "Difference Engine" vorbereitete,
gilt als die erste Programmiererin der Weltgeschichte. Sie hat auch das
Verhaltensmuster für alle nachfolgenden Programmierer vorgegeben: Sie
trank und schluckte Drogen.
Jochen Theodorou
2007-07-20 22:03:39 UTC
Permalink
Post by Thomas Thiele
Post by Jochen Theodorou
Ressourcen kann man auch schliessen ohne einen Destruktor zu benutzen.
Das Problem ist ja nicht so sehr das explizite Zerstören, sondern dass
das auch gemacht werden muss, wenn niemand den Destruktor im Code
aufruft.
Aufrufen _kann_.
ja weiter?
Post by Thomas Thiele
Post by Jochen Theodorou
Übrigens werden in Java Objekte meist auch sofort collected, wenn du
sie in einer Methode angelegt hast und nach verlassen der Methoden
nicht mehr referenzierst.
Meist...
kommt auf den GC an eben.
Post by Thomas Thiele
Post by Jochen Theodorou
Garantiert denn C++ dass der Destruktor aller Objekte aufgerufen wird,
wenn die Anwendung abstürzt?
Bei ordentlichem Design: ja.
Aber das erfordert wirklich ordentliches Design insbsondere bei
Exeptionhandling.
kommt ja scheinbar selten vor. Ausserdem klingt das danach dass ich es
ja dann eh wieder von Hand machen muss, womit sich für mich der
Unterschied zu Java nicht erschliesst.

[...]
Post by Thomas Thiele
Post by Jochen Theodorou
Ausserdem wer sagt denn das in a ein A gespeichert ist und nicht eine
Subklasse davon.
Der Debugger.
der war gut ;) Fröhliches schreiben von Bibliothken wünsche ich dann.
Post by Thomas Thiele
Post by Jochen Theodorou
Ich würde eher eine Art Adapter oder Proxy verwenden.
Ähnliche Antworten ala "das Design ist schlecht" kamen auch von anderen
hier. Leider übersehen diese das Entscheidende: das Design stammt nicht
von mir. Ich muss es benutzen! Aus Fremdbibliotheken! Aus anderen
projekten die historisch so gewachsen sind.
Das ideale Design ist graue Theorie. In der Theorie habt ihr recht.
Mag schon sein, aber in C++ bekommst du exact das gleiche Problem wenn
jemand das automatische Anlegen des Copy-Konstruktor verhindert hat und
mit dem Ersatz Schindluder treibt.
Post by Thomas Thiele
Post by Jochen Theodorou
Und zu guter letzt... mit Reflection kann ich auch den Wert für a kopieren.
Nein, kann ich nicht (immer).
Wann genau nicht müsste ich dir raussuchen. Weiss ich nicht mehr.
Schau nur ruhig nach, aber es geht, man muss nur den Zugriff auf private
explizit Freigeben, was ein Securitymanager verhindern kann. Ohne den
kann ich auch zum Beispiel Strings ändern. (man schreibt in das private
char[] Feld).

Mag ja sein dass in C++ ein paar mehr Dinge ganz automatisch gehen, für
die man in Java explizit etwas tun muss, andererseits gehört das auch
zur Philosohie von Java

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Sascha Bohnenkamp
2007-07-20 14:27:50 UTC
Permalink
Im mathematischen Sinne ist Java vollständig, also kannst Du jedes
berechenbare Problem damit lösen.

Wenn Du Sachen meinst, die an Java nicht "gefallen" .. davon gibt es
bestimmt vieles .. wie bei jeder anderen Sprache auch.

(z.B. Plattformunabhängig aber ggf. VM- bzw. VM-Versionsabhängig,
wesewegen man häufig diverse VMs installiert haben muss etc.pp.)
Thomas Thiele
2007-07-20 21:02:08 UTC
Permalink
Post by Sascha Bohnenkamp
Im mathematischen Sinne ist Java vollständig, also kannst Du jedes
berechenbare Problem damit lösen.
Das ist eine andere Frage.
Die Frage ist kann schon gelöste Probleme (anderen Code) so anwenden,
wie ich es brauche?
Post by Sascha Bohnenkamp
Wenn Du Sachen meinst, die an Java nicht "gefallen" .. davon gibt es
bestimmt vieles ..
Dann erzähl mal. Lass uns ein bisschen Java-Bashing betreiben...;-)
Jochen Theodorou
2007-07-20 22:17:54 UTC
Permalink
Post by Thomas Thiele
Post by Sascha Bohnenkamp
Im mathematischen Sinne ist Java vollständig, also kannst Du jedes
berechenbare Problem damit lösen.
Das ist eine andere Frage.
Die Frage ist kann schon gelöste Probleme (anderen Code) so anwenden,
wie ich es brauche?
da sage ich ganz klar: kommt darauf an ;)

Ich meine erwartest du wirklich das ein Lisp-Programm ohne grössere
Änderungen in Java funktioniert?

Es sind verschiedene Sprachen mit unterschiedlichen Konzepten. Oder wie
ist "wie ich es brauche" zu verstehen?
Post by Thomas Thiele
Post by Sascha Bohnenkamp
Wenn Du Sachen meinst, die an Java nicht "gefallen" .. davon gibt es
bestimmt vieles ..
Dann erzähl mal. Lass uns ein bisschen Java-Bashing betreiben...;-)
du meinst so Sachen wie das man das Gefühl hat man wird wie eine Art
Kleinkind behandelt? oder das man ohne IDE kaum arbeiten kann? In einem
anderen Teil hast du dich darüber beschwert das so viele Java
programmieren, die keine Ahnung haben. Ist ja auch kein Wunder, das ist
schliesslich Teil der Philosophie...

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Thomas Thiele
2007-07-20 23:20:00 UTC
Permalink
Post by Jochen Theodorou
du meinst so Sachen wie das man das Gefühl hat man wird wie eine Art
Kleinkind behandelt?
Ja. Genau.
Post by Jochen Theodorou
oder das man ohne IDE kaum arbeiten kann?
Stimmt nicht!
Ich hab schon ein J2EE-Projekt mit Ultra-Edit gemacht.
Allerdings nur change requests gemacht und bugfixing.

IDE-Schwein...und vielleicht auch noch Syntakhighlighting...Weichei ;-)
Post by Jochen Theodorou
anderen Teil hast du dich darüber beschwert das so viele Java
programmieren, die keine Ahnung haben. Ist ja auch kein Wunder, das ist
schliesslich Teil der Philosophie...
Was ich für ein Problem halte. Generell aber auf Management-Ebene.
Ich möchte niemanden einen Vorwurf machen, der als Quereinsteiger
subobtimal programmiert. War ich ja selber mal.
Aber wenn "oben" indirekt die Einstellung herrscht, dass man lieber
von C++ die Finger lässt, weil wir nur wenige C++ Programmierer sind.
Aber dass man jeden Depp an Java lässt, herrscht mir hier eine leichte
Schieflage vor. Was auch Java nicht gut tut.
Wie gesagt, schlecht ist die Sprache nicht. Sie ist mit einer der
besseren. Nur neben Python und C++ sehe ich nicht so viel Bedarf
für eine Sprache wie Java. Wenn dann schon eine ganz andere Sprache.
Mit völlig anderem Konzept. So ist es mehr ein kastriertes C++ mit VM.
Jochen Theodorou
2007-07-21 01:20:16 UTC
Permalink
Post by Thomas Thiele
Post by Jochen Theodorou
du meinst so Sachen wie das man das Gefühl hat man wird wie eine Art
Kleinkind behandelt?
Ja. Genau.
Post by Jochen Theodorou
oder das man ohne IDE kaum arbeiten kann?
Stimmt nicht!
Ich hab schon ein J2EE-Projekt mit Ultra-Edit gemacht.
Allerdings nur change requests gemacht und bugfixing.
IDE-Schwein...und vielleicht auch noch Syntakhighlighting...Weichei ;-)
wenn die Sprache was taugt brauch' ich das nicht ;) Zum Beispiel sind
mit Groovy die Programme in der Regel kürzer, womit man automatisch
weniger die IDE brauchen würde
Post by Thomas Thiele
Post by Jochen Theodorou
anderen Teil hast du dich darüber beschwert das so viele Java
programmieren, die keine Ahnung haben. Ist ja auch kein Wunder, das
ist schliesslich Teil der Philosophie...
Was ich für ein Problem halte. Generell aber auf Management-Ebene.
Ich möchte niemanden einen Vorwurf machen, der als Quereinsteiger
subobtimal programmiert. War ich ja selber mal.
Aber wenn "oben" indirekt die Einstellung herrscht, dass man lieber
von C++ die Finger lässt, weil wir nur wenige C++ Programmierer sind.
ist doch verständlich.
Post by Thomas Thiele
Aber dass man jeden Depp an Java lässt, herrscht mir hier eine leichte
Schieflage vor. Was auch Java nicht gut tut.
Das liegt meiner Meinung nach an der Verbreitung der Sprache und das
wiederum hängt mit der Erlernbarkeit und Wartbarkeit der Sprache
zusammen. Und da sehe ich nunmal Java überlegen.
Post by Thomas Thiele
Wie gesagt, schlecht ist die Sprache nicht. Sie ist mit einer der
besseren. Nur neben Python und C++ sehe ich nicht so viel Bedarf
für eine Sprache wie Java. Wenn dann schon eine ganz andere Sprache.
Mit völlig anderem Konzept. So ist es mehr ein kastriertes C++ mit VM.
Python tut sich schwer wegen seiner Formatierung. So blöd das klingt,
das ist ein Grund. Und C++ leistet nicht was Java leistet wenn es darum
geht unabhängig von der Plattform zu sein, einfach zu compilieren und zu
linken. Auch wenn man nur auf Windows arbeitet, so spielt die
Unabhägigkeit von der Plattform doch eine Rolle. Und für andere
Anwendungen dürfte die Schwierigkeit mittels eines Bufferoverflows einen
Schädling zu bekommen ein Grund gewesen sein. Von daher sehe ich in Java
kein kastriertes C++, es ist was eigenes, mit eigenem Ökosystem.

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Thomas Thiele
2007-07-21 15:17:33 UTC
Permalink
Post by Jochen Theodorou
Python tut sich schwer wegen seiner Formatierung. So blöd das klingt,
das ist ein Grund.
Einen den ich zwar sehr oft höre, aber nicht nachvollziehen kann.
Denn oft sind genau diejenigen die die Formatierungspflicht bei
Python bemänglen die, die auf exakte Einhaltung eines Styleguides
mit definierter Anzahl von Lehrzeichen als Einrückung und richtiger
Klassersetzung bestehen.
Post by Jochen Theodorou
Von daher sehe ich in Java
kein kastriertes C++, es ist was eigenes, mit eigenem Ökosystem.
Vielleicht ist es wirklich ein psychologisches Problem. Und genau
die Ähnlichkeit mit c++ führt zu diesen Diskussionen.
Jochen Theodorou
2007-07-22 01:04:04 UTC
Permalink
Post by Thomas Thiele
Post by Jochen Theodorou
Python tut sich schwer wegen seiner Formatierung. So blöd das klingt,
das ist ein Grund.
Einen den ich zwar sehr oft höre, aber nicht nachvollziehen kann.
Denn oft sind genau diejenigen die die Formatierungspflicht bei
Python bemänglen die, die auf exakte Einhaltung eines Styleguides
mit definierter Anzahl von Lehrzeichen als Einrückung und richtiger
Klassersetzung bestehen.
das ist eine rein psychologische Sache. Es bedarf da keines logischen
Grundes... vielen gefällt das "Schriftbild" einfach nicht.
Post by Thomas Thiele
Post by Jochen Theodorou
Von daher sehe ich in Java kein kastriertes C++, es ist was eigenes,
mit eigenem Ökosystem.
Vielleicht ist es wirklich ein psychologisches Problem. Und genau
die Ähnlichkeit mit c++ führt zu diesen Diskussionen.
Also ich sehe das nicht so eng... Da arbeitet man einmal mit Common
Lisp, das andere mal mit Scheme. Verschiedene Sprachen, aber extrem
ähnlich. Dann arbeitet man mit C oder C++... Zu sagen die würden sich
syntaktisch fundamental unterschieden wäre auch gewagt. Oder nimm von
mir aus die ganzen Pascal Dialekte.. die sehen alle irgendwie gleich
aus. Die Pascal- und die C-Art sind die bekanntesten, und eine Sprache,
die nicht in dieses Schema passt wird halt kritisch begutachtet... so
wie zum Beispiel Python. Ich wette, würde man Python geschweifte
Klammern für die Blöcke verschreiben würde die Akzeptanz immens steigen.


Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Thomas Thiele
2007-07-22 12:14:59 UTC
Permalink
Post by Jochen Theodorou
das ist eine rein psychologische Sache. Es bedarf da keines logischen
Grundes... vielen gefällt das "Schriftbild" einfach nicht.
Ok, ich gebe zu ich liebe Python. Meine Lieblingssprache, solange es
nicht auf Performance ankommt und ich sie nehmen kann.
Post by Jochen Theodorou
Also ich sehe das nicht so eng... Da arbeitet man einmal mit Common
Lisp, das andere mal mit Scheme. Verschiedene Sprachen, aber extrem
ähnlich. Dann arbeitet man mit C oder C++... Zu sagen die würden sich
syntaktisch fundamental unterschieden wäre auch gewagt.
Aber mit c und C++ gabs doch ähnliche Probleme!
Viele ältere C-Programmierer programmieren halt eigentlich C statt C++.
Da gibt's einen Haufen Bibliotheken wo das so ist...
Oder C Programmierer programmieren statt in Ansi-C in K&R-C. *schüttel*
_Das_ sieht erst aus...;-)
Jochen Theodorou
2007-07-22 14:09:05 UTC
Permalink
Thomas Thiele schrieb:
[...]
Post by Thomas Thiele
Post by Jochen Theodorou
Also ich sehe das nicht so eng... Da arbeitet man einmal mit Common
Lisp, das andere mal mit Scheme. Verschiedene Sprachen, aber extrem
ähnlich. Dann arbeitet man mit C oder C++... Zu sagen die würden sich
syntaktisch fundamental unterschieden wäre auch gewagt.
Aber mit c und C++ gabs doch ähnliche Probleme!
in der Ähnlichkeit der Syntax sehe ich kein Problem.
Post by Thomas Thiele
Viele ältere C-Programmierer programmieren halt eigentlich C statt C++.
Da gibt's einen Haufen Bibliotheken wo das so ist...
Das ist schon eher ein Problem... besonders wenn dann tricks angewandt
werden die in der einer Sprache zur Sprache gehören in der anderen aber
emuliert werden müssen... Oder wie war nochmal der Spruch mit Lisp
stecke in allem drin? ;)

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Stefan Matthias Aust
2007-07-22 10:02:28 UTC
Permalink
Post by Thomas Thiele
Post by Jochen Theodorou
Python tut sich schwer wegen seiner Formatierung. So blöd das klingt,
das ist ein Grund.
Einen den ich zwar sehr oft höre, aber nicht nachvollziehen kann.
Da muss ich Jochen ebenfalls widersprechen. Strukturierung durch
Einrückung (wie übrigens auch bei Haskell oder Occam) gefällt mir
ausgesprochen gut. Ich wünschte nur, ich würde meinen gvim besser
beherrschen und könnte leichte Blöcke ein- und ausrücken. Schließende
Klammern oder "end"-Schlüsselworte sind syntaktischer Ballast und es tut
gut, ihn nicht zu haben. Das kann denke ich auch ein Lisp-Entwickler
bestätigen.

Hier ist die Summenbildung über eine Collection in Java:

int sum(Collection<Integer> collection) {
int sum = 0;
for (Integer i : collection) {
sum += i;
}
return sum;
}

Und in Python:

def sum(seq):
sum = 0
for i in seq: sum += i
return sum

4 statt 7 Zeilen. Man würde es wahrscheinlich eher als

def sum(seq):
return reduce(int.__add__, seq)

schreiben (also 2 Zeilen), doch das wäre unfair.
Post by Thomas Thiele
Denn oft sind genau diejenigen die die Formatierungspflicht bei
Python bemänglen die, die auf exakte Einhaltung eines Styleguides
mit definierter Anzahl von Lehrzeichen als Einrückung und richtiger
Klassersetzung bestehen.
Was ich im Übrigens auch für wichtig halte.
--
Stefan Matthias Aust
Jochen Theodorou
2007-07-22 12:11:49 UTC
Permalink
Post by Stefan Matthias Aust
Post by Thomas Thiele
Post by Jochen Theodorou
Python tut sich schwer wegen seiner Formatierung. So blöd das klingt,
das ist ein Grund.
Einen den ich zwar sehr oft höre, aber nicht nachvollziehen kann.
Da muss ich Jochen ebenfalls widersprechen. Strukturierung durch
Einrückung (wie übrigens auch bei Haskell oder Occam) gefällt mir
ausgesprochen gut. Ich wünschte nur, ich würde meinen gvim besser
beherrschen und könnte leichte Blöcke ein- und ausrücken. Schließende
Klammern oder "end"-Schlüsselworte sind syntaktischer Ballast und es tut
gut, ihn nicht zu haben.
also erstmal habe ich gesagt dass das ein psychologischerFaktor ist, der
asu dem Schriftbild entsteht und halt dem einem gefällt während der
andere es als kryptisch empfindet. Natürlich macht das die
Funktionsweise nicht schlechter deswegen! Wobei ich sagen muss, wenn ich
an Tabs vs. Leerzeichen denke wird das eventuell schon unschön. Wie
verhält sich da Python?
Post by Stefan Matthias Aust
Das kann denke ich auch ein Lisp-Entwickler bestätigen.
Lisp ist extrem, weil einfach alles in runden Klammern hängt.
Post by Stefan Matthias Aust
int sum(Collection<Integer> collection) {
int sum = 0;
for (Integer i : collection) {
sum += i;
}
return sum;
}
sum = 0
for i in seq: sum += i
return sum
4 statt 7 Zeilen.
int sum(Collection<Integer> collection) {
int sum = 0;
for (Integer i : collection) sum += i;
return sum;}
Man kann also auch in Java so programmieren wenn man will, aber ich will
das ehrlich gesagt nicht.

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Thomas Thiele
2007-07-22 12:24:59 UTC
Permalink
Wie verhält sich da Python?
Unschön! Das muss man zugeben. Aber praktisch ist es kein Problem, wenn
man konsequent nur mit Tabs oder nur mit Leerzeichen arbeitet. Fast
Jeder Editor kann das ja.

1 Tab entspricht 8 Leerzeichen

Was dann konfus wird, wenn man Tabweite von Beispielsweise 2 hat.

def function(self):
anweisung1 #mit tab
anweisung2 #mit leerzeichen

gibt keinen Syntax error, aber das hier:

def function(self):
anweisung1 #mit tab
anweisung2 #mit leerzeichen
Martin Kaffanke
2007-07-22 12:41:08 UTC
Permalink
Post by Thomas Thiele
Wie verhält sich da Python?
Unschön! Das muss man zugeben. Aber praktisch ist es kein Problem, wenn
man konsequent nur mit Tabs oder nur mit Leerzeichen arbeitet. Fast
Jeder Editor kann das ja.
1 Tab entspricht 8 Leerzeichen
Lässt sich das dort nicht irgendwie einstellen ähnlich wie der charset am
beginn der Datei?

# -*- coding: utf-8 -*-

vielleicht gibts ja auch sowas für die 1 tab = x leerzeichen?

lg,
Martin
Raffael Herzog
2007-07-22 13:43:25 UTC
Permalink
Post by Martin Kaffanke
Post by Thomas Thiele
1 Tab entspricht 8 Leerzeichen
Lässt sich das dort nicht irgendwie einstellen ähnlich wie der charset
am beginn der Datei?
Man kann es dem Interpreter übergeben. Das ist aber auch unschön, man
sollte ganz einfach nur mit Leerzeichen arbeiten, dann hat man das
Problem nicht. Das gilt auch für andere Sprachen, für Python aber ganz
speziell, weil die Einrückung hier Teil der Syntax ist.

Gruss,
Raffi
--
Come to think of it, there are already a million monkeys on a million
typewriters, and Usenet is *nothing* like Shakespeare!

***@raffael.ch · PGP Key 5D1FF5F4 · http://www.raffael.ch/
Martin Kaffanke
2007-07-22 12:38:01 UTC
Permalink
Post by Jochen Theodorou
also erstmal habe ich gesagt dass das ein psychologischerFaktor ist, der
asu dem Schriftbild entsteht und halt dem einem gefällt während der
andere es als kryptisch empfindet. Natürlich macht das die
Funktionsweise nicht schlechter deswegen! Wobei ich sagen muss, wenn ich
an Tabs vs. Leerzeichen denke wird das eventuell schon unschön. Wie
verhält sich da Python?
Mag das auch nicht, aber dafür gibts ja editoren. Üblicherweise rücke ich
aber alle Quelltexte (auch bei Java) ein, um die Lesbarkeit zu erhöhen.
Das das bei Python alles ist, aber bei Java halt zusätzlich gemacht werden
muss, sofern man einen Editor hat, der das ohnehin nicht von haus aus
macht, macht python einfacher.
Post by Jochen Theodorou
Man kann also auch in Java so programmieren wenn man will, aber ich will
das ehrlich gesagt nicht.
Die Zeilenanzahl ists ja nicht, ich hätte auch in python hier 'sum += i' in
eine eigene Zeile geschrieben.

Finde aber die Lesbarkeit von Python einfacher, weils irgendwie meiner
persönlichen Intuition besser entspricht und ich bei Java oft ewig brauche
bis ich die Konstrukte hingebracht habe.

Bsp. Ich habe eine Liste von Objekten, die alle eine ID haben und möchte
nun ein Dictionary (wie heißt das eigentlich in Java), zum schnelleren
auffinden der Objekte:

# Konstruieren:
class A:
def __init__(self, id):
self.id = id
olist = [A(1), A(2), A(3), A(4)]

# Ok, und jetzt mein Problem, das ich in Java nicht so einfach
# hingekriegt habe:

odict = dict( [(i.id, i) for i in olist] )

Wie würde man das in Java schreiben?

Danke,
Martin
Jochen Theodorou
2007-07-22 13:46:50 UTC
Permalink
Martin Kaffanke schrieb:
[...]
Post by Martin Kaffanke
Finde aber die Lesbarkeit von Python einfacher, weils irgendwie meiner
persönlichen Intuition besser entspricht und ich bei Java oft ewig brauche
bis ich die Konstrukte hingebracht habe.
nun, ich bin mit Pascal groß geworden, deswegen habe ich gerne Marker
zumindest für das Ende eines Blocks... und das einzige wo ich sowas
nicht hatte war GWBasic oder Assembler... nicht unbedingt die besten
Paten für Python finde ich. Aber wie gesagt, das hat mit Logik wenig zu tun.
Post by Martin Kaffanke
Bsp. Ich habe eine Liste von Objekten, die alle eine ID haben und möchte
nun ein Dictionary (wie heißt das eigentlich in Java), zum schnelleren
self.id = id
olist = [A(1), A(2), A(3), A(4)]
# Ok, und jetzt mein Problem, das ich in Java nicht so einfach
odict = dict( [(i.id, i) for i in olist] )
Wie würde man das in Java schreiben?
dazu müsste ich erstmal wissen was das ist ;) Es wird wohl eine Liste
von Paaren erzeugen, aber was dict macht weiss ich nicht. Vorallem nicht
warum ich dazu die Klasse A brauche. Ansonsten würde ich sagen dass eine
Map das leistet.

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Martin Kaffanke
2007-07-22 14:39:29 UTC
Permalink
Post by Jochen Theodorou
[...]
Post by Martin Kaffanke
Finde aber die Lesbarkeit von Python einfacher, weils irgendwie meiner
persönlichen Intuition besser entspricht und ich bei Java oft ewig brauche
bis ich die Konstrukte hingebracht habe.
nun, ich bin mit Pascal groß geworden, deswegen habe ich gerne Marker
zumindest für das Ende eines Blocks... und das einzige wo ich sowas
nicht hatte war GWBasic oder Assembler... nicht unbedingt die besten
Paten für Python finde ich. Aber wie gesagt, das hat mit Logik wenig zu tun.
Post by Martin Kaffanke
Bsp. Ich habe eine Liste von Objekten, die alle eine ID haben und möchte
nun ein Dictionary (wie heißt das eigentlich in Java), zum schnelleren
self.id = id
olist = [A(1), A(2), A(3), A(4)]
# Ok, und jetzt mein Problem, das ich in Java nicht so einfach
odict = dict( [(i.id, i) for i in olist] )
Wie würde man das in Java schreiben?
dazu müsste ich erstmal wissen was das ist ;) Es wird wohl eine Liste
von Paaren erzeugen, aber was dict macht weiss ich nicht.
Schaut das so kompliziert aus?

Also ich kann später einfach über

odict[id] auf das jeweilige Item zugreifen, dies gibt mir sozusagen einen
Index, (wobei hier ziffern aus dem integer Raum kommen, die eigentlich
keine Bedeutung haben, außer das Objekt eindeutig zu identifizieren).
Post by Jochen Theodorou
Vorallem nicht
warum ich dazu die Klasse A brauche.
Die Brauche ich nicht, die habe ich und ist hier nur minimal
wiedergegeben, natürlich macht die um einiges mehr...
Post by Jochen Theodorou
Ansonsten würde ich sagen dass eine
Map das leistet.
Werde ich mir mal ansehen.

Bisher habe ich in Java nur die Liste als ArrayList. Nun, hier suche ich
meist direkt in einer Schleife das Passende Objekt raus:

private Object find_object(int gesucht) {
for (int i; i < olist.size() ; i++) {
if (olist.get(i).id == gesucht)
return olist.get(i);
}
}

in python halt

odict[gesucht]

Also ganz ohne eigene methode, dafür die liste davor mit

odict = dict( [(i.id, i) for i in olist] )

umgewandelt.

lg,
Martin
Bernd Eckenfels
2007-07-22 15:05:59 UTC
Permalink
Post by Martin Kaffanke
Bisher habe ich in Java nur die Liste als ArrayList. Nun, hier suche ich
Wenn man auf diese - sagen wir mal unerfahrene - Art und Weise an eine
Sprache herangeht, dann kommen halt keine guten Ergebnisse raus. Das liegt
dann aber weniger an der Sprache (es sei denn die Sprache ist so kompliziert
dass man sie nur als Guru überhaupt benutzen will :)
Post by Martin Kaffanke
in python halt odict[gesucht]
Das hat nun wirklich nichts mit Python Vorteilen zu tun.

Gruss
Bernd
Jochen Theodorou
2007-07-22 15:32:40 UTC
Permalink
Martin Kaffanke schrieb:
[...]
Post by Martin Kaffanke
Post by Jochen Theodorou
Post by Martin Kaffanke
Wie würde man das in Java schreiben?
dazu müsste ich erstmal wissen was das ist ;) Es wird wohl eine Liste
von Paaren erzeugen, aber was dict macht weiss ich nicht.
Schaut das so kompliziert aus?
das nicht, aber die Syntax sagte mir trotzdem nicht viel, weil ich es
nicht gewohnt bin und ganz falsch lag ich ja auch nicht.
Post by Martin Kaffanke
Also ich kann später einfach über
odict[id] auf das jeweilige Item zugreifen, dies gibt mir sozusagen einen
Index, (wobei hier ziffern aus dem integer Raum kommen, die eigentlich
keine Bedeutung haben, außer das Objekt eindeutig zu identifizieren).
du übersiehst aber eventuell einen wichtigen Punkt. Du musst dienen Stil
der Sprache anpassen. Python in Java zu programmieren macht weder dich
glücklich noch Leute die das lesen sollen.

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Stefan Ram
2007-07-22 14:10:38 UTC
Permalink
Post by Martin Kaffanke
Finde aber die Lesbarkeit von Python einfacher,
Das ist, als würdest Du sagen, »Die Temperatur des Tisches ist kälter.«.
Wenn der Tisch /kälter/ ist, dann ist die Temperatur aber /kleiner/
(oder »geringer« oder »niedriger«).

Genau so ist es mit der Lesbarkeit:
Wenn Python /einfacher/ zu lesen ist, dann ist die Lesbarkeit /besser/.
Post by Martin Kaffanke
odict = dict( [(i.id, i) for i in olist] )
final java.util.Map oDict = new java.util.HashMap( oList.length );
for( final A i : oList )oDict.put( i.id, i );

Wie bestimmt man denn in Python, ob das Verzeichnis mit
Streuspeicherung oder mit Bäumen implementiert werden soll?
Martin Kaffanke
2007-07-22 14:44:10 UTC
Permalink
Post by Martin Kaffanke
odict = dict( [(i.id, i) for i in olist] )
final java.util.Map oDict = new java.util.HashMap( oList.length ); for(
final A i : oList )oDict.put( i.id, i );
Oh, hm. Aber ich denke, wenn ich mich mal eingelesen habe ist das genauso
einfach...
Wie bestimmt man denn in Python, ob das Verzeichnis mit
Streuspeicherung oder mit Bäumen implementiert werden soll?
Das bestimme ich bei 'dict' gar nicht, für Bäume verwendet man dann andere
Module. Ich bleibe in meinem Fall ja auch im Rahmen, also < sagen wir 50
bis 80 Items, in der Regel werden es < 15 sein. Wenn man größere
Datenmengen hat, dann verwende z.b. ich dict eigentlich nicht.

lg,
Martin
Jochen Theodorou
2007-07-22 15:35:16 UTC
Permalink
Post by Martin Kaffanke
Post by Martin Kaffanke
odict = dict( [(i.id, i) for i in olist] )
final java.util.Map oDict = new java.util.HashMap( oList.length ); for(
final A i : oList )oDict.put( i.id, i );
Oh, hm. Aber ich denke, wenn ich mich mal eingelesen habe ist das genauso
einfach...
sieh bitte nicht Stefan's Formatierung als ein Beispiel für das normale
Layout von Code in Java an. Stefan hat da seine eigenen Regeln, die
viele als schlecht lesbar empfinden.

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Stefan Matthias Aust
2007-07-22 15:00:36 UTC
Permalink
Post by Stefan Ram
Wie bestimmt man denn in Python, ob das Verzeichnis mit
Streuspeicherung oder mit Bäumen implementiert werden soll?
Indem man eine entsprechende Implementierung benutzt. Wer { } als
Kurzform für ein Dictionary-Konstruktor benutzt, bekommt immer eine
HashMap. Wer dict() benutzt, ebenfalls. Wer

machs_mir_mit_baeumen(a=3, b=4)

benutzt und obige Funktion entsprechend implementiert oder eine passende
Bibliotheksfunktion importiert, der hat eben eine andere Implementierung
des Map-Konzepts. Entscheidend ist, der Zugriff kann dank
Operator-Überladung von [] immer syntaktisch auf die selbe Weise gemacht
werden.
--
Stefan Matthias Aust
Stefan Matthias Aust
2007-07-22 14:46:15 UTC
Permalink
Post by Martin Kaffanke
Bsp. Ich habe eine Liste von Objekten, die alle eine ID haben und möchte
nun ein Dictionary (wie heißt das eigentlich in Java), zum schnelleren
self.id = id
olist = [A(1), A(2), A(3), A(4)]
Wenn du olist nur hast, um sie in odict zu stecken, könntest du auch

olist = (A(i) for i in xrange(1, 11))

benutzen. Auch würde ich die [] bei odict weglassen, weil das ein
unnötiges Array erzeugt. Also einfach

odict = dict((o.id, o) for o in olist)
Post by Martin Kaffanke
Wie würde man das in Java schreiben?
public class A {
public int id;
public A(int id) {
this.id = id;
}
}
List<A> olist = Arrays.asList(new A(1), new A(2), new A(3), new A(4));
/* hat aber nicht die gleiche Semantik, da olist jetzt nicht
änderbar ist. Eigentlich wäre es daher: */
List<A> olist = new ArrayList<A>(4);
olist.add(new A(1));
olist.add(new A(2));
olist.add(new A(3));
olist.add(new A(4));

Map<Integer, A> odict = new HashMap<Integer, A>(4);
for (A a : olist) {
odict.put(a.id, a);
}

@Jochen: Der Ausdruck mit dem nachgestellten for ist eine
List-Comprehension a la Haskell, die sich genauso liest wie eine
mathematische Mengenbeschreibung.

set = { x | x > 10 }
=>
set = (x for x in numbers() if x > 10)

mit

def numbers():
n = 0
while True:
yield n
n += 1

was natürlich nicht endlich ist. Man möge daher nie versuchen, obiges
set in ein Set-Objekt oder eine Liste oder Tupel zu verwandeln.
--
Stefan Matthias Aust
Stefan Matthias Aust
2007-07-22 14:56:07 UTC
Permalink
Post by Jochen Theodorou
Post by Stefan Matthias Aust
Das kann denke ich auch ein Lisp-Entwickler bestätigen.
Lisp ist extrem, weil einfach alles in runden Klammern hängt.
Nun, was ich meinte ist, dass ein Lisp-Entwickler auf die Klammern nicht
achtet. Niemals (so hoffe ich) stehen sie alleine in einer Zeile, also
der Code ist immer

(define (f n)
(if (= n 0)
1
(* (f (1- n)) n)))

und nicht

(define (f n)
(if (= n 0)
1
(* (f (1- n)) n)
)
)
--
Stefan Matthias Aust
Jochen Theodorou
2007-07-22 15:44:07 UTC
Permalink
Post by Stefan Matthias Aust
Post by Jochen Theodorou
Post by Stefan Matthias Aust
Das kann denke ich auch ein Lisp-Entwickler bestätigen.
Lisp ist extrem, weil einfach alles in runden Klammern hängt.
Nun, was ich meinte ist, dass ein Lisp-Entwickler auf die Klammern nicht
achtet. Niemals (so hoffe ich) stehen sie alleine in einer Zeile, also
der Code ist immer
(define (f n)
(if (= n 0)
1
(* (f (1- n)) n)))
und nicht
(define (f n)
(if (= n 0)
1
(* (f (1- n)) n)
)
)
ja gut, aber bei Variante 1 musst die ständig die runden Klammern
zählen. Es gibt schon einen Grund warum der Editor bei... ich glaube Dr.
Scheme immer so aufdringlich die Klammern hat blinken lassen. Die zweite
Variante finde ich lesbarer, weil ich diesen Stil eher gewohnt bin.

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Stefan Ram
2007-07-22 15:57:41 UTC
Permalink
Post by Stefan Matthias Aust
(define (f n)
(if (= n 0)
1
0123456
Post by Stefan Matthias Aust
(* (f (1- n)) n)))
die runden Klammern zählen
Ich bevorzuge eine regelmäßige Einrückung um 2 Positionen
pro Ebene der Verschachtelung von Listen:

0 2 4

( define( f n )
( if( = n 0 )
1
( *( f( 1- n )) n )))


Hier sind die beiden Zweige des »if« unter dem »if« gleich
eingerückt. Sie sind ja auch auf der gleichen Ebene.

Ich verstehe nicht die Regel, nach der der Autor der zitierten
Liste die »1« bei Position 6 schreibt und die folgende Klammer
bei Position 4, das »if« aber bei Position 3, obwohl alle drei
auf derselben Ebene liegen. Chaotischer als für drei gleich
tiefe Einträge drei verschiedene Einrückungen zu verwenden,
geht es meiner Meinung nach nicht.
Thomas Thiele
2007-07-22 12:21:24 UTC
Permalink
Post by Stefan Matthias Aust
int sum(Collection<Integer> collection) {
int sum = 0;
for (Integer i : collection) {
sum += i;
}
return sum;
}
Das Beispiel ist fast unfair. Denn diese Kontruktion gibts erst seit
Java1.5. Früher[tm] war das noch krampfiger.
Post by Stefan Matthias Aust
Post by Thomas Thiele
Denn oft sind genau diejenigen die die Formatierungspflicht bei
Python bemänglen die, die auf exakte Einhaltung eines Styleguides
mit definierter Anzahl von Lehrzeichen als Einrückung und richtiger
Klassersetzung (sollte Klammersetzung heissen) bestehen.
Was ich im Übrigens auch für wichtig halte.
Definitiv!
Jedoch prallen da oft andere Geschmäcker aufeinander.
Beispiele.

Folgendes halte _ich_ für schlechten Stil.

if (...) {

} else{

}

Besser:

if (...) {

}
else{

}

Damit else auf gleiche Einrückungsebene wie das zugehörige if.

Und

a = langerAudruck +
nochEinlangerAusdruck +
nochEinGanzLangerAusdruckzumSchluss;

ebenfalls. Besser wäre hier:

a = langerAudruck
+ nochEinlangerAusdruck
+ nochEinGanzLangerAusdruckzumSchluss;
Stefan Matthias Aust
2007-07-22 14:50:24 UTC
Permalink
Folgendes halte _ich_ für schlechten Stil. [...]
Was du für schlecht hältst, ist der von Sun empfohle Stil (sie haben es
gewagt, einen Styleguide zu schreiben, der recht weit akzeptiert ist)
und daher würde ich sagen, man gewöhnt sich an allem (sogar dem Dativ)
und wer Rom kommt, soll es wie die Römer treiben oder so ähnlich.

Bei C# muss ich mich daher auch an das IMHO abartige

if (...)
{
bla();
}

gewöhnen :)
Und
a = langerAudruck +
nochEinlangerAusdruck +
nochEinGanzLangerAusdruckzumSchluss;
a = langerAudruck
+ nochEinlangerAusdruck
+ nochEinGanzLangerAusdruckzumSchluss;
Da sage ich die erste Variante ist besser (schon allein daher, da sie
die einzige für Ruby und ich glaube auch Python mögliche ist) weil man
eben sieht, dass die Zeile noch weitergehen muss, da das zweite Argument
des Operators fehlt.
--
Stefan Matthias Aust
Jochen Theodorou
2007-07-22 15:38:46 UTC
Permalink
Stefan Matthias Aust schrieb:
[...]
Post by Stefan Matthias Aust
Post by Thomas Thiele
a = langerAudruck +
nochEinlangerAusdruck +
nochEinGanzLangerAusdruckzumSchluss;
a = langerAudruck
+ nochEinlangerAusdruck
+ nochEinGanzLangerAusdruckzumSchluss;
Da sage ich die erste Variante ist besser (schon allein daher, da sie
die einzige für Ruby und ich glaube auch Python mögliche ist) weil man
eben sieht, dass die Zeile noch weitergehen muss, da das zweite Argument
des Operators fehlt.
übrigens geht zweiteres auch in Groovy nicht gut.

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Thomas Thiele
2007-07-22 22:17:26 UTC
Permalink
Post by Stefan Matthias Aust
Was du für schlecht hältst, ist der von Sun empfohle Stil
Hab ich doch gesagt: die Geschmäcker gehen auseinandern.
Post by Stefan Matthias Aust
(sie haben es
gewagt, einen Styleguide zu schreiben, der recht weit akzeptiert ist)
Und ich wage ihn zu kritisieren. Nicht aus Prinzip, sondern weil es
bestimmte Gründe dafür gibt.
Post by Stefan Matthias Aust
Post by Thomas Thiele
a = langerAudruck +
nochEinlangerAusdruck +
nochEinGanzLangerAusdruckzumSchluss;
a = langerAudruck
+ nochEinlangerAusdruck
+ nochEinGanzLangerAusdruckzumSchluss;
Ich weiss das viele Leute ersteres bevorzugen, deswegn nahm ich es ja
als Beispiel.
Vorteil von 2. ist dass jede Zeile alleine eine ungültige Zeile ist.
D.h. kommentiert man den Ausdruck aus, vergisst aber die letzte Zeile,
dann wird in der oberen Variante nochEinGanzLangerAusdruckzumSchluss;
als gültiger Ausdruck trotzdem ausgewertet. Man denke vor allen
daran, dass es eine Funktion sein kann.

Ausserdem ist zweites Beispiel besser wenn man lange Zeilen schreibt.
Hier sieht man den Operator ohne Scrollen zu müssen.
(ja, ich weiss 80 Zeichen und so...aber wer druckt noch Code wirklich
aus oder arbeitet mir VT100 und vi...)
Bernd Eckenfels
2007-07-22 13:28:01 UTC
Permalink
Post by Stefan Matthias Aust
int sum(Collection<Integer> collection) {
int sum = 0;
for (Integer i : collection) {
sum += i;
}
return sum;
}
Nicht dass ich das so machen wuerde, aber es gibt einen Grund warum LoC
nicht in "Zeilen" definiert ist:

int sum(Collection<Integer> collection) {
int sum = 0;
for (Integer i : collection) { sum += i; }
return sum; }

Gruss
Bernd
Stefan Matthias Aust
2007-07-22 14:52:43 UTC
Permalink
Post by Bernd Eckenfels
Nicht dass ich das so machen wuerde, aber es gibt einen Grund warum LoC
int sum(Collection<Integer> collection) {
int sum = 0;
for (Integer i : collection) { sum += i; }
return sum; }
Das ist aber nicht der Stil, wie man Java schreibt (ich hätte das
Python-Beispiel auch in eine Zeile quetschen können) und daher nicht
gültig. Tatsächlich sieht es so aus wie Code, den Stefan Arbeitsspeicher
verbrochen haben könnte. Dort hätten wir dann aber java.util.Collection
und java.lang.Integer für maximale Unlesbarkeit gelesen :)
--
Stefan Matthias Aust
Bernd Eckenfels
2007-07-22 15:37:38 UTC
Permalink
Post by Stefan Matthias Aust
(ich hätte das
Python-Beispiel auch in eine Zeile quetschen können)
Geht das denn, kann man mehr als einen Block oder Statement in einer Python
Zeile haben?

Gruss
Bernd
Stefan Matthias Aust
2007-07-22 15:47:06 UTC
Permalink
Post by Bernd Eckenfels
Post by Stefan Matthias Aust
(ich hätte das
Python-Beispiel auch in eine Zeile quetschen können)
Geht das denn, kann man mehr als einen Block oder Statement in einer Python
Zeile haben?
Befehle lassen sich durch ";" trennen. Nach dem ":" darf ein Befehl bzw.
eine durch ";" getrennte Sequenz von Befehlen folgen.
--
Stefan Matthias Aust
Stefan Ram
2007-07-22 13:36:26 UTC
Permalink
Post by Stefan Matthias Aust
int sum(Collection<Integer> collection) {
int sum = 0;
for (Integer i : collection) {
sum += i;
}
return sum;
}
Und in Python: (...)
4 statt 7 Zeilen.
Allerdings hat die Java-Version in der von mir gepflegten
Formatierung auch nur vier Zeilen:

int sum( final Collection< java.lang.Integer >collection )
{ int sum = 0;
for( final java.lang.Integer i : collection )sum += i;
return sum; }

Und zu diesen beiden Klammern muß ich noch anmerken:

Loading Image...
Bernd Eckenfels
2007-07-22 13:43:50 UTC
Permalink
Post by Stefan Ram
Allerdings hat die Java-Version in der von mir gepflegten
Ich wollte ja eigentlich mich nicht wieder mit deiner gefplgegten
Post by Stefan Ram
for( final java.lang.Integer i : collection )sum += i;
^^

Wieso denn Leerzeichen vor den Klammern aber nicht danach?

Gruss
Bernd
Stefan Ram
2007-07-22 13:59:04 UTC
Permalink
Post by Bernd Eckenfels
Post by Stefan Ram
for( final java.lang.Integer i : collection )sum += i;
^^
Wieso denn Leerzeichen vor den Klammern aber nicht danach?
Ein Leerzeichen nach einer öffnenden Klammer wünsche ich
ohnehin, damit die Anfänge von Eintängen bei Einrückung um
zwei Zeichen untereinander ausgerichtet sind:

Ohne Leerzeichen:

v
(alpha, beta, gamma,
delta, epsilon, zeta)
^

Mit Leerzeichen:

v
( alpha, beta, gamma,
delta, epsilon, zeta )
^

Dann ist es symmetrisch, wenn ein Leerzeichen auch vor einer
schließenden Klammer steht.

In

( 2 + 3 ) * 4

ist mir aber zu viel Leerraum, weswegen ich nach einer
schließenden Klammer keinen Leerraum schreibe:

( 2 + 3 )* 4

Dies geschieht auch in Symmetrie dazu, daß ich vor einer
öffnenden Klammer keinen Leerraum einfüge:

y = sin( x );

Diese Regeln findet man auch in der folgenden Seite:

http://www.purl.org/stefan_ram/pub/c_format_en

Hier noch einmal eine Begründung einiger Teile. (Ganz am
Ende sieht man auch noch einmal, daß mein Klammerstil keine
neuen Zeilen zu Python-artiger Formatierung fügt.)

One Way to Format Parentheses

There are several different ways to format texts with braces
and parentheses. One of them is being described here.

Indentation within Braces

An indentation of just one space often is too small to be seen
clearly, because the natural width and form of characters
often varies by an amount that is not very much smaller than a
space. Therefore, the indentation should amount to at least
two positions. In order not to waste horizontal spaces, an
indentation of exactly two positions is chosen. This means,
that the left position of the next level is two larger than
the position of the directly enclosing level.

Indentation by two positions within a block

{ ++x;
++x; }
^ ^
0 2

Bad A small indentation by one position is not always visible
clearly

{++x;
++x; }

Good The indentation by two positions is visible clearly

{ ++x;
++x; }

Bad A large indentation by more than two positions wastes
horizontal space with no additional benefit

{ ++x;
++x; }

Spaces within braces

In mathematics, there are often no spaces at the inner side of
parentheses or braces in expressions, but spaces are used
indeed at the inner side of braces in set notation, when the
braces contain a description (not when they contain a list).

Spaces in set notation

{ x | x > 2 }

This style is adopted here: One space is written at the inner
side of braces.

Spaces at the inner side of parentheses within a block

{ ++x; }

This style is consistent with the indentation by two
positions, because only using this style, corresponding parts
of two lines have the same position.

Bad No space after the first brace, the two statements are
misaligned

{++x;
++x; }

Good One space after the first brace, the two statements are
properly aligned

{ ++x;
++x; }

Bad Two spaces after the first brace, the two statements are
misaligned

{ ++x;
++x; }

There are some exceptions to this rule: No spaces are used
within empty braces "{}" and between two or more closing
braces of the same direction "}}", except, when the first one
of them is part of an empty pair "{} }" (an empty pair of
braces if treated like a single non-braces character).

Unified rules for all Brackets

For simplicity and uniformity, the rules from above apply to
all kinds of brackets, including parentheses, braces (curly
brackets), square brackets, and angle brackets.

Spaces within parentheses and square brackets

{ y = f( x )+ g() + a[ 2 ]; }

Binary operators are sorrounded by a space, but the space is
omitted, when there already is a space on the other side of a
sequence of brackets directly beside the operator: By this rule,
" )+" is written instead of " ) +".

Representation of the Syntactical Structure

A method declaration in Java consists of a head and a body.
The following representation shows this structure:

Good formatting according to the structure

void alpha() // head
{ beta(); } // body

The following formatting is misleading, because the line break
does not match the structural break:

Bad line break within the body

void alpha() { // head and the beginning of the body
beta(); } // the rest of the body

This formatting also would make no sense for blocks within
blocks. So it is often not used for such blocks. Therefore
even the adopters of this style can not use it uniformly.

Left Braces Look Like "bullets"

There is a well known style to publish lists in typography
using bullets sticking out on the left, looking like this:

Common list representation with bullets in typography

o This is the first point
of this list, it is written
here just as an example.

o Here is another entry

o This is another example given
just as an example to show
an example

The braces of the beginnings of blocks stand out on the left
just the same, when the formatting being described here is
used, so they look quite naturally as beginning-of-a-block
markers, when one is used to the typographical list notation:

Left braces look like bullets to mark blocks

{ printf(); printf();
printf(); printf(); printf();
printf(); printf(); }

{ printf(); printf(); }

{ printf(); printf(); printf();
printf(); printf();
printf(); }

Neutrality

Someone wrote this C code:

Code someone wrote

while( fgets( eingabe, sizeof eingabe, stdin ))
if( sscanf( eingabe, "%d", &wert )!= 1 )
fprintf( stderr, "Please enter a number!\n" );
else
summe += wert;

It amazes me that I can add braces by my style conventions
(not changing the meaning of the code)
without the need to change the position of any character of
the given code or change the overall number of line:

The code from above plus braces

while( fgets( eingabe, sizeof eingabe, stdin ))
{ if( sscanf( eingabe, "%d", &wert )!= 1 )
{ fprintf( stderr, "Please enter a number!\n" ); }
else
{ summe += wert; }}

Insofar, my bracing style might be considered non-obtrusive.
Olaf Pohlmann
2007-07-20 15:32:00 UTC
Permalink
Post by Thomas Thiele
Was ich meine sind harte Einschränkungen die es unmöglich machen etwas
bestimmtes zu programmieren oder wirklich zu schlimmeren Fehlern
führen.
Es gibt keine Moeglichkeit zu testen, ob der Typ eines Objekts eine
Unterklasse einer gegebenen anderen Klasse ist. Das hat zur Folge, dass
eine Unterklasse die Methode equals() ihrer instaniierbaren Superklasse
"zerstoert". Hier ist ein Beispiel:


// Superklasse
public class A {

private String s;

public A(String s) {
this.s = s;
}

public String getS() { return s; }

@Override
public boolean equals(Object obj) {
if (! (obj instanceof A)) // true for subclasses
return false;
A other = (A) obj;
return s.equals(other.s);
}

@Override
public int hashCode() {
return s.length();
}
}

// Subklasse
public class B extends A {

private String c;
private int x;

public B(String s, String c, int x) {
super(s);
this.c = c;
this.x = x;
}

@Override
public boolean equals(Object obj) {
if (! (obj instanceof B))
return false;
B other = (B) obj;
return super.equals(other) && c.equals(other.c) && x == other.x;
}

@Override
public int hashCode() {
return super.hashCode() + 3 * c.length() + 7 * x;
}
}

// Test
import java.util.*;

public class Test {

public static void main(String[] args) {
A a = new A("abc");
B b = new B("abc", "abcabca", -3);

Set<A> set = new HashSet<A>();
set.add(a);
set.add(b);
System.out.println("Size of the set: " + set.size());

set.clear();
set.add(b);
set.add(a);
System.out.println("Size of the set: " + set.size());

}
}

Die Ausgabe des Tests:
Size of the set: 2
Size of the set: 1


Dieses Verhalten ergibt sich dadurch, dass HashSet vor dem Einfuegen
prueft, ob es das neu einzufuegende Objekt schon enthaelt. Die Klasse
vergleicht dazu die HashCodes, und ruft equals() genau dann auf, wenn
die HashCodes gleich sind. Die Parameter der Konstruktoren A() und B()
ergeben "zufaellig" :-) die gleichen HashCodes, also wird equals()
aufgerufen. Das Problem ist nun, dass A#equals() den Wert true
zurueckgibt, B#equals() dagegen false.

Die Moral von der Geschichte kann nur sein, dass man keine verschiedenen
instantiierbaren Typen der gleichen Vererbungshierarchie in dieselbe
Collection stecken darf. Der Grund ist die Assymetrie den Operators
"instanceof", bzw. das Fehlen eines Gegenstuecks, das in die andere
Richtung assymetrisch ist.


op
Jochen Theodorou
2007-07-20 15:56:57 UTC
Permalink
Post by Olaf Pohlmann
Post by Thomas Thiele
Was ich meine sind harte Einschränkungen die es unmöglich machen etwas
bestimmtes zu programmieren oder wirklich zu schlimmeren Fehlern
führen.
Es gibt keine Moeglichkeit zu testen, ob der Typ eines Objekts eine
Unterklasse einer gegebenen anderen Klasse ist. Das hat zur Folge, dass
eine Unterklasse die Methode equals() ihrer instaniierbaren Superklasse
// Superklasse
public class A {
[...]
Post by Olaf Pohlmann
@Override
public boolean equals(Object obj) {
if (getClass()!=A.class || obj.getClass()!=A.class)
return false;
A other = (A) obj;
return s.equals(other.s);
}
[...]

in dem Fall würde equals nur true ergeben, wenn obj ein A ist (und keine
Unterklasse) und this ein A ist (und keine Unterklasse). Natürlich macht
dann der Aufruf super.equals(other) in B absolut 0 Sinn mehr. Jedenfalls
gibt es da Class#isAssignable, das ich benutzen kann um das Verhältnis
zweier Klassen zu prüfen. Und in dem Fall auch symetrisch. Deine Aussage
"Es gibt keine Moeglichkeit zu testen, ob der Typ eines Objekts eine
Unterklasse einer gegebenen anderen Klasse ist" ist also so nicht richtig.

Gruss theo
--
Jochen "blackdrag" Theodorou
Groovy Tech Lead (http://groovy.codehaus.org)
http://blackdragsview.blogspot.com/
Bernd Eckenfels
2007-07-20 18:10:07 UTC
Permalink
Post by Olaf Pohlmann
Es gibt keine Moeglichkeit zu testen, ob der Typ eines Objekts eine
Unterklasse einer gegebenen anderen Klasse ist.
Du meinst man kann nicht prüfen ob es keine unterklasse ist? das geht mit

a.getClass()==b.getClass()

Gruss
Bernd
Bernd Eckenfels
2007-07-20 18:07:01 UTC
Permalink
Post by Thomas Thiele
D.h. durch verspätete destruierung bzw. der Unmöglichkeit einer
automatischen Destruierung entstehen Ressourcenleaks! Entgegen dem
Java-Versprechen...
Nein tun sie nicht. Und es gibt ein workaround: dispose() methoden für
expliziten destruktor.
Post by Thomas Thiele
Aber was habe ich gekonnt? Mein B Objekt was per Vererbung ein A
Object _ist_ wird niemals
die private Variable a übernehmen.
Aber es gibt ja genug Workarounds: das Object kann sich selber kopieren oder
du benutzt serialisierung. Gemaess deiner Definition ist das keine
"ernsthafte" restriktion.
Post by Thomas Thiele
Kein super.super.function(); möglich. Das ist Mist.
Ich glaube ich will deine Designs und den quellcode nicht sehen :)

Gruss
Bernd
Thomas Thiele
2007-07-20 21:00:10 UTC
Permalink
Post by Bernd Eckenfels
Post by Thomas Thiele
Aber was habe ich gekonnt? Mein B Objekt was per Vererbung ein A
Object _ist_ wird niemals
die private Variable a übernehmen.
Aber es gibt ja genug Workarounds: das Object kann sich selber kopieren
Hä? Dann habe ich wieder ein A. Ich will aber ein B.
Post by Bernd Eckenfels
du benutzt serialisierung.
Erklär mal bitte. Da stehe ich grad auf dem Schlauch.
Post by Bernd Eckenfels
Ich glaube ich will deine Designs und den quellcode nicht sehen :)
Lass es mich so ausdrücken: Die Designs und den Quellcode der solche
Fragen aufwirft, den willst du wirklich nicht sehen...;-)
Dirk Brosowski
2007-07-24 09:20:47 UTC
Permalink
Post by Thomas Thiele
Post by Bernd Eckenfels
Post by Thomas Thiele
Aber was habe ich gekonnt? Mein B Objekt was per Vererbung ein A
Object _ist_ wird niemals
die private Variable a übernehmen.
Aber es gibt ja genug Workarounds: das Object kann sich selber kopieren
Hä? Dann habe ich wieder ein A. Ich will aber ein B.
Post by Bernd Eckenfels
du benutzt serialisierung.
Erklär mal bitte. Da stehe ich grad auf dem Schlauch.
Post by Bernd Eckenfels
Ich glaube ich will deine Designs und den quellcode nicht sehen :)
Lass es mich so ausdrücken: Die Designs und den Quellcode der solche
Fragen aufwirft, den willst du wirklich nicht sehen...;-)
Aber wieso führt sowas dann zu Kritik an Java? Mh, ich würde den
Designer aus dem Fenster springen lassen, denn solche Leute sind doch
dann für exorbitant teure Projekte zuständig.

Grüße

Dirk
Andreas Eberhöfer
2007-07-20 18:16:19 UTC
Permalink
Post by Thomas Thiele
Hallo,
Was ich meine sind harte Einschränkungen die es unmöglich machen etwas
bestimmtes zu programmieren oder wirklich zu schlimmeren Fehlern
führen.
1. Zerstörung von Objekten nicht "just in time".
--------------------------------------------------------------------
Garbagecollection und die Nichtnotwenigkeit sich um Aufräumarbeiten zu
kümmern mag ein Vorteil sein. Aber die Java-Garbagecollection
garantiert eben nicht - wie bei Python beispielsweise - die sofortige
Zerstörung (bzw. wenigstens den sofotigen Aufruf eines Destruktors)
wenn das Objekt den Sichtbarkeitsbereich verlässt.
D.h. durch verspätete destruierung bzw. der Unmöglichkeit einer
automatischen Destruierung entstehen Ressourcenleaks! Entgegen dem
Java-Versprechen...
In Java muss man wissen was man tut. Ressourcen schließt man selbst. Vom
Aufwand kommt das doch auf das selbe raus, ob ich nun eine Methode
aufrufe die die Resource schließt oder den Destruktor ist doch egal.
Wenn es Python automatisch so macht ist es sicher schön, aber selbst
wenn es in Java nicht so ist, eine Einschränkung sehe ich da nicht.
Post by Thomas Thiele
2. Kein impliziter Copycontructor.
------------------------------------------------
Aus Bibliothek gibt es eine Klasse: (aufs wesentliche gekürzt)
class A{
private int a;
int getA(){return a;}
}
Also unspannend. Ein simpler Datencontainer.
Jetzt benöge ich dazu eine Erweiterung, weil ich zusätzlich Daten
class B extends A{
private int b;
int getB(){return b;}
void setB(int b){ this.b = b;}
}
Sieht auch unspektakulär aus.
Die Probleme beginnen wenn ich nur ein A Object bekomme aber ein B
Z.B.
// get A from the library function, that can only return an A
A a = libClass.createA();
// now I need the B...
B b = new B(a); //geht nicht!!!!!!!*
myClass.machwasmitB(b);
*ja, ja, syntaktisch geht das schon, ich kann einen solchen
Konstruktor schreiben.
B(A a){}
Aber was habe ich gekonnt? Mein B Objekt was per Vererbung ein A
Object _ist_ wird niemals
die private Variable a übernehmen.
Wieso nicht? Vorrausgesetzt A hat natürlich einen Konstruktor der das
int a übergeben bekommt. Aber sonst bekommst du ja in A nie nen Wert rein.

public B(int a,int b)
{
super(a);
this.b = b;
}

public B(A a,int b)
{
this(a.getA(),b);
}
Post by Thomas Thiele
3. Aufruf einer Funktion einer höheren Basisklasse nicht möglich
---------------------------------------------------------------------------------------------
Kein super.super.function(); möglich. Das ist Mist.
Findest du, ich hab das noch nie gebraucht.
Post by Thomas Thiele
class A(){
void function1(){ /* ....*/};
void function2(){ /* ....*/};
}
class B extends A(){
void function2(){
/* ...was B-spezifisches... */
super.function2(); //die benötigte A funktionalität
};
void function3(){/*....*/}
}
class C extends B(){
void function2(){
/* ...was C-spezifisches... */
//super.function2(); //nein!!!!, ich will nix B-spezifisches!!!!
super.super.function2(); //aber das geht nicht
}
};
Fällt euch noch mehr ein?
Du kannst kein Swap schreiben so wie du es von anderen Sprachen gewohnt
bist, da es kein Call by Referenz gibt.
Generics sind nicht so mächtig wie Templates in C++.
Da gibt es sicherlich ein paar Sachen. Aber programmieren kannst du
alles, Java ist ja Turingvollständig ;). Außerdem die schlimmeren Fehler
kannst du sicherlich in C++ bauen (Bufferoverflow, Memory Leaks, ...).
Was für mich eine gute Sprache ausmacht ist aber nicht der Sprachumfang
sondern die API und zusätzliche Frameworks für die Sprache. Da finde ich
Java traumhaft.

mfg
Andreas
Thomas Thiele
2007-07-20 20:57:45 UTC
Permalink
Post by Andreas Eberhöfer
In Java muss man wissen was man tut. Ressourcen schließt man selbst. Vom
Aufwand kommt das doch auf das selbe raus, ob ich nun eine Methode
aufrufe die die Resource schließt oder den Destruktor ist doch egal.
Wenn es Python automatisch so macht ist es sicher schön, aber selbst
wenn es in Java nicht so ist, eine Einschränkung sehe ich da nicht.
Du hattest noch nie Ressourcen leaks? (Datenbank connections z.B.)
Post by Andreas Eberhöfer
Post by Thomas Thiele
Aber was habe ich gekonnt? Mein B Objekt was per Vererbung ein A
Object _ist_ wird niemals
die private Variable a übernehmen.
Wieso nicht? Vorrausgesetzt A hat natürlich einen Konstruktor der das
int a übergeben bekommt.
Hat A selbstverständlich nicht, sonst wäre das Problem ja trivial.
Post by Andreas Eberhöfer
Aber sonst bekommst du ja in A nie nen Wert rein.
Man kann Werte in Klasseninstanzen durchaus auch anders setzen als
per Kontruktor und Setter-Funktionen.
Die Welt besteht nicht nur aus Bohnen...
Post by Andreas Eberhöfer
Post by Thomas Thiele
Kein super.super.function(); möglich. Das ist Mist.
Findest du, ich hab das noch nie gebraucht.
Ich schon.
Post by Andreas Eberhöfer
Du kannst kein Swap schreiben so wie du es von anderen Sprachen gewohnt
bist, da es kein Call by Referenz gibt.
Naja. Mit Containern kannst du das basteln.

Abgesehen davon: in Python geht das am allerbesten.

a, b = b, a;
Post by Andreas Eberhöfer
Generics sind nicht so mächtig wie Templates in C++.
Generics in Java suboptimal um es mal euphemistisch zu sagen.
Der Beginn von Ende der Sprache.
Post by Andreas Eberhöfer
Was für mich eine gute Sprache ausmacht ist aber nicht der Sprachumfang
sondern die API und zusätzliche Frameworks für die Sprache. Da finde ich
Java traumhaft.
Na gut, totgesagte leben länger...

In der Tat ist Java schon damit ein Selbstläufer.
Java ist ja nicht schlecht. Nur leider zu sehr gegenüber C++ gelobt und
C++ verteufelt. Ich erlebe das in Diskussionen auf Arbeit sehr häufig.
Bernd Eckenfels
2007-07-20 21:09:23 UTC
Permalink
Post by Thomas Thiele
In der Tat ist Java schon damit ein Selbstläufer.
Java ist ja nicht schlecht. Nur leider zu sehr gegenüber C++ gelobt und
C++ verteufelt. Ich erlebe das in Diskussionen auf Arbeit sehr häufig.
Ich trau mir zumindest keine solchen grossen C++ Projekte zu die ich in Java
manage. Dann doch eher .Net.

Gruss
Bernd
Thomas Thiele
2007-07-20 21:16:00 UTC
Permalink
Post by Bernd Eckenfels
Ich trau mir zumindest keine solchen grossen C++ Projekte zu die ich in Java
manage.
Also ich schon.
Da wir in der Firma aber hauptsächlich Java programmieren sind die
großen Projekte halt Java.

Nur ist der große Vorteil von Java, leichter erlernbar zu sein,
gleichzeitig der größte Nachteil: Es programmieren auch zu viele
schlechte Leute mit, die bei C++ "Segmentation fault"
schon aussortiert hätte.

In einem wirklich gut gemanagten und designten Projekt ist die
Frage der Sprache eh zweitrangig.
Bernd Eckenfels
2007-07-20 21:29:45 UTC
Permalink
Post by Thomas Thiele
Nur ist der große Vorteil von Java, leichter erlernbar zu sein,
gleichzeitig der größte Nachteil: Es programmieren auch zu viele
schlechte Leute mit, die bei C++ "Segmentation fault"
schon aussortiert hätte.
hast du denn erfahrungen mit grossen projekten?
Post by Thomas Thiele
In einem wirklich gut gemanagten und designten Projekt ist die
Frage der Sprache eh zweitrangig.
kennst du welche?

Gruss
Bernd
Thomas Thiele
2007-07-20 23:11:12 UTC
Permalink
Post by Bernd Eckenfels
hast du denn erfahrungen mit grossen projekten?
Ja. Aber alle großen Projekte wo ich selber beteiligt war, waren in Java.
C++ waren meist eher kleinere Dinge.
Post by Bernd Eckenfels
Post by Thomas Thiele
In einem wirklich gut gemanagten und designten Projekt ist die
Frage der Sprache eh zweitrangig.
kennst du welche?
gut gemanagten und designten Projekt? Nein.
Wanja Gayk
2007-07-22 11:30:33 UTC
Permalink
Thomas Thiele said...
Post by Thomas Thiele
Post by Bernd Eckenfels
hast du denn erfahrungen mit grossen projekten?
Ja. Aber alle großen Projekte wo ich selber beteiligt war, waren in Java.
C++ waren meist eher kleinere Dinge.
Das könnte einen Grund haben, der nicht für C++ spricht.. *giggle*

Gruß,
-Wanja-
--
Ada Byron, die Lochkarten für Babbages "Difference Engine" vorbereitete,
gilt als die erste Programmiererin der Weltgeschichte. Sie hat auch das
Verhaltensmuster für alle nachfolgenden Programmierer vorgegeben: Sie
trank und schluckte Drogen.
Alfred
2007-07-21 05:45:12 UTC
Permalink
Post by Thomas Thiele
In einem wirklich gut gemanagten und designten Projekt ist die
Frage der Sprache eh zweitrangig.
Genau und wenn's wirklich _gutes_ Design sein soll, dann
taucht ein "super.super.function();" gar nicht auf - Oder?

Alfred
Alfred
2007-07-21 05:43:08 UTC
Permalink
Post by Thomas Thiele
Du hattest noch nie Ressourcen leaks? (Datenbank connections z.B.)
Nur Anfänger allokieren solche Ressourcen in einem Konstruktor - oder
Leute die auch sonst Türen zwar öffnen, aber nie wieder schliessen,
weil sie in der S-Bahn geboren sind. Ressourcen allokiert man so
kurz wie möglich und behandelt diese auch explizit, wofür es in den
Interfaces ja auch passende close()-Methoden gibt.
Post by Thomas Thiele
...
Man kann Werte in Klasseninstanzen durchaus auch anders setzen als
per Kontruktor und Setter-Funktionen.
Reflection?
Post by Thomas Thiele
Die Welt besteht nicht nur aus Bohnen...
Stimmt - man kann auch Kakao trinken.
Post by Thomas Thiele
Post by Andreas Eberhöfer
Post by Thomas Thiele
Kein super.super.function(); möglich. Das ist Mist.
Findest du, ich hab das noch nie gebraucht.
Ich schon.
Dann ist dein Design einfach nur Murks - das braucht
kein Mensch.
Post by Thomas Thiele
...
In der Tat ist Java schon damit ein Selbstläufer.
Java ist ja nicht schlecht. Nur leider zu sehr gegenüber C++ gelobt und
C++ verteufelt. Ich erlebe das in Diskussionen auf Arbeit sehr häufig.
Jede Sprache hat ihre Daseinsberechtigung. Man muss nur wissen,
was man will. Und ich möchte z.B. keine WebApp mit C++ schreiben.
Allerdings die Weiterentwicklung von Java macht daraus langsam
aber sicher eine bunte Mischung aus syntaktischen Schnipseln
aller Art - irgendwann wird's unerträglich.

Alfred
Thomas Thiele
2007-07-21 15:06:20 UTC
Permalink
Post by Alfred
Post by Thomas Thiele
Kein super.super.function(); möglich. Das ist Mist.
Dann ist dein Design einfach nur Murks - das braucht
kein Mensch.
Sorry, aber das ist immer zu einfach!
Diese Aussage ist zu 90% ein Zirkelschluß derart, dass ein
Design mist sei, nur weil es _in dieser Sprache_ ungünstig ist.
Worauf ich eigentlich hinauswollte sind sprachunabhängige
Designpatterns die nur deswegen in Java "schlechtes Design"
sind, weil sie in Java nicht gehen.
Auch in anderen Sprachen fehlen mir manchmal Dinge.
In C++ fehlt mir z.B. das "final" was weiteres Überschreiben
einer Methode verbietet. Umgekehrt fehlt mir ein beiden allen
Sprachen ein Schlüsselwort ala "overwrite" was redefinition
einer Methode in einer abgeleiteten Klasse erzwingt.

public class A{
public void allgemeineMethode(){}
public void overwrite spezifischeMethode(){}
}

public class B extends A{
public void nochNeMethode(){}
}

->compile error: B must be declared abstract or redefine
spezifischeMethode()...

Ja, klar, geht auch mit Bordmittel. Aber es würde eine Klasse
sparen, was den üblichen Java-Klassen-Wald verringern würde.
Post by Alfred
Allerdings die Weiterentwicklung von Java macht daraus langsam
aber sicher eine bunte Mischung aus syntaktischen Schnipseln
aller Art - irgendwann wird's unerträglich.
Voll zustimm. Ab Java 1.5 gehts abwärts.
Es beginnt das was auch C++ geschadet hat. Eine verkomplizierung der
Sprache die mehr Nachteile als Nutzen bringt.
In C++ sind das z.B. schlüsselwörter wie mutable, oder sogar die
templates. Kein Compiler den ich benutze (visual C++ und Gcc)
kann mit templates so umgehen wie es der Standard verlangt. Export.

Mit Java sehe ich ähnliches. Java hat eine Daseinsberechtigung.
Und zwar ist ein Eckpfeiler die relative Überschaubarkeit.
Bernd Eckenfels
2007-07-22 01:47:06 UTC
Permalink
Post by Thomas Thiele
Worauf ich eigentlich hinauswollte sind sprachunabhängige
Designpatterns die nur deswegen in Java "schlechtes Design"
sind, weil sie in Java nicht gehen.
Ja, aber super.super ist generell schlecht, es verstößt gegen die Kapselung.
Ich wuesste garnicht wozu ich das brauche.
Post by Thomas Thiele
einer Methode verbietet. Umgekehrt fehlt mir ein beiden allen
Sprachen ein Schlüsselwort ala "overwrite" was redefinition
einer Methode in einer abgeleiteten Klasse erzwingt.
Das tut doch abstract?

Gruss
Bernd
Lothar Kimmeringer
2007-07-22 08:37:19 UTC
Permalink
Post by Bernd Eckenfels
Post by Thomas Thiele
einer Methode verbietet. Umgekehrt fehlt mir ein beiden allen
Sprachen ein Schlüsselwort ala "overwrite" was redefinition
einer Methode in einer abgeleiteten Klasse erzwingt.
Das tut doch abstract?
Er meint das der Art, dass die Methode in der Superklasse
durchaus definiert ist, bei einer Ableitung aber ebenfalls
ueberschrieben werden muss. Wenn Du Dir sein Beispiel
ansiehst, wirst Du zwei unscheinbare geschweifte Klammer
hinter der Methode sehen ;-)


Gruesse, Lothar
--
Lothar Kimmeringer E-Mail: ***@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!
Dirk Brosowski
2007-07-23 08:32:06 UTC
Permalink
Post by Thomas Thiele
Post by Alfred
Post by Thomas Thiele
Kein super.super.function(); möglich. Das ist Mist.
Dann ist dein Design einfach nur Murks - das braucht
kein Mensch.
Sorry, aber das ist immer zu einfach!
Nein, ist es nicht. Im objektorientierten System mit Vererbung ist es
ein schlechtes Design wenn ich auf die super-Methode nicht meines
direkten Vorfahrens zugreife, sondern die von dessen Vorfahren.

Das ist so und das bleibt so. Das ist weder leserlich, noch wartbar und
damit der Beginn des Todes einer Klassenhierachie.


Grüße

Dirk
Thomas Thiele
2007-07-23 21:30:01 UTC
Permalink
Post by Dirk Brosowski
Nein, ist es nicht. Im objektorientierten System mit Vererbung ist es
ein schlechtes Design wenn ich auf die super-Methode nicht meines
direkten Vorfahrens zugreife, sondern die von dessen Vorfahren.
Das ist so und das bleibt so. Das ist weder leserlich, noch wartbar und
damit der Beginn des Todes einer Klassenhierachie.
Die Alternative wäre eine Copy-und-Paste-Orgie.
Entweder Klasse komplett parallel mit ähnlicher Funktionalität (woraus
es praktisch hinausgelaufen ist) - aber ebensowenig schön.
Oder die Luxuslösung mit kompletten Redesign: Aufwändig, erfordert neue
Tests etc. pp.
Bernd Eckenfels
2007-07-23 21:37:06 UTC
Permalink
Post by Thomas Thiele
Die Alternative wäre eine Copy-und-Paste-Orgie.
Entweder Klasse komplett parallel mit ähnlicher Funktionalität (woraus
es praktisch hinausgelaufen ist) - aber ebensowenig schön.
Oder die Luxuslösung mit kompletten Redesign: Aufwändig, erfordert neue
Tests etc. pp.
Ohne konkrete Beispiele zu kennen kann man dir nichts raten, aber aus meiner
Erfahrung kann ich dir hier nicht zustimmen. Wenn du die Funktion einer
ueberschriebenen super methode nicht nutzen kannst, wieso kannst du deren
super methode nutzen (woher kennst du diese wenn die kapselung sauber ist).

In der Regel ist es generell sauber Funktionen die Ableitungen benutzen
koennten in eine eigene helper methode zu packen, und diese aufzurufen. Dann
kann man diese erstens wiederverwenden und zweitens mit feiner granularität
ueberschreiben.

Gruss
Bernd
Dirk Brosowski
2007-07-24 09:17:17 UTC
Permalink
Post by Thomas Thiele
Post by Dirk Brosowski
Nein, ist es nicht. Im objektorientierten System mit Vererbung ist es
ein schlechtes Design wenn ich auf die super-Methode nicht meines
direkten Vorfahrens zugreife, sondern die von dessen Vorfahren.
Das ist so und das bleibt so. Das ist weder leserlich, noch wartbar
und damit der Beginn des Todes einer Klassenhierachie.
Die Alternative wäre eine Copy-und-Paste-Orgie.
Entweder Klasse komplett parallel mit ähnlicher Funktionalität (woraus
es praktisch hinausgelaufen ist) - aber ebensowenig schön.
Oder die Luxuslösung mit kompletten Redesign: Aufwändig, erfordert neue
Tests etc. pp.
Eine Copy-and-Paste-Orgie ist mit Sicherheit falsch. Für mich riecht das
weiterhin nach einem falschen Design. Warum leitest du überhaupt von
diesem Objekt und nicht von dessen Vater ab? Ist das wirklich "ein"
Objekt oder stecken da vielleicht zwei gleichzeitig drin? Sozusagen der
Wohnzimmertisch und der Wohnzimmerstuhl und du brauchst nun zwar den
Wohnzimmertisch und seine Eigenschaften und parallel vielleicht doch auf
jeden Fall einen normalen Stuhl.

Solche Ideen kommen mir ... und das ist definitiv Murks, grosser Murks
wie mal jemand sagte.

Desweiteren könnte es sein, dass du deine Probleme besser mit einigen
DesignPattern lösen könntest. Delegator fällt mir da direkt mal ein.


Grüße

Dirk
Thomas Thiele
2007-07-21 15:11:43 UTC
Permalink
Post by Alfred
Post by Thomas Thiele
Man kann Werte in Klasseninstanzen durchaus auch anders setzen als
per Kontruktor und Setter-Funktionen.
Reflection?
Nicht nur. a kann aus einer nativen Methode stammen.
Oder aus dem Aufruf einer anderen Klasse, die mir - da anderes Package -
nicht sichbar ist.
a kann Ergebnis einer Berechnung oder internen Zählung sein.
a kann beim parsen entstanden sein, z.B. xmlbeans oder axis.
etc. pp.

a ist ja nur ein Beispiel. Entscheident ist, dass ich die
privaten Member gar nicht kenne, ja gar nicht kennen soll!
Trotzdem müssten sie übernommen werden.
Ein impliziter Copy-Contructor würde da Wunder wirken...
Post by Alfred
Post by Thomas Thiele
Die Welt besteht nicht nur aus Bohnen...
Stimmt - man kann auch Kakao trinken.
Post by Thomas Thiele
Post by Andreas Eberhöfer
Post by Thomas Thiele
Kein super.super.function(); möglich. Das ist Mist.
Findest du, ich hab das noch nie gebraucht.
Ich schon.
Dann ist dein Design einfach nur Murks - das braucht
kein Mensch.
Post by Thomas Thiele
...
In der Tat ist Java schon damit ein Selbstläufer.
Java ist ja nicht schlecht. Nur leider zu sehr gegenüber C++ gelobt
und C++ verteufelt. Ich erlebe das in Diskussionen auf Arbeit sehr
häufig.
Jede Sprache hat ihre Daseinsberechtigung. Man muss nur wissen,
was man will. Und ich möchte z.B. keine WebApp mit C++ schreiben.
Allerdings die Weiterentwicklung von Java macht daraus langsam
aber sicher eine bunte Mischung aus syntaktischen Schnipseln
aller Art - irgendwann wird's unerträglich.
Alfred
Thomas Thiele
2007-07-21 15:14:26 UTC
Permalink
Post by Alfred
Post by Thomas Thiele
Die Welt besteht nicht nur aus Bohnen...
Stimmt - man kann auch Kakao trinken.
BTW. es gibt auch Kakaobohnen...;-)
Alfred
2007-07-22 10:37:12 UTC
Permalink
Post by Thomas Thiele
Post by Alfred
Post by Thomas Thiele
Die Welt besteht nicht nur aus Bohnen...
Stimmt - man kann auch Kakao trinken.
BTW. es gibt auch Kakaobohnen...;-)
Stimmt - ist mir im Nachhinein auch aufgefallen.
Aber es gibt ja auch Tee - und den hats nicht in Bohnen.

Alfred
Wolfgang Rostek
2007-07-20 18:19:59 UTC
Permalink
Ich habe ab und zu Aufgaben, wo ich große Datenmengen in Memory
analysieren möchte/muß. Die Rohdaten haben schon mal 100MB und
mehr (mit 1byte character encoding). Um lazy loading/unloading und
stärkeres Filtern einzubringen, habe ich eher weniger Zeit. Alles rein
und die hohe Performance von in-memory ausnutzen.

Der Memory Overhead um Primitive (in Collections) und Strings zu
bearbeiten ist
aber beträchtlich. Einige Sachen wären durchaus innerhalb von 2GB und
mit der 32bit JVM zu machen, wenn nicht Java so viel drauflegen würde.

Hier ein etwas älterer Artikel von SMA, der dies zeigt (und auch eine
Lösung für Strings)

http://groups.google.com/group/de.comp.lang.java/browse_frm/thread/6de5ef8213f26836/f164638ac267ad8b?lnk=gst&q=Aust+50+String+char+header&rnum=1#f164638ac267ad8b

Gruß
Wolfgang R.
m***@heinerkuecker.de
2007-07-20 18:52:29 UTC
Permalink
Post by Wolfgang Rostek
Ich habe ab und zu Aufgaben, wo ich große Datenmengen in Memory
analysieren möchte/muß. Die Rohdaten haben schon mal 100MB und
mehr (mit 1byte character encoding). Um lazy loading/unloading und
stärkeres Filtern einzubringen, habe ich eher weniger Zeit. Alles rein
und die hohe Performance von in-memory ausnutzen.
Der Memory Overhead um Primitive (in Collections) und Strings zu
bearbeiten ist
aber beträchtlich. Einige Sachen wären durchaus innerhalb von 2GB und
mit der 32bit JVM zu machen, wenn nicht Java so viel drauflegen würde.
In diesem Artkel steht einiges zum Speicherlayout von Objekten:

ftp://www6.software.ibm.com/software/developer/jdk/diagnosis/GCandMemory-042005.pdf

Leider nichts über Primitive.

Zum Thema zwar etwas unpassend, aber ich wills einfach mal sagen:

So manches Gross-Projekt wäre ohne Java sehr viel schwerer
oder unmöglich.

Das fängt schon mit dem Kompilieren an.

Keine Header-Dateien und keine einzuhaltende Reihenfolge
der Deklaration und Benutzung aller Entitäten.

Rekursive Deklaration von Klassen kein Problem.

javac und ant usw machen den ganzen make-Kram mit.

Linken nicht notwendig.

Laufzeit:

Alles viel sicherer und die JVM lädt nur die Klassen,
die sie benötigt. Alles andere bleibt draussen,
egal wieviel Code das ganze Projekt hat.

Bei C/C++ müsste man da schon mit DLLs oder
*.so oder *.bin arbeiten.
Ich glaube, die binden sich auch nicht so natürlich wie
Interface-Implementierungen in die Sprache ein.

Komponenten:
OSGi oder die neuen Super-Packages

So was gibt es unter C/C++ gar nicht.

Entwickeln:

Bequem auf Eclipse oder anderer IDE unter
Windows entwickeln und später läuft es auf
Host (zOS) oder Linux oder Solaris.

Alles sehr einfach und bequem.

Heiner
www.heinerkuecker.de
Wolfgang Rostek
2007-07-20 20:24:06 UTC
Permalink
Danke für den Link.

Ich selbst habe auch wenig an Java auszusetzen und versuche
möglichst alles in Java zu lösen. Hab einfach keine Lust im
Augenblick eine weitere Sprache zu lernen.
Ok, einige kleine Sachen sind in einer Unix Shell auch sehr
zeitsparend zu lösen.

Den Punkt den ich oben erwähnt habe betrifft einen kleinen
Sprachenstreit mit meinen Kollegen aus der SQL Fraktion.

Wir haben eine große Oracle Datenbank und müssen (off-line)
Daten extrahieren und ein temporäres Modell bauen. Die
Kollegen verstricken sich in immer komplexere SQL Statements
und die Laufzeit der Queries ist auch beträchtlich.

Meine Idee ist den erforderliche Subset in Java Objekte in
Memory zu laden und dann die Verknüpfungen auf den
Maps zu programmieren. Sollte doch extrem schnell sein,
wenn ich nicht mehr die Platte kontaktieren muß. Bin mir
aber nicht sicher, wie optimal dies auch schon von SQL/Oracle
auf der anderen Seite gemacht wird.

Wenn ich aber schon für einen String mit einem Character
50 byte belege, brauche ich bei unserer Datenmenge erst
gar nicht anfangen. Allein wenn ich in Java mit 1 byte chars
arbeiten könnte, wäre das schon super.

Gibt es irgendwo eine Bibliothek, um nicht zu kompliziertes
String Handling mit 1 byte ASCII Strings zu machen?

Gruß
Wolfgang R.
m***@heinerkuecker.de
2007-07-23 11:04:16 UTC
Permalink
Wolfgang Rostek
Post by Wolfgang Rostek
Gibt es irgendwo eine Bibliothek, um nicht zu kompliziertes
String Handling mit 1 byte ASCII Strings zu machen?
http://www.heinerkuecker.de/Xrpp.html

http://control-and-command.de/zip/Xrpp.zip

In dem zip-File gibt es die Klassen
ByteStr
ByteStrBuff

Heiner
www.heinerkuecker.de
Wolfgang Rostek
2007-07-23 15:30:14 UTC
Permalink
Vielen Dank, super Hilfe

Gruß
Wolfgang R.
Alfred
2007-07-21 05:55:03 UTC
Permalink
Post by Thomas Thiele
...
Aber was habe ich gekonnt? Mein B Objekt was per Vererbung ein A
Object _ist_ wird niemals
die private Variable a übernehmen.
Vielleicht reicht ja mein kleines Hirn nicht ganz aus,
aber seit wann soll ein _privates_ Member übernommen werden?

Ich sehe deine Einschränkungen bei Java jedenfalls nicht
so ganz und wüsste spontan auch nicht, was ich in der
täglichen Praxis mit Java gar nicht hinbekommen würde.
Post by Thomas Thiele
Java ist ja nicht schlecht. Nur leider zu sehr gegenüber C++
gelobt und C++ verteufelt. Ich erlebe das in Diskussionen auf
Arbeit sehr häufig.
Du trittst gerade genau auf diesem Pfad - nur andersrum...

Alfred
Stefan Matthias Aust
2007-07-22 10:09:31 UTC
Permalink
Post by Thomas Thiele
Was ich meine sind harte Einschränkungen die es unmöglich machen etwas
bestimmtes zu programmieren oder wirklich zu schlimmeren Fehlern
führen. [...]
Ich empfinde deine drei Beispiel allesamt als unkritisch. Für die
Verwaltung von Ressourcen musst du (geschwätzig wie immer in Java) ein

Resource r = aquire();
try {
use(r);
} finally {
dispose(r);
}

benutzen. Hier würde ich Java stattdessen vorwerfen, das man derartige
Codeabschnitte nicht abstrahieren kann, also dass das fehlt, was als
Closures durch die Diskussionen geistert.

In C# gibt es das Schlüsselwort using, in Python heißt es with.

Ich meine, du schriebst, dass Python ebenfalls Ressources sofort
freigibt. Das ist glaube ich ein Artefakt, was (jedenfalls in den
älteren Versionen) dem mangelhaften GC mittels Referenzzählung
geschuldet ist. Python 3k soll doch damit aufhören, oder? Dann wäre dort
das selbe von dir wahrgenommene Problem wie bei Java vorhanden.

Ich bin ein Fan von explizitem Kopieren und würde lieber besser
verhindern können, dass man Objekte ändern kann. Dies funktioniert
leider nur umständlich durch das definieren weiterer Interfaces und das
muss man im Voraus planen.

Ein "super.super" habe ich noch nie gebraucht.
Post by Thomas Thiele
Fällt euch noch mehr ein?
Mich stört beispielsweise bei Java, das es keine Closures gibt, dass ich
keine lokale Typinferenz habe (beides Features, die C# 3.0 inzwischen
bietet) und das die aktuellen VMs beim Hot Code Replacement versagen,
sobald man die Objektstruktur ändert.
--
Stefan Matthias Aust
Lothar Kimmeringer
2007-07-22 11:12:59 UTC
Permalink
Post by Thomas Thiele
1. Zerstörung von Objekten nicht "just in time".
--------------------------------------------------------------------
Garbagecollection und die Nichtnotwenigkeit sich um Aufräumarbeiten zu
kümmern mag ein Vorteil sein. Aber die Java-Garbagecollection
garantiert eben nicht - wie bei Python beispielsweise - die sofortige
Zerstörung (bzw. wenigstens den sofotigen Aufruf eines Destruktors)
wenn das Objekt den Sichtbarkeitsbereich verlässt.
Das nicht, frueher oder spaeter wird das ganze aber abgeraeumt, was
fuer mich aufs gleiche herauskommt. Dein Beispiel mit wachsendem
Ressourcenverbrauch wuerde Dir aber auch woanders passieren, evtl.
aber garniert mit einem Coredump, weil Du durch Aufruf des Destruktors
Ressourcen freigegegen hast, die von anderer Seite dann ploetzlich
versucht wird, verwendet zu werden.
Post by Thomas Thiele
D.h. durch verspätete destruierung bzw. der Unmöglichkeit einer
automatischen Destruierung entstehen Ressourcenleaks!
Nein. Wenn Du weiter bei der Behauptung bleibt, haette ich gerne
einen Proof of Concept in Form eines Testcases.
Post by Thomas Thiele
Fällt euch noch mehr ein?
Mir persoenlich gehen ab und zu Friend-Deklarationen ab, also
die Moeglichkeit, Methoden oder Members fuer bestimmte Klassen
sichtbar zu machen, fuer den Rest aber nicht. Man kann sich
zwar mit Package Visiblity behelfen, manchmal ist mir das aber
schon zu viel Sichtbarkeit.


Gruesse, Lothar
--
Lothar Kimmeringer E-Mail: ***@kimmeringer.de
PGP-encrypted mails preferred (Key-ID: 0x8BC3CD81)

Always remember: The answer is forty-two, there can only be wrong
questions!
Bernd Eckenfels
2007-07-22 13:30:19 UTC
Permalink
Post by Lothar Kimmeringer
Mir persoenlich gehen ab und zu Friend-Deklarationen ab, also
die Moeglichkeit, Methoden oder Members fuer bestimmte Klassen
sichtbar zu machen, fuer den Rest aber nicht. Man kann sich
zwar mit Package Visiblity behelfen, manchmal ist mir das aber
schon zu viel Sichtbarkeit.
Ack. Ich wünsche mir z.b. hierarchische packages, das würde der package
visibility schon einiges helfen.

Gruss
Bernd
Florian Weimer
2007-07-22 11:42:47 UTC
Permalink
Post by Thomas Thiele
1. Zerstörung von Objekten nicht "just in time".
--------------------------------------------------------------------
Garbagecollection und die Nichtnotwenigkeit sich um Aufräumarbeiten zu
kümmern mag ein Vorteil sein. Aber die Java-Garbagecollection
garantiert eben nicht - wie bei Python beispielsweise - die sofortige
Ich glaube, daß das auch nicht von Python garantiert wird. Die gängige
C-Implementierung macht das so, es gibt aber noch andere.
Post by Thomas Thiele
Zerstörung (bzw. wenigstens den sofotigen Aufruf eines Destruktors)
wenn das Objekt den Sichtbarkeitsbereich verlässt.
D.h. durch verspätete destruierung bzw. der Unmöglichkeit einer
automatischen Destruierung entstehen Ressourcenleaks! Entgegen dem
Java-Versprechen...
Das kann man jedenfalls durch try-finally nachbauen. Die fehlende
finally-Klausel kann man sicherlich mit einem Werkzeug à la FindBugs
automatisch finden.

Ich gebe zu, daß ein using-Konstrukt, wie es C# hat, noch besser
wäre. Aber die automatische Speicherverwaltung per Referenzzähler
(das, was C-Python macht) hat selbst eine ganze Reihe von Problemen,
so daß sie keine allgemeine Lösung ist.
Post by Thomas Thiele
2. Kein impliziter Copycontructor.
Aber was habe ich gekonnt? Mein B Objekt was per Vererbung ein A
Object _ist_ wird niemals die private Variable a übernehmen.
In Java würde man das per Delegation angehen.
Post by Thomas Thiele
3. Aufruf einer Funktion einer höheren Basisklasse nicht möglich
Naja, wenn dieses Konstrukt möglich und sinnvoll ist, dann muß man so
viel dokumentieren, daß es auf die zusätzliche Methode auch nicht
ankommt.
Heiner Kücker
2007-07-22 13:06:11 UTC
Permalink
Thomas Thiele schrieb
Post by Thomas Thiele
ich wollte mal Nachfragen, welche Nachteile oder besser Fehler ihr in
Java in Vergleich zu anderen Programmiersprachen seht. Ich meine nicht
Sachen die in Java und der Philosophie begründent liegen,
sondern Eigenschaften, die es unmöglich machen etwas bestimmtes zu
programmieren.
Ich hab nicht alles gelesen, evtl. hat es schon jemand geschrieben.

Betriebssystemnahe Sachen wie Gerätetreiber, Kernelmodule,
Interrupt-Handler oder so gehen mit Java nicht.

Bis Java5 hat man ohne Zusatz-Lib nicht mal die Info über den freien
Plattenplatz im API.
--
Heiner Kücker
www.heinerkuecker.de
www.control-and-command.de
m***@heinerkuecker.de
2007-07-23 11:19:03 UTC
Permalink
Thomas Thiele
Post by Thomas Thiele
ich wollte mal Nachfragen, welche Nachteile oder besser Fehler ihr in
Java in Vergleich zu anderen Programmiersprachen seht. Ich meine nicht
Sachen die in Java und der Philosophie begründent liegen,
sondern Eigenschaften, die es unmöglich machen etwas bestimmtes zu
programmieren.
C++ Programmierer mögen Operatorüberladung und Mehrfachvererbeung
vermissen. Das meine ich z.B.
nicht. Denn beide Dinge kann man mehr oder weniger hübsch mit anderen
Konstrukten lösen.
Auch das Java als Programmierparadigma Objektorientierung (scheinbar)
erzwingt ist keine Einschränkung in dem Sinne.
Hast Du das hier schon mal gelesen ?

C-Hasser in 10 Tagen

http://www.math.uni-bremen.de/~thielema/CHater.html

Heiner
www.heinerkuecker.de
Thomas Thiele
2007-07-23 18:37:47 UTC
Permalink
Post by m***@heinerkuecker.de
C-Hasser in 10 Tagen
Das ist eben der Unterschied...Javahasser wird man schneller...;-)

Ernsthafter:
C ist nicht C++ und auch C++ ist keine schöne Sprache.
Aber eine recht mächtige.
Andreas Eberhöfer
2007-07-23 19:25:13 UTC
Permalink
Post by Thomas Thiele
Post by m***@heinerkuecker.de
C-Hasser in 10 Tagen
Das ist eben der Unterschied...Javahasser wird man schneller...;-)
Und PHP-Hasser wird man noch schneller.
Post by Thomas Thiele
C ist nicht C++ und auch C++ ist keine schöne Sprache.
Aber eine recht mächtige.
Kaum ein Mensch will heute noch eine Eierlegende-Woll-Milch-Sau-Sprache.
Es geht doch darum, dass jede Sprache ihr Anwendungsgebiet hat. Für
betriebliche Informationssysteme gibt IMHO keine besser geeignete
Sprache als Java. Ich will mich dabei hauptsächlich auf meine
Bussinesslogik konzentrieren, und mir keine Gedanken darüber machen wie
ich meinen Speicher wieder aufräumen muss, so wie ich es in C/C++ machen
muss.
Umgekehrt würde ich nicht umbedingt Embedded Systeme in Java
programmieren wollen, da will man so viel rausholen wie geht, da macht
für mich "Zeiger-Schubsen" Sinn. Genau so wenig würde ich ein
Datenbanksystem für große Systeme in Java machen.
Python finde ich zwar eine ganz nette Sprache, aber für mich ist es noch
keine ernsthafte Kongurenz zu Java. Das ist sicherlich eine persönliche
Sache, aber ich bin kein großer Fan von dynamischen Sprachen. Außerdem
finde ich es etwas seltsam, dass man bei jeder Objekt-Methode self als
ersten Parameter mitgeben muss und das es keine Namespaces oder Packages
gibt. Aber sicherlich gibt es auch einige sehr nette Sprachfeatures wie
yield, List comprehension oder Function Decorators.

Nimm es nicht persönlich, aber hast du schon mal daran gedacht den Job
zu wechseln und etwas zu machen das sich mit C++ besser lösen lässt, als
hier Java-Bashing zu betreiben ;).

mfg
Andreas
Thomas Thiele
2007-07-23 21:27:26 UTC
Permalink
Post by Andreas Eberhöfer
Nimm es nicht persönlich, aber hast du schon mal daran gedacht den Job
zu wechseln und etwas zu machen das sich mit C++ besser lösen lässt, als
hier Java-Bashing zu betreiben ;).
Dann machts doch keinen Spass mehr. Wenn man täglich mit C++ zu tun hat
und zwar sowohl mit eigenen dahingesch...luderten Code als auch mit dem
von anderen (keine aufgeräumten Open-Source-Projekte...sondern
kommerzielle Software...;-)) dann würde ich den ganzen Tag auf C++
kotzen...;-)

Aber irgendwie versöhnt mich dann immer die monatliche Überweisung...;-)
Da programmiert man auch schon mal Visual Basic falls gewünscht.
(war mal ein durchaus ernsthaftes Projekt, zwar nicht super groß, aber
egal.)

Das Problem ist, dass Projekte wachsen, da noch ein bisschen aufgbohrt,
da noch was drangeschraubt. Und schwuppdiwupp hat man schlechtes Design.
Wenn dann die Sprache noch gutes Design auch in solchen "Notfällen"
(Termindruck, keine schnelle Alternative) erzwingen will, hat man die
Sprache halt gegen sich...und dann entstehen solche Threads. ;-)
Bernd Eckenfels
2007-07-23 21:40:16 UTC
Permalink
Post by Thomas Thiele
Das Problem ist, dass Projekte wachsen, da noch ein bisschen aufgbohrt,
da noch was drangeschraubt. Und schwuppdiwupp hat man schlechtes Design.
Wenn dann die Sprache noch gutes Design auch in solchen "Notfällen"
(Termindruck, keine schnelle Alternative) erzwingen will, hat man die
Sprache halt gegen sich...und dann entstehen solche Threads. ;-)
Also ich habe bisher immer den Eindruck gehabt dass einem Java in genau den
Situationen dank GC und managed Code den Arsch rettet. Mach mal ein grosses
C++ Projekt (und suche ne Memory Corruption), dass weisst du was ich meine.

Dinge wie "fehlendes" super.super sind ja notfalls wenn es sein muss mit 2-3
Zeilen als Work-around geloest, man kann nicht davon reden dass Java einem
in dem Fall ausbremst. (aber man kann mit sicherheit sagen dass in vielen
stellen in denen man sich ausgebremst fuehlt man besser eine andere Loesung
nehmen sollte)

Gruss
Bernd
Thomas Thiele
2007-07-23 22:50:56 UTC
Permalink
Post by Bernd Eckenfels
Also ich habe bisher immer den Eindruck gehabt dass einem Java in genau den
Situationen dank GC und managed Code den Arsch rettet. Mach mal ein grosses
C++ Projekt (und suche ne Memory Corruption), dass weisst du was ich meine.
Ich weiss was du meinst.
Im Zusammenspiel mit vielen anderen Programmieren rettet das wirklich
einen den Arsch. Allerdings fehlt die Gegenprobe...
Wenn ich meinen eigenen Code kenne, dann weiss ich wo ich suchen muss
und habs auch fast[1] immer gefunden.
Aber fremden Code zu debuggen ist Sackgang.

[1] multithreading mit posix threads und sockets unter IRIX, suid also
das ganze Programm unter Unix mit C-Libs etc. Die Memory Corruption war
nicht zu finden und das Programm stützte nichtderterministisch ab.

Letztendlich habe ich das in Python gemacht. Genauer das war mein erstes
Projekt in Python auf Anraten meines damaligen Kollegen. Er hatte Recht.
Dass Java Threading eingebaut hat ist ein großes Plus für Java.

Aber ansonsten habe ich schon einen Raytracer inclusive (recht
spartanischer, aber immerhin vier Ansichten, ) GUI gechrieben.
Geht alles...
Dirk Brosowski
2007-07-24 10:57:33 UTC
Permalink
Post by Thomas Thiele
Das Problem ist, dass Projekte wachsen, da noch ein bisschen aufgbohrt,
da noch was drangeschraubt. Und schwuppdiwupp hat man schlechtes Design.
Wenn dann die Sprache noch gutes Design auch in solchen "Notfällen"
(Termindruck, keine schnelle Alternative) erzwingen will, hat man die
Sprache halt gegen sich...und dann entstehen solche Threads. ;-)
Wenn ich sowas lese, dann kommt mir das Grauen und gleichzeitig die
Sicherheit, dass genau solche Leute wie du für schlechtes Design
verantwortlich sind.

Es gibt null Gründe warum ein grosses Projekt schlechtes Design haben
sollte. Es gibt tausend Gründe warum man nicht unter Termindruck auf
Quick-and-Dirty zurückgreifen soll. Denn dann entstehen nicht solche
Threads wie hier (überflüssig wie ein Kropf) sondern dann beginnt der
Todeskampf des Quelltext. Der nächste Entwickler wird die Hände über den
Kopf zusammenschlagen und die Effizienz in der Softwareentwicklung in
diesem Unternehmen tendiert gegen null.

Daraus folgt dann direkt, dass mehr Leute gebraucht werden und dann wird
wieder "Fachkräftemangel" geschrien.


Und du willst, dass Java diesen Quick-And-Dirty-Krams noch besser
unterstützt? Du solltest ganz schnell den Job wechseln, Gärtner wäre
auch nicht gut, die armen Pflanzen.

Sorry, aber sowas regt mich auf. Die Denkweise von dir zeigt mir, dass
Java und seine Paradigmen viel schwerer zu erlernen sind, als manche
glauben. Und deine Denkweise zeigt auch, dass Software-Entwicklund und
gutes Architektur-Design etc. kein Hokuspokus sind, dass jeder erlernen
könnte. Du stehst auf jeden Fall auf der anderen Seite des Zaunes.

Grüße

Dirk
Thomas Bensler
2007-07-24 11:03:47 UTC
Permalink
Post by Dirk Brosowski
Wenn ich sowas lese, dann kommt mir das Grauen und gleichzeitig die
Sicherheit, dass genau solche Leute wie du für schlechtes Design
verantwortlich sind.
[...]
Sorry, aber sowas regt mich auf. Die Denkweise von dir zeigt mir, dass
Java und seine Paradigmen viel schwerer zu erlernen sind, als manche
glauben. Und deine Denkweise zeigt auch, dass Software-Entwicklund und
gutes Architektur-Design etc. kein Hokuspokus sind, dass jeder erlernen
könnte. Du stehst auf jeden Fall auf der anderen Seite des Zaunes.
<gemütlich zurücklehn> Will noch jemand Popcorn und ein Bier?

SCNR, Thomas.
Michael Paap
2007-07-24 15:02:44 UTC
Permalink
Post by Thomas Bensler
<gemütlich zurücklehn> Will noch jemand Popcorn und ein Bier?
Ein Hefeweizen bitte. Der Thread hat Potential. ;-)

Gruß,
Michael
Dirk Brosowski
2007-07-24 15:07:15 UTC
Permalink
Post by Michael Paap
Post by Thomas Bensler
<gemütlich zurücklehn> Will noch jemand Popcorn und ein Bier?
Ein Hefeweizen bitte. Der Thread hat Potential. ;-)
Ich nehme auch ein Hefeweizen ... Popcorn lieber nicht, Nachos wären okay.

Dann habe ich auch mal Zeit zwischen dem Reden zuzuhören ;)

Aber jetzt mal ernsthaft: Bin ich der einzige der nicht verstehen kann
wieso schlechtes Design in einem Projekt als Grundlage der Begründung
für neue Features im Java-Sprachumfang verwendet wird, welche schlechtes
Design nur weiter fördern?

Grüße

Dirk
Ralf Ullrich
2007-07-24 17:19:35 UTC
Permalink
Post by Dirk Brosowski
Aber jetzt mal ernsthaft: Bin ich der einzige der nicht verstehen kann
wieso schlechtes Design in einem Projekt als Grundlage der Begründung für
neue Features im Java-Sprachumfang verwendet wird, welche schlechtes
Design nur weiter fördern?
Nee, du bist nicht der einzige. Ich war im Laufe dieses Threads zigmal
versucht Thomas Thiele einfach zu plonken nur um letztlich meine Nerven zu
schonen, weil mir bei diesem Thread eigentlich mit jedem seiner Postings
die Hutschnur hochging.

Das fängt schon mit dem Eingangsposting an: Wer eine kritische Diskussion
über die Schwächen einer Sprache beginnen möchte, sollte Experte in dieser
Sprache sein. TT ist das in Bezug auf Java ganz offensichtlich nicht, da
er ja noch nicht mal in seinen kurzen Pseudo-Code-Fetzen annähernd
korrekte Java-Syntax verwenden kann. (Penible Zeitgenossen werten schon
die Schreibweise JAVA im Betreff als Zeichen dafür, es mit einem
Java-Neuling zu tun zu haben.)

Dann ist da noch was TT in seinem Eingangsposting kritisiert: Den
Copy-Konstruktor hat er schon im September vor beinahe 2 Jahren vermisst,
und etliche Antworten darauf erhalten, nicht bloß von mir:
http://groups.google.de/group/de.comp.lang.java/msg/f7135d943a18b75f . In
einer Sprache, die auf alle Objekte nur über Referenzen zugreift und keine
echten Value-Objekte kennt, ist ein automatischer Copy-Konstructor
ziemlich unnütz. Und TT weiß ja eigentlich auch welchen Krampf man sich
mit einem solchen Konstruktor einhandelt:
http://groups.google.de/group/de.comp.lang.iso-c++/msg/2b19c6fa9b880d09 .
Warum er ihn dann in Java dennoch haben will, ist mir schleierhaft, zumal
er ja jeden Kritikpunkt der in der Philosophie von Java begründet ist
eigentlich ausschließt. Und der autom. Copy-Konstruktor ist nicht nur eng
mit dem Operator-Overloading verknüpft, sondern auch aus den gleichen
Gründen, nämlich zu leicht missverständlichen Code schreiben zu können,
aus Java herausgehalten worden.

Naja, zu super.super.foo() kann ich dann nur sagen, dass mir beim bloßen
Gedanken, sowas nötig zu haben, schon das Grauen kommt. (Was soll
eigentlich in folgendem Fall passieren:
class A {
int foo() {...}
}
class B extends A {
int foo() {... super.foo(); ...}
int bar() {...}
}
class C extends B {
int foo() {... super.super.foo(); ...}
}

Und jetzt wird B refaktoriert, weil noch etwas B-ähnliches dazu kommt:

abstract class AbstractB extends A {
int foo() {... super.foo(); ...}
abstract int bar();
}
class B extends AbstractB {
int bar() {...}
}
class BB extends AbstractB {
int bar() {...}
}

Was soll das super.super.foo() in C jetzt machen? Ruft es immer noch
A#foo() auf?)

Na und die Behauptung wegen der Lazy-GC seien Resourcenleaks unvermeidlich
haben ja schon genug Leute widerlegt.


Nun wenn ich mich auf dieselbe Ebene wie TT stellen würde, dann würde ich
mit meinen mageren C++ Kenntnissen mal in einer C++ Gruppe fragen, was die
wirklichen Einschränkungen von C++ seien. Da fiele mir mal als allererstes
ein, dass man in C++ kein Metaprogramming machen kann, wie es in Java zur
Build-Time durch Bytecode-Enhancer schon immer und seit 1.5 durch die
Instrumentation API auch zur Laufzeit möglich ist.

Und kann ich in C++ von einem Objekt auf das ich nur eine Referenz
erhalten habe, dessen Schnittstelle herausfinden? Und so wie Beans auch in
Skripten in meiner Anwendung benutzen? Überhaupt: Kann ich C++ ähnlich dem
BSF leicht eine Scripting-Sprache in meine Anwendung einbauen, die dann
Zugriff auf meine Anwendungsobjekte erhalten kann? Für all das ist
Reflection nötig und die gibt es AFAIK bei C++ nicht.

Nun mag es dennoch sein dass es sowas gibt, ich kenne C++ nicht genug um
es zu kritisieren, und ich würde mir wünschen, dass TT _meiner_
Lieblingssprache solange er kein Experte in ihr ist, denselben Respekt
entgegenbringt, wie ich seinem geliebten C++ und Python und was noch alles.

cu
Stefan Ram
2007-07-24 17:43:43 UTC
Permalink
Da fiele mir mal als allererstes ein, dass man in C++ kein
Metaprogramming machen kann, wie es in Java zur Build-Time
durch Bytecode-Enhancer schon immer und seit 1.5 durch die
Instrumentation API auch zur Laufzeit möglich ist.
C++ erlaubt Metaprogrammierung mit Schablonen, wenn auch nicht
in so einfacher Weise wie in Lisp mit Lisp-Makros. Die
Instrumentierung von Java

http://java.sun.com/javase/6/docs/api/java/lang/instrument/package-summary.html

kenne ich nicht so gut, habe sie aber bisher nicht als
besondere Unterstützung von Metaprogrammierung wahrgenommen.

In C++ gibt es allerdings eine gut gepflegte Kultur der
Metaprogrammierung.

Die Idee, dazu Schablonen einzusetzen stammt von Erwin Unruh

http://www.erwin-unruh.de/meta.html

, sie wurde unter anderem durch das Buch von Alexandrescu populär

http://erdani.org/book/main.html

und wird heute intensiv eingesetzt, etwa in boost.

http://www.boost.org/

Ein gewisses Maß an Metaprogrammierung ist mit jeder Sprache
möglich, so kann ein BASIC-Programm ein anderes BASIC-Programm
generieren.

10 PRINT "10 PRINT 10"

Auch den Einsatz von Präprozessoren kann man als
Metaprogrammierung ansehen.
Und kann ich in C++ von einem Objekt auf das ich nur eine
Referenz erhalten habe, dessen Schnittstelle herausfinden?
C++ kennt ja keine Schnittstellen als Teil der Sprache
- den Laufzeittyp kann man mit RTTI wohl nicht immer
erhalten.
Ralf Ullrich
2007-07-24 18:27:05 UTC
Permalink
Post by Stefan Ram
Da fiele mir mal als allererstes ein, dass man in C++ kein
Metaprogramming machen kann, wie es in Java zur Build-Time
durch Bytecode-Enhancer schon immer und seit 1.5 durch die
Instrumentation API auch zur Laufzeit möglich ist.
C++ erlaubt Metaprogrammierung
Danke für den Hinweis, aber wie ich feststellen muss, versteht man wohl
heute unter "Metaprogrammierung" etwas anderes als ich 1988 gelernt habe.
Ich zitiere:

*Metaprogramme* behandeln andere Programme als Daten. Die Objekte, die von
Metaprogrammen manipuliert werden, sind selbst Programme.

*Metaprogrammierung* ist somit als Erstellung von Programmen definiert,
die die Manipulation von anderen Programmen zum Ziel haben.

(aus Gustaf Neumann - Metaprogrammierung und Prolog - ISBN m3-925118-94-2)

Damit fallen Java-Profiler, AspectJ, JDO-Bytecodeenhancer, Instrumentation
und ähnliches, wie z.B. das annotationsgesteuerte JAXB 2.x, unter diese
Definition von Metaprogrammierung, aber das worauf du in Bezug auf C++
verwiesen hast, scheint mir nicht darunter zu fallen. Aber ich kann mich
täuschen, wie gesagt ich kann C++ nur rudimentär. (Achja, die Hotspot-VM
selbst ist natürlich auch ein Metaprogramm, genauer sogar ein
Metaübersetzer und -interpreter, da sie Bytecode-Programme als Daten
behandelt.)


Die neue Begriffsverwendung von "Metaprogrammierung", die sich auch in der
Wikipedia findet (http://de.wikipedia.org/wiki/Metaprogrammierung) und der
Verwendung bei C++ entspricht, ist dagegen bloße Code-Generation. Der
wesentlich Unterschied, ist, dass C+-Metaprogrammierung prinzipiell aus
beliebigen Daten Programmcode generiert, während die Metaprogrammierung,
so wie ich sie kenne, aus normalem Programmen, die nicht extra für diesen
Schritt vorbereitet sind, neue erweiterte Programme erzeugt, also
tatsächlich Programme als Eingabedaten entgegennimmt.

Ein einfach vorzustellendes Beispiel ist da ein Metaprogramm M, dass einem
Programm P Tracing-Funktionalität hinzufügt, sodass jeder Methodenaufruf
bei Einsprung und Rücksprung jeweils eine entsprechende Tracing-Meldung
ausgibt. M kann dabei das Programm P entweder interpretieren und während
der Interpretation die Meta-Funktionalität liefern, oder so zu einem neuen
Programm übersetzen, dass die Meta-Funktionalität in das Programm
integriert wird. In letzerem Fall ist das Ergebnis ein neues Programm
P_trace, dass durch weitere Metaübersetzer noch weiter erweitert werden
kann.

cu
Stefan Ram
2007-07-24 18:57:12 UTC
Permalink
Post by Ralf Ullrich
Wikipedia findet (http://de.wikipedia.org/wiki/Metaprogrammierung) und der
Verwendung bei C++ entspricht, ist dagegen bloße Code-Generation.
Hierfür gibt es auch die Bezeichnung »generative Metaprogrammierung«.

http://www.struji.com/files/2007gttse.pdf

Das »abstract« dieser aktuellen [Konferenzbeitrag für Juli
2007] PDF-Quelle beginnt auch mit einer Definition von
»metaprogramming«:

»Metaprogramming is the concept that program synthesis is
a computation. Generative programming is about developing
metaprograms that synthesize other programs.«

Die generative Metaprogrammierung ist nicht mit der
»generischen Metaprogrammierung« zu verwechseln, die den
Einsatz typgenerischer Schablonen bezeichnet.

Da ist C++ mit seinem »duck-typing« etwas flexibler als Java
mit seinen Schnittstellen, das dafür wiederum
semantisch-typsischerer ist.

Ansonsten müssen wir wohl anerkennen, daß es keine
einzig-richtige und allgemein anerkannte Definition von
»Metaprogrammierung« gibt.

Die ISO-2382-Familie von Normen zu Begriffen der Informatik
erwähnt diesen Begriff gar nicht. Auch nicht das verwandte
INCITS-Begriffsverzeichnis:

http://www.incits.org/tc_home/k5htm/m2.htm

Also ist der Begriff schon etwas abgelegener.
Wanja Gayk
2007-07-25 21:41:17 UTC
Permalink
Dirk Brosowski said...
Post by Dirk Brosowski
Aber jetzt mal ernsthaft: Bin ich der einzige der nicht verstehen kann
wieso schlechtes Design in einem Projekt als Grundlage der Begründung
für neue Features im Java-Sprachumfang verwendet wird, welche schlechtes
Design nur weiter fördern?
Der von dir zitierte Teil war zumindest nach meinem dafürhalten keine
Lobeshymne auf Sprachen die schlechtes Design gutheißen, sondern las
sich für mich eher wie eine simple Bestandsaufnahme ohne Wertung.

Ist halt so: Wenn du unter Termindruck, Quick&Dirty willst, aber dir die
Sprache das nicht durchgehen lassen will, steht dir die Sprache im Weg.
Und ich möchte hinzufügen: Wowereit!
Auch wenn es mal nervt, ist es doch gut, wenn man in dem Moment einer
gewissen Scheißegal-Haltung, weil der Kunde ohne Ende Druck macht und
man den einfach nur losweden will, wenigstens ein bischen in seinem
Schaum gebremst wird, damit man sich nicht noch mehr Scheiße einfängt,
die einem später dreimal so heftig um die Ohren fliegt.

Gruß,
-Wanja-
--
Ada Byron, die Lochkarten für Babbages "Difference Engine" vorbereitete,
gilt als die erste Programmiererin der Weltgeschichte. Sie hat auch das
Verhaltensmuster für alle nachfolgenden Programmierer vorgegeben: Sie
trank und schluckte Drogen.
Peter Katzmann
2007-07-25 06:45:39 UTC
Permalink
Für mich gibt es nur eine wirkliche Schwäche bei Java.
Wenn man mal versucht hat die serielle Schnittstelle direkt zu verwenden
und auch noch Platformübergreifend, dann hat man seinen Spass.
Die API ist wirklich nicht sonderlich gut gelungen.

Ansonsten gibt es immer ein paar ecken und Kanten an jeder Sprache.
Nur andauernd nach neuen Features zu rufen ist wirklich nicht immer die
Lösung aller Probleme. Hin und wieder ist auch einfach ein überdenken
des Lösungsansatzes schon hilfreich :)

peter
Thomas Thiele
2007-07-23 18:43:36 UTC
Permalink
Post by m***@heinerkuecker.de
Hast Du das hier schon mal gelesen ?
"Es gibt etliche Sprachen, die sich als Fortführung von C verstehen oder
die auf wesentlichen Schwächen von C aufbauen: C++, Java, C# usw. Diese
eignen sich allein aufgrund ihrer Syntax gut zum Hassen."
Lesen Sie weiter auf narkive:
Loading...