Verfasst: Freitag 13. Februar 2009, 15:17
Ok, ehrlich gesagt habe ich nicht so viel Ahnung von Java. Ich habe mir nur das System mit den Types und Subtypes kurz angesehen, das vermutlich von Ada stammt. Wie viel davon übernommen wurde und in wie weit man das in Java anwendet, weiß ich allerdings nicht.
Wenn ich in Ada arbeite, weiß ich aber, dass das Typsystem durchaus viel verwendet wird. es steht praktisch nur insofern im Weg, dass man für gewöhnlich einen längeren Code hat.
Nehmen wir mal als Beispiel einen Quaderförmigen Wassertank. Mich interessieren die Seitenlängen und das Fassungsvolumen. Für beides werden beispielsweise gleichartige Fixed-Point-Typen gespeichert. Gleichartig bedeutet normalerweise, dass sie voll kompatibel sind, weil sie die gleichen Eigenschaften besitzen. In Ada allerdings nicht, so dass ich eine Seitenlänge nicht dem Volumen zuweisen kann, was ja auch ein logischer Fehler wäre. Wenn ich aber über die Seitenlängen das Volumen ausrechnen will, kann ich Casten. Du hast also einen Schutz und wenn du den umgehen willst, ist das mit zusätzlichem Code möglich. Du hast aber auf dem ersten Blick sofort die Typen vor dir. Durch die Typen kannst du verschiedene Variablen also logisch voneinander trennen, auch wenn ihre Typen gleiche Eigenschaften besitzen.
Genauso wie die Subranges.
Zum einen ist das eine Sache der Portabilität. Wenn ich auf einem System arbeite, dass mit 16- und 32-Bit-Typen arbeitet und ich eine Zahl brauche, die ganzzahlige Werte von 1 bis 10 speichert, gebe ich dem Compiler diese gewünschten Eigenschaften an. Der Compiler wird daraus einen 16bit-Integer machen. Das ist der kleinste mögliche Typ, der das System voll ausnutzt und alle Eigenschaften bietet, die ich verlange. In einer Sprache mit weniger umfangreichem Typsystem müsste ich selbst einen 16-Bit-Integer verlangen. Wenn ich den Code auf ein System kompiliere, dass nur mit 8 bit, oder nur mit 32 und 64 Bit normal umgehen kann, habe ich ein Problem. Bei Ada wählt der Compiler aber auch hier einen passenden Wert aus. Bei dynamisch typisierten Sprachen wird natürlich ohnehin etwas passendes vom Interpreter verwendet...
Aber auch hier kann man logisch trennen. Wenn ich eine Variable habe, dessen Wertebereich ich zwischen 1 und 100 definiere, weil andere Werte nicht benötigt werden, kann ich einen Fehler in einem anderen Bereich des Systems eventuell dadurch erkennen, dass diese Variable "unlogische" Werte annimmt. Manuelle Rangechecks sind nicht mehr nötig. Nehme ich die obige Wanne wieder und erstelle mir einen anonymen Subtyp, der "Inhalt in Litern" von 0.00 bis 100.00 annimmt, weil in die Wanne nunmal nur 100 Liter reinpassen und alles andere überlaufen würde, diese Wanne auch nicht "leerer als leer" sein kann, habe ich mir sofort die nötige Umgebung geschaffen um auf bestimmte Aktionen logisch reagieren zu können. Man kann sich dadurch zwar auch unnötig vertun (dieses Feature war Schuld am Absturz der Ariane 5 beim Erstflug - man hat Code einfach ungetestet aus der Ariane 4 übernommen und eine "logische Beschränkung des Wertebereichs" hängt natürlich von der Umgebung ab, die sich hier geändert hat), aber im Prinzip bleibt es einfach ein Werkzeug und auch bei manuellen Wertebereichsprüfungen (die man dann übrigens erstmal im Code einzeln suchen muss, was viel Fehlerträchtiger ist...) wäre das passiert.
Wenn ich einen Typ vom anderen ableite kann ich mir auch aussuchen, ob die Typen zueinander kompatibel sein sollen, und in welchem Umfang Operationen auf diesem Typ übernommen oder angepasst werden sollen.
Dass sich der Code aufbläht, wenn man jede einzelne Variable deklarieren muss und sich für alles eigene Typen definiert, für die man dann vermutlich noch generische Pakete instanzieren muss, ist natürlich klar... Es zwingt einem aber niemand dazu. Man kann gerne durch die Bank weg mit den Standardtypen arbeiten. Es wird aber in der Regel nicht gemacht und das hat seinen Grund.
In Python versucht man dem Programmierer Arbeit abzunehmen. Dadurch nimmt man ihm erstmal auch bestimmte Werkzeuge, aber wenn man sich daran gewöhnt, vermisst man diese Werkzeuge auch nicht und freut sich stattdessen über die abgenommene Arbeit. Dass ein und das selbe Programm in Python sehr viel kürzer ausgedrückt werden kann, ist ja kein Geheimnis.
Wenn ich in Ada arbeite, weiß ich aber, dass das Typsystem durchaus viel verwendet wird. es steht praktisch nur insofern im Weg, dass man für gewöhnlich einen längeren Code hat.
Nehmen wir mal als Beispiel einen Quaderförmigen Wassertank. Mich interessieren die Seitenlängen und das Fassungsvolumen. Für beides werden beispielsweise gleichartige Fixed-Point-Typen gespeichert. Gleichartig bedeutet normalerweise, dass sie voll kompatibel sind, weil sie die gleichen Eigenschaften besitzen. In Ada allerdings nicht, so dass ich eine Seitenlänge nicht dem Volumen zuweisen kann, was ja auch ein logischer Fehler wäre. Wenn ich aber über die Seitenlängen das Volumen ausrechnen will, kann ich Casten. Du hast also einen Schutz und wenn du den umgehen willst, ist das mit zusätzlichem Code möglich. Du hast aber auf dem ersten Blick sofort die Typen vor dir. Durch die Typen kannst du verschiedene Variablen also logisch voneinander trennen, auch wenn ihre Typen gleiche Eigenschaften besitzen.
Genauso wie die Subranges.
Zum einen ist das eine Sache der Portabilität. Wenn ich auf einem System arbeite, dass mit 16- und 32-Bit-Typen arbeitet und ich eine Zahl brauche, die ganzzahlige Werte von 1 bis 10 speichert, gebe ich dem Compiler diese gewünschten Eigenschaften an. Der Compiler wird daraus einen 16bit-Integer machen. Das ist der kleinste mögliche Typ, der das System voll ausnutzt und alle Eigenschaften bietet, die ich verlange. In einer Sprache mit weniger umfangreichem Typsystem müsste ich selbst einen 16-Bit-Integer verlangen. Wenn ich den Code auf ein System kompiliere, dass nur mit 8 bit, oder nur mit 32 und 64 Bit normal umgehen kann, habe ich ein Problem. Bei Ada wählt der Compiler aber auch hier einen passenden Wert aus. Bei dynamisch typisierten Sprachen wird natürlich ohnehin etwas passendes vom Interpreter verwendet...
Aber auch hier kann man logisch trennen. Wenn ich eine Variable habe, dessen Wertebereich ich zwischen 1 und 100 definiere, weil andere Werte nicht benötigt werden, kann ich einen Fehler in einem anderen Bereich des Systems eventuell dadurch erkennen, dass diese Variable "unlogische" Werte annimmt. Manuelle Rangechecks sind nicht mehr nötig. Nehme ich die obige Wanne wieder und erstelle mir einen anonymen Subtyp, der "Inhalt in Litern" von 0.00 bis 100.00 annimmt, weil in die Wanne nunmal nur 100 Liter reinpassen und alles andere überlaufen würde, diese Wanne auch nicht "leerer als leer" sein kann, habe ich mir sofort die nötige Umgebung geschaffen um auf bestimmte Aktionen logisch reagieren zu können. Man kann sich dadurch zwar auch unnötig vertun (dieses Feature war Schuld am Absturz der Ariane 5 beim Erstflug - man hat Code einfach ungetestet aus der Ariane 4 übernommen und eine "logische Beschränkung des Wertebereichs" hängt natürlich von der Umgebung ab, die sich hier geändert hat), aber im Prinzip bleibt es einfach ein Werkzeug und auch bei manuellen Wertebereichsprüfungen (die man dann übrigens erstmal im Code einzeln suchen muss, was viel Fehlerträchtiger ist...) wäre das passiert.
Wenn ich einen Typ vom anderen ableite kann ich mir auch aussuchen, ob die Typen zueinander kompatibel sein sollen, und in welchem Umfang Operationen auf diesem Typ übernommen oder angepasst werden sollen.
Dass sich der Code aufbläht, wenn man jede einzelne Variable deklarieren muss und sich für alles eigene Typen definiert, für die man dann vermutlich noch generische Pakete instanzieren muss, ist natürlich klar... Es zwingt einem aber niemand dazu. Man kann gerne durch die Bank weg mit den Standardtypen arbeiten. Es wird aber in der Regel nicht gemacht und das hat seinen Grund.
In Python versucht man dem Programmierer Arbeit abzunehmen. Dadurch nimmt man ihm erstmal auch bestimmte Werkzeuge, aber wenn man sich daran gewöhnt, vermisst man diese Werkzeuge auch nicht und freut sich stattdessen über die abgenommene Arbeit. Dass ein und das selbe Programm in Python sehr viel kürzer ausgedrückt werden kann, ist ja kein Geheimnis.