Achtung, Achtung, Achtung, Sondermeldung: Java hat bereits Union Typen eingebaut

22/03/2014 - 17:22 von Heiner Kücker | Report spam
Dies ist ein ergànzender Thread zu dem
anderen Dialog mit Patrick Roemer.
Dort melde ich mich aber auch noch mal.

Ihr werdet es nicht glauben, Java hat
bereits Union Typen eingebaut, und
zwar von Anfang an.

Nur leider nicht korrekt umgesetzt.

Irgendwie kam mir das komisch vor,
bei Nice, Kotlin und Ceylon spricht
man von nullable types.

Null als Type, also in Java eine Klasse?
(Ich meine dabei Java bis Version 5,
wo es noch keine Generics gab)

Naja, es gibt in Java noch primitive
Typen, aber die sind keine Objekte.

Nehmen wir mal an es wàre so, dass Null
ein Typ/Klasse wàre, für manchen ist das
eventuell selbstverstàndlich, in meinen
Java-Büchern stand nichts davon und
Informatik habe ich nicht studiert.

native final class Null {
public static final Null null ...nativer Kram...;
}

Der Modifier nativ soll bedeuten, diese Klasse
ist bereits im Lieferumfang enthalten und
selbst kann man so was nicht anlegen.

Der Modifer final bedeutet, erben kannste
davon auch nicht.

Es gibt nur eine Singleton-Instanz,
die heisst null.

Im rechten Teil der Deklaration der
null-Instanz, der Zuweisung, steht
irgendwas natives, mit Java kannste
da nix machen.


Wie sieht das in der Maschine (JVM, CPU) aus?:

Jedes Objekt hat entweder eine Nummer (Handle)
oder in einer Referenz zeigt man auf eine
Speicheradresse.

Wenn es eine Nummer ist, dann gibt es für null
sicher eine magische Nummer wie 0 oder -1.

Wenn es eine Speicheradresse ist, dann
wahrscheinlich eine reservierte (magische)
Adresse.

Eventuell hat das null-Objekt auch eine
Information über seine Klasse Null oder
dies ist als Sonderbehandlung in der JVM
eingebaut.


Methoden und Member hat die Null-Klasse
nicht.

Aber man Operatoren darauf anwenden.

Vergleichs-Operator

x == null

x != null

wobei der zweite Term eigentlich eine
Abkürzung für

! ( x == null )

ist.

Plus geht auch:

null + "ein String"

Das ist aber nur wegen der Java-Sonderlocke
der eingebauten(implziten) Typ-Umwandlung
in der String-Konkatenation möglich.

Heh, implicits gibts auch schon,
das werde ich den Scala-Fans mal
um die Ohren hauen :)

Wir haben jetzt unsere Null-Klasse
mit Singleton-Instanz.

Programmieren wir mal ein bisschen
los:

String str = null;

Heh, das dürfte in unserer gedachten
Sprache nicht kompilieren.

null ist kein String.

Aha, in Java ist jede Objekt-Referenz
eigentlich eine Referenz auf einen
Union-Type.

Union-Typen gibt es in Ceylon,
ein Objekt kann eine von mehreren Klassen
haben.

http://ceylon-lang.org/documentatio...nion_types
http://java.dzone.com/articles/top-...n-language

Aus Mengen-Sicht entspricht ein Union-Type
der Vereinigungsmenge, meist grafisch als
voll ausgemalte liegende Acht dargestellt.

http://de.wikipedia.org/wiki/Menge_(Mathematik)#Vereinigung_.28Vereinigungsmenge.29

Ich schreibe es mal mit dem Pipe-Zeichen,
das meist für ODER steht, wobei ODER das
aussagenlogische Äquivalent zur
Vereinigungsmenge ist.

Die Notation mit dem Fragezeichen am Ende
wàre wahrscheinlich auch ok, aber der
Aspekt des Union-Type wàre nicht so
deutlich.

final String|Null str = null;

if ( str instanceof Null ) {
System.out.println( "null" );
{
else {
System.out.println( str.toString() );
}

An der if-Verzweigung sehen wir,
dass es beim Aufrufen von Methoden
oder beim Zugriff auf Member des
Objektes sicher sein muss, welchen
Typ es hat.

Unsere imaginàre Sprache müsste
dies also erzwingen.

Leider können wir es in Java nicht
so hinschreiben.

Ausserdem zwingt uns Java nicht,
den Typ festzustellen, sondern
erlaubt uns auf dem eingebauten
Irgendwas-Null-Union-Type den
Aufruf von Methoden und den
Zugriff auf Member.

Falls das Objekt vom Typ/Klasse Null
ist, wird eine NullPointerException
geworfen.

Das ist nicht so ganz korrekt,
besser wàre vielleicht eine
ClassCastException, weil man
ein Objekt vom Type Null nicht
nach String casten kann.

Da Nice, Kotlin und Ceylon den Null-Type
besser behandeln als Java, scheint der
komische Irgendwas-Null-Union-Type kein
Problem der JVM, sondern eines der Sprache
Java zu sein.

Erste Frage:
Wie löst man das in Scala?

Kann ich schreiben?:

val str:String = null

Ich habe kein Scala auf meinem Rechner
und kann es deshalb nicht selbst
ausprobieren.

Zweite Frage:
Was meint Ihr dazu?
(Ist das alles Unsinn?)
(Bin ich ein Spàtmerker?)

Grüße
Heiner Kücker
 

Lesen sie die antworten

#1 Patrick Roemer
22/03/2014 - 21:41 | Warnen spam
Responding to Heiner Kücker:
Ihr werdet es nicht glauben, Java hat
bereits Union Typen eingebaut, und
zwar von Anfang an.



Ich bin nun wirklich nicht fit in Typentheorie, aber meinem Verstaendnis
nach bedeutet Unterstuetzung von union types, dass das Typsystem eine
Verknuepfung von Typen zulaesst, die analog zur logischen Disjunktion
ist - IOW, das ist eher sowas wie eine Algebra ueber den Typen.

Du siehst ein Phaenomen (null), das man auf Basis von union types
implementieren koennte. Daraus kann man aber kaum ableiten, dass die
Sprache union types unterstuetzt.

Null als Type, also in Java eine Klasse?



Typ, aber keine Klasse. JLS §4.1.

[...]
null + "ein String"

Das ist aber nur wegen der Java-Sonderlocke
der eingebauten(implziten) Typ-Umwandlung
in der String-Konkatenation möglich.

Heh, implicits gibts auch schon,
das werde ich den Scala-Fans mal
um die Ohren hauen :)



Mach mal, wird sicher lustig. :)

Dasselbe Problem wie oben. Man koennte das, was hochspezialisiert in die
Sprache reingepfriemelt wurde, mit implicits nachempfinden. Die
Schlussfolgerung, dass es dann wohl implicits in der Sprache gibt, ist
falsch.

Wie löst man das in Scala?

Kann ich schreiben?:

val str:String = null



Ja - wobei es null in Scala eigentlich nur aus Gruenden der
Java-Interoperabilitaet gibt. Und diese Entscheidung bringt, wie in
Java, Sonderbehandlungen mit sich, die sich quer durch die ganze
Sprachspezifikation ziehen. :/

Anders als in Java, wo der null type mehr oder minder unsichtbar ist,
gibt es einen expliziten Null trait. Genau wie in Java wird die
Einbettung ins Typsystem so geloest, dass null ein zusaetzlicher Wert im
Wertebereich aller Referenztypen ist(JLS §4.12.2), und dass alle
Referenztypen Supertypen des null type sind (JLS §4.10.2) - wobei
letzteres Dich jetzt wahrscheinlich zur Sondereilmeldung "Java hat
Mehrfachvererbung!!1!" veranlassen wird. ;)

Diese Art der Einbettung hat mit union types nichts zu tun: Es gibt,
auch implizit, keinen Typ, der "T|Null" entspricht.

Viele Gruesse,
Patrick

Ähnliche fragen