Control Flow
DXL biedt verschillende constructies voor conditionele logica en het hergebruiken van waarden.
If-then-else
De basis voor conditionele waarden.
Syntax
if conditie then waarde_als_waar else waarde_als_onwaar
Voorbeelden
// Eenvoudige conditie
if status == "done" then "Afgerond" else "Bezig"
// Numerieke vergelijking
if budget > 10000 then "Groot" else "Klein"
// Met berekening
if progress >= 100 then 100 else progress
// Geneste if
if score >= 90 then "A"
else if score >= 80 then "B"
else if score >= 70 then "C"
else "D"
Met blokken
Voor complexere expressies kun je blokken gebruiken:
if conditie {
waarde_als_waar
} else {
waarde_als_onwaar
}
if @actions.count() > 0 {
@actions[status == "done"].count() / @actions.count() * 100
} else {
0
}
Else-if ketens
if score >= 90 {
"Uitstekend"
} else if score >= 70 {
"Goed"
} else if score >= 50 {
"Voldoende"
} else {
"Onvoldoende"
}
Match expressies
Pattern matching voor complexe condities.
Basis syntax
match waarde {
patroon1 => resultaat1,
patroon2 => resultaat2,
_ => default_resultaat
}
Op exacte waarden
match status {
"done" => "Afgerond",
"inprogress" => "Bezig",
"todo" => "Te doen",
"blocked" => "Geblokkeerd",
_ => "Onbekend"
}
match priority {
1 => "Urgent",
2 => "Hoog",
3 => "Normaal",
4 => "Laag",
_ => "Niet ingesteld"
}
Op ranges (bereiken)
Ranges zijn inclusief aan de start, exclusief aan het einde: start..end matcht waarden waar start <= waarde < end.
match score {
0..50 => "Onvoldoende",
50..70 => "Voldoende",
70..90 => "Goed",
90..101 => "Uitstekend",
_ => "Ongeldig"
}
match days_remaining {
0..1 => "Vandaag!",
1..8 => "Deze week",
8..31 => "Deze maand",
_ => "Later"
}
Of-patronen
Combineer meerdere waarden met |:
match status {
"done" | "completed" | "finished" => "Afgerond",
"todo" | "open" | "new" => "Nieuw",
_ => "Anders"
}
match weekday {
1 | 2 | 3 | 4 | 5 => "Werkdag",
6 | 7 => "Weekend",
_ => "Ongeldig"
}
Met guards
Voeg extra condities toe aan een patroon:
match status {
"done" if budget > 10000 => "Groot project afgerond",
"done" => "Project afgerond",
"inprogress" if due_date < today => "Achterstand!",
"inprogress" => "Bezig",
_ => "Anders"
}
Wildcard
De _ (underscore) matcht elke waarde en wordt gebruikt als default:
match category {
"A" => 100,
"B" => 75,
"C" => 50,
_ => 0 // Alle andere waarden
}
Een match-expressie moet alle mogelijke waarden dekken. Gebruik altijd een _ wildcard als laatste arm om dit te garanderen.
Let bindings
Wijs een waarde toe aan een variabele voor hergebruik.
Syntax
let naam = waarde; expressie_die_naam_gebruikt
Basisgebruik
let total = @actions.count();
let done = @actions[status == "done"].count();
done / total * 100
Meerdere bindings
let budget = @actions.budget.sum();
let spent = @actions.actual_cost.sum();
let remaining = budget - spent;
"Budget: " + budget + ", Besteed: " + spent + ", Over: " + remaining
Complexe berekeningen opsplitsen
let actions = @actions;
let total = actions.count();
let done = actions[status == "done"].count();
let progress = actions[status == "inprogress"].count();
let blocked = actions[status == "blocked"].count();
if total == 0 then "Geen acties"
else if blocked > 0 then "Geblokkeerd (" + blocked + " acties)"
else if done == total then "Volledig afgerond"
else done + "/" + total + " (" + (done / total * 100).round() + "%)"
Standalone let
Een let zonder volgende expressie retourneert de toegewezen waarde:
let x = 42
// Retourneert 42
Dit is vooral nuttig in interactieve contexten (REPL).
Null handling
Null coalesce (??)
Geef een default waarde als de linkerkant null is:
budget ?? 0 // 0 als budget null is
name ?? "Naamloos" // "Naamloos" als name null is
Safe navigation (?.)
Retourneert null als de linkerkant null is:
owner?.name // null als owner null is
Combineren
owner?.name ?? "Niet toegewezen"
In condities
if budget != null then budget else 0
// Of korter:
budget ?? 0
Combineren van constructies
If met let
let total = @actions.count();
if total == 0 then 0
else @actions[status == "done"].count() / total * 100
Match met dimensiewaarden
Match op entiteiten met slugs (vergelijking op GUID):
match @dim:kans {
zeer_laag | laag => "Laag risico",
gemiddeld => "Gemiddeld risico",
hoog | zeer_hoog => "Hoog risico",
_ => "Onbekend"
}
Match met relatie-lookups
Match op entiteiten met de @type[slug] syntax:
// Match een gekoppelde succesbepalende factor
match @results[omzet].succesbepalende_factor {
@succesbepalende_factor[klantgerichtheid] => "Focus op klant",
@succesbepalende_factor[innovatie] => "Innovatief",
_ => "Overig"
}
Vergelijken met slugs
if @dim:kans == hoog || @dim:kans == zeer_hoog then "Hoog risico"
else if @dim:kans == gemiddeld then "Gemiddeld risico"
else "Laag risico"
Best practices
1. Gebruik let voor hergebruik
// Slecht: berekening wordt twee keer uitgevoerd
@actions.count() > 0 && @actions[status == "done"].count() / @actions.count() > 0.5
// Goed: één keer berekenen
let total = @actions.count();
total > 0 && @actions[status == "done"].count() / total > 0.5
2. Bescherm tegen deling door nul
// Slecht: kan fout geven
done / total * 100
// Goed: check eerst
let total = @actions.count();
if total == 0 then 0 else @actions[status == "done"].count() / total * 100
3. Gebruik null coalesce voor optionele velden
// Slecht: kan null retourneren
budget
// Goed: default waarde
budget ?? 0
4. Gebruik match voor meerdere cases
// Slecht: geneste if-else
if status == "done" then "Groen"
else if status == "inprogress" then "Oranje"
else if status == "blocked" then "Rood"
else "Grijs"
// Goed: match
match status {
"done" => "Groen",
"inprogress" => "Oranje",
"blocked" => "Rood",
_ => "Grijs"
}
5. Geef complexe expressies betekenisvolle namen
// Minder leesbaar
if @actions[status == "done"].count() / @actions.count() * 100 >= 80 then "Op schema" else "Achterstand"
// Leesbaarder
let completion_pct = @actions[status == "done"].count() / @actions.count() * 100;
if completion_pct >= 80 then "Op schema" else "Achterstand"