Zum Inhalt springen

Logik & Verzweigung

Steuerregeln sind Fallunterscheidungen: Zonen, Schwellen, Sonderfälle. FinDSL drückt sie mit wähle, wenn und abbruch aus — alles Ausdrücke, die einen Wert liefern.

Die häufigste Form: mehrere Bedingungen, der erste passende Zweig gewinnt. sonst ist Pflicht (Vollständigkeitsgarantie):

@Quelle("§ 32a Absatz 1 EStG")
fn EstGrundtarif(zve: Euro): Euro = wähle {
falls zve < 0 als Euro -> abbruch("zvE darf nicht negativ sein")
falls zve < GFB + 1 -> 0
falls zve < ZONE_2_OBERGRENZE + 1 -> {
var y: Dezimal = (zve - GFB) / ZEHNTAUSEND
((ZONE_2_PROGRESSION * y + ZONE_2_LINEAR) * y).abrunden() als Euro
}
sonst -> (ZONE_5_SATZ * zve - ZONE_5_ABZUG).abrunden()
}

Ein Zweig kann ein einzelner Ausdruck oder ein Block { … } mit Zwischenwerten (var) sein — der letzte Ausdruck im Block ist das Ergebnis.

Vergleicht ein Subjekt (oft eine Aufzählung) mit Mustern. Decken die Muster alle Werte ab, ist sonst optional — der Compiler prüft die Vollständigkeit:

fn Kinderfreibetrag(stkl: Steuerklasse, zkf: EuroCent): Euro = wähle (stkl) {
falls I, II -> 0
falls III -> (zkf * KFB_SATZ_III).abrunden()
falls IV, V, VI -> (zkf * KFB_SATZ_IV_VI).abrunden()
}

Für genau zwei Zweige. Die Klammern um die Bedingung sind Pflicht, beide Zweige müssen denselben Typ haben:

wenn (stkl == I)
0
sonst
ANP_REGEL

abbruch("Begründung") bricht die Berechnung mit einer Begründung ab — für Eingaben, die das Gesetz nicht zulässt. Im Typsystem hat abbruch den Bottom-Typ never und passt damit in jeden Zweig:

falls zve < 0 als Euro -> abbruch("zvE darf nicht negativ sein")

Den Ablehnungspfad testet man positiv mit erwartet abbruch (siehe Prüfen).