Ich überlege schon lange, wie man für Optional
, List
, Stream
u.s.w. eine typsichere DSL bauen kann, die insbesondere das gleichzeitige Hantieren mit mehreren dieser Objekte erleichtert. Dabei habe ich mich ein wenig an der do-Notation von Haskell orientiert. Inzwischen kann ich sowas schreiben:
Optional<Integer> a = ...
Optional<String> b = ...
Optional<Integer> result = Optionals.optionals()
.assign(a).toA()
.assign(b).toB()
.withA().andB().map((a, b) -> a + b.length()).toC()
.withC().map(c -> c*c).read();
Konzeptionell sind A,B,C “Slots”, in die ich Werte packen kann. Ein Slot kann auch typsicher mit einem neuen Wert eines anderen Typs überschrieben werden. Obwohl ich für die Unterstützung A…Z jeweils 26 Versionen von paar Methoden brauchen würde, habe ich wenigstens keine kombinatorische Explosion. Die Schachtelungstiefe mit “and” ist beschränkt, für jedes weitere wird jeweils eine neue Klasse fällig (und man bräuchte 3,4,5…wertige Funktionen). Natürlich sind mehr Methoden möglich, wie flatMap
, filter
, ifPresent
.
Die Fragen an euch sind: Ist das lesbar und nützlich? Oder ist das schon Overkill? Optional
ist hier natürlich nur ein Beispiel, so könnte man das Gleiche mit Stream
machen, und z.B. zip
u.s.w. anbieten.
Ich würde erst einmal über die DSL an sich diskutieren, bevor ich die Implementierung zeige (die recht einfach ist)