Pen & Paper - Rollenspiel > Werkstatt

Covella - Fantasy-Kalender - DSL für beliebige Systeme von Zeitmessung

<< < (11/17) > >>

1of3:
Das hat wenig mit Scala oder Java zu tun. Die Frage ist, wie die Funktionen geschrieben sind. ;)

Du hast allerdings nicht unrecht, ich hatte nur vier Extratage, also hieße es dann:


--- Code: ---val standardYear = (quartal *4 + Days(1) as "extra day") as "year"
val leapYear = (quartal * 4  + Days(1) as "extra day" + Days(1) as "leap day" ) as "year"
--- Ende Code ---

Zur Erklärung: Das "as" fasst was davor kommt zu einer Zeiteinheit zusammen mit dem folgenden Bezeichner zusammen. Was die Operatoren tun, hängt davon ab, ob zwischendurch ein "as" fällt. Dadurch wird also gesteuert, was "+" tut.

Zur Verdeutlichung bezeichne ich nicht ausgezeichnete Einheiten mit Großbuchstaben (A, B, C),  ausgezeichnete - d.h. solche, die "as" bekommen haben - mit Großbuchstaben und Apostroph (A', B', C').

Es gilt: A' + B' => (A', B'). D.h. die Summe zweier ausgezeichneter Einheiten ist ein Compound, das sie enthält.
Wenn man nun ein Compound hat und addiert noch ein ausgezeichnetes Element, was soll passieren? - Das drite Element soll mit in die Klammer:
(A', B') + C' => (A', B', C').

Wenn man jetzt zwischendurch wieder "as" schreibt, passiert folgendes: (A', B')'. Das zusammengesetzte Element ist also ausgezichnet und damit abgeschlossen. (Intern ändert "as" den Datentyp.) Wenn man jetzt auf diesem ausgezeichneten Element etwas addiert, ist das Ergebnis anders: (A', B')' + C' => ( (A', B')', C' ). Es hat also ein weiteres Level erzeugt.

Skeeve:

--- Zitat von: 1of3 am 16.10.2016 | 10:31 ---Das hat wenig mit Scala oder Java zu tun. Die Frage ist, wie die Funktionen geschrieben sind. ;)

--- Ende Zitat ---

Naja, um die Funktionien zu verstehen... hätte es auch eine andere Uhrzeit sein müssen. Aber nun macht sich hier auch langsam die Erkenntnis breit dass "as" und "named" gar keine Elemente von Java oder Scala sind, sondern selbstgemachte Methoden einer abstrakten Klasse (oder doch Funktionen?)

Aber mein Erkenntnissgewinn ist hier ja nicht Thema, also weiter machen....  ;)

1of3:
Och, ich erklär das gern. Aber du hast recht. Dass man diesen Unterschied nicht sofort erkennt, ist eine Eigenschaft von DSL-freundlichen Sprachen: Keine Semikola, Funktionsaufrufe brauchen keine Klammern, Zugriff auf Eigenschaften und Methoden brauchen keine Punkte. Das gleiche könnte man wohl auch in Groovy und einigen anderen modernen Sprachen machen. Und ja, es sind Instanz-Methoden, Scala kann keine Toplevel-Funktionen und statische Methoden werden durch Methoden auf Singletons ersetzt.

Aber kommen wir mal zurück:

Ich würde für Konvenienz neben Days auch direkt Month einführen.

Month(int) - gib mir einen Monat mit int Tagen.
Month(int,String) - gib mir einen Monat mit int Tagen und Namen String.

Wir sollten auch die typischen Bezeichnungen für Tag, Woche, Monat, Jahr direkt als internationalisierten String einfügen. Dann kann sich die Kundschaft für typische Fälle die Anführungszeichen sparen. Internationalisierte Strings gibts mit der Bibliothek Rapture wohl recht komfortabel, hab ich aber noch nicht ausprobiert.


Zum Format:

Das könnten wir mit einem handgemachten Stringkontext machen. Das sähe bei der Verwendung dann z.B. so aus:


--- Code: ---date"""$number(day). $name(month) $number(year)"""
--- Ende Code ---

Wenn man in den Aufrufen keine Anführungszeichen verwendet, kann man zur Berandung auch einmal, statt dreimal die Anführungszeichen machen. Hinter den Kulissen wird ein String mit einem solchen Präfix wie date als StringContext behandelt und der Compiler sucht dann eine Methode namens date.

Die Methode sollte dann ein DateFormat zurückgeben, das hat:
- eine Methode "to" um ein Datum zum String zu machen.
- eine PartialFunction "from" um aus einem String ein Datum zu machen.

Der Kalender hält eine Liste mit DateFormats vor. Wenn der User dann einen String parsen will, werden alle partiellen Funktionen durchlaufen, ob eine passt.

Skeeve:

--- Zitat von: 1of3 am 16.10.2016 | 21:12 ---Dass man diesen Unterschied nicht sofort erkennt, ist eine Eigenschaft von DSL-freundlichen Sprachen: Keine Semikola, Funktionsaufrufe brauchen keine Klammern, Zugriff auf Eigenschaften und Methoden brauchen keine Punkte.

--- Ende Zitat ---

Ja! Man kann Python zwar recht großzügig umbauen und verbiegen , aber ganz so frei wie bei Scala wird man es wohl nicht hinbekommen...
Aber ich habe gerade ein Beispiel entdeckt. Ich glaube aus
--- Code: ---val leapYear = (quartal * 4  + Days(1) as "extra day" + Days(1) as "leap day" ) as "year"
--- Ende Code ---
könnte man z.B.
--- Code: ---leapYear = (quartal * 4  + Days(1) |as| "extra day" + Days(1) |as| "leap day" ) |as| "year"
--- Ende Code ---
machen und das wäre ein gültiger Python-Ausdruck den man durch den Python-Parser jagen könnte und bei passender Metaprogrammierung würde das Teil dann auch das gewünschte machen.
Oder man baut sich seinen eigenen speziell an die neue Sprache angepassten Parser. Das geht fast immer,  aber ob man den Aufwand treiben möchte.

1of3:
Mir sind noch ein paar Fragen zur Benutzung gekommen:

Bei einigen Zeiteinheiten fangen wir beim Zählen bei Null an. Es kann z.B. "0 Uhr 5 Minuten" sein. Aber egal, ob die Woche bei Sonntag oder Montag anfängt, es ist der erste Tag. Ebenso haben wir keinen nullten Tag im Monat und keinen nullten Monat im Jahr.

Wenn jetzt also jemand Datum#get(month) bzw. Datum#get(hour) sagt, erwartet er da ggf. unterschiedliche Ergebnisse. Jetzt gibts zwei Möglichkeiten: Entweder in der Dokumentation steht: "Die Rückgaben fangen bei 0 an zu zählen, achte drauf ggf. was draufzuaddieren, wenn du das Ergebnis benutzt!", oder wir erweitern das Modell, das man das Verhalten einstellen kann. Auch dann fragt sich, was der Standard sein soll, wenn man nichts einstellt: 0 oder 1?

Was findet denn die geneigte Userschaft sinnvoller?



Damit verwandt: Wir sagen zwar, dass wir unsere Jahre zählen, aber wir zählen sie nicht so, wir wir alles andere Zählen. Ein Jahr 0 gibts nicht und die davor sind auch nicht negativ. An dieser Stelle würde ich aber so rigoros sein und zu sagen: Das sind keine Zahlen. Das sind Jahresnamen. Das Jahr heißt "1980 n. Chr." bzw. "43 v. Chr." oder wie mans gern mag. Wer an der Stelle also get(year) statt getName(year) abfragt, bekommt nicht das gewünschte.

Navigation

[0] Themen-Index

[#] Nächste Seite

[*] Vorherige Sete

Zur normalen Ansicht wechseln