Patrick Roemer schrieb:
> Responding to Heiner Kücker:
> > Patrick Römer schrieb:
> >> Irgendwo musst Du doch eh mal kohaerent dokumentieren, wie eine
> >> Verwendung Deines Tools aussieht.
> Beim Text auf Deiner Einfuehrungsseite stellen sich mir Fragen wie:
> - Was soll eine Konvertierungsmethode sein?
Die Konvertierungsmethoden zur allgemeineren Constraint-Expression
werden automatisch generiert.
Zum Beispiel sind kompatibel
speziellere Expression: A and B
allgemeinere Expression: A
ANDB_A_B_ANDE#convertToAconstraint.
Voraussetzung ist die einfache Implikation:
(A and B) => A
(A and B) => B
Die Konvertierungsmethoden sind die Alternative zur Java-Typ-Kompatibilität
(kompatibel zur Oberklasse/Interface)
Die Java-Typ-Kompatibilität wird nicht genutzt,
weil sich dort kein Ausschluss absichern lässt
(man kann nur was erlauben, nichts verbieten)
Beispiele dafür finden sich im Package
_01_simple
> - Welcher Zwang, eine abstrakte Klasse zu implementieren?
Hier geht es um die Spezialisierung von Constraints.
Um ein Constraint zu spezialisieren muss eine
Switch-Definition vorgenommen werden.
Ein Beispiel dazu findet sich im Package
_05_switch
Anhand der Switch-Definition wird in der
generierten Constraint-Java-Klasse eine
nicht-statische innere Klasse generiert,
welche implementiert werden muss.
Eine abstrakte Klasse ist die einzige
Möglichkeit (die ich kenne) um in Java
die Implementierung jedes Zweiges per
Compiler abzusichern (im Gegensatz zum
Java-Switch oder if-else).
In Scala gibt es dafür sealed case Klassen
oder Option.
Die spezialisierenden Zweig-Expressions dürfen
sich in ihrer erfüllenden boolschen Belegung
(Model) nicht überlappen (müssen disjoint sein),
damit nicht ein zufällig vor einem anderen Zweig
geprüfter Zweig gewinnt.
Werden nicht alle erfüllenden boolschen Belegungen
des ursprünglichen Constraints von den Zweig-Expressions
abgedeckt, wird eine zu implementierende caseDefault-Methode
generiert.
> - Was meint er jetzt genau mit Range-Check?
Das Range-Check-beispiel befindet sich im Package
_12_int_range
Es basiert auf parametrisierbaren Prädikaten
zum Beispiel
new IntLesser ( 0 ) , // x < 0
new IntEqual ( 0 ) , // x == 0
new IntGreater( 0 ) // x > 0
Für die Feststellung der einfachen Implikation
verwende ich die erweiterte Funktionalität
der Includes, DynamicInclude
new IntLesser ( 0 ) => new IntLesser ( 1 )
(x < 0) => (x < 1)
Für die Feststellung des Ausschlusses (Kontradiktion)
verwende ich die erweiterte Funktionalität der
Excludes, DynamicExclude:
Das Symbol für den Exclude ist so ein eingekreistes Plus
(xor) welches ich hier nicht darstellen kann:
new IntLesser ( 0 ) excludes new IntGreater( 0 )
(x < 0) excludes (x> 0)
Eine Anwendung für dieses Feature habe ich nicht,
das sollte sich finden.
> - usw.
Ich freue mich, wenn Du noch ein paar Fragen stellst,
es liest eventuell noch jemand mit.
> > Der Leser will sicher erst mal wissen, was
> > die Motivation und der grobe Lösungsweg ist.
> Eben. Und das weiß ich nach dem Anlesen des Texts nicht.
Ich weiß jetzt auch nicht so genau,
wie ich es besser formulieren soll,
für den gemeinen Java-Programmierer
ist es sicher strange, für die Scala-
und Haskell-Welt eher langweilig.
> So ziemlich alle Projektseiten, die ich mir in der letzten Zeit
> angeschaut habe, hatten direkt einen "Getting Started"-Absatz oder einen
> prominenten Link auf eine entsprechende Seite. Und da war dann
> üblicherweise das von mir erwartete minimale, vollständige
> Anwendungsbeispiel zu finden.
Minimal und vollständig, die Quadratur des Kreises.
> Inzwischen bin ich mir recht sicher, nicht Zielgruppe für dieses
> Projekt zu sein, also kann es mir ja egal sein. Aber Du hattest nach
> Feedback gefragt, und das sind nun mal meine 2 Cent.
Vielen dank für das Feedback, es war bisher das einzige
außer das von dem professionellen Poster.
> > Etwas schwierig ist, wenn Du auf einmal schreibst,
> > Du meinst interne DSLs, die meist in dynamischen
> > Sprachen auftauchen, selten in Java (außer
> > Fluent-Interface oder Builder).
> Du hast DSLs als Beispiel dafuer erwaehnt, dass man Code schreibt, der
> direkt von generiertem Code abhaengt, und ich habe beschrieben, warum
> mir das sowohl für interne wie externe DSLs eher ungewöhnlich erschien.
Aha.
> > Einen kleinen Code-Generator kann man schon mal
> > verwenden, aber unerlaubt Scala im Projekt
> > einzuführen wird wahrscheinlich ein schnelles
> > Vertragsende bewirken.
> Du wirst lachen, aber für so enorm halte ich den Unterschied gar nicht:
> In beiden Fällen fuehre ich eine zusaetzliche Bibliothek und einen
> zusaetzlichen Buildschritt ein, einhergehend mit Code, den mir meine
> Kollegen als "vollkommen unleserlich" um die Ohren hauen wuerden. ;)
In so einem Projekt gibt es technische und fachliche Teamleiter
sowie eine verantwortlichen Kollegen für Build und versionierung.
Das tägliche Bauen erfolgt im Hudson.
Wie soll ich da subversiv (lustig SVN)
einen Scala-Compiler und die Bibliotheken
einschleusen.
Die fühlen sich schon auf den Schlips getreten,
wenn man im util-Package was fixt, ohne dafür
einen Tracker zu haben.
> In Deinem "simple"-Beispiel ist das Package "use"
> schon abhaengig von den generierten Constraints.
Das soll ja auch so sein, anders können
die Constraints auch gar nicht wirken.
> Aber wir müssen das nicht weiterfuehren.
Müssen wir nicht, ich danke Dir für die Hinweise.
Ich wollte aber nicht einfach Dein Posting
unbeantwortet lassen, das wirkt ignorant.
> Mein Tässchen Tee ist das Tool offenkundig nicht,
> und mein Feedback hast Du. Wenn es Dir geholfen hat,
> freut mich das, wenn wir uns nur einig sind, uns nicht einig zu
> sein, ist das auch nicht weiter schlimm.
Vielen Dank, es hat mir geholfen,
wir haben die Meinung oft genug getauscht,
so dass jeder die eigene zurück hat.