35 Conditionals
A conditional chooses between two result-producing expressions using a Boolean condition.
For example, this expression labels each course as advanced or introductory:
u.course.(
code,
(if advanced then "advanced" else "introductory") as level
)
The condition is advanced. If it is true for the current course, the result is
"advanced". Otherwise the result is "introductory".
Conditions can use path tails
The condition is an ordinary Boolean-valued expression, so it can use navigation, filters and folds:
u.course.(
code,
(if assessment.exam.Σexists then "exam" else "coursework")
as assessmentStyle
)
This labels a course as "exam" when it has at least one exam assessment, and
as "coursework" otherwise.
Branches can use path tails too
The then-branch and else-branch are also path expressions. The following expression uses a fold in the then-branch:
u.course.(
code,
(if advanced
then assessment.project.estimatedHours.Σsum
else 0)
as advancedProjectHours
)
For advanced courses, the result is the total estimated project hours. For other
courses, the result is 0.
Both branches produce one result
The producing branches must have a common result type. This works because both branches produce strings:
u.course.(
code,
(if session.time.day.Σcount > 2
then "spread out"
else "compact")
as timetableShape
)
A conditional exposes one result. The result name can be supplied with as on
the whole conditional expression.
Conditionals are not alternatives
Conditionals and alternatives are both expression-level branching constructs, but
they answer different questions. Use if then else when there is an explicit
Boolean condition. Use | when several branches may produce the same kind of
result.
u.course.assessment.(
(if exam.Σexists
then exam.maxMark
else (assignment.maxMark | project.maxMark))
as maxMark
)
This is legal, but it is not the clearest expression of the idea. The variant case is better written with alternatives:
u.course.assessment.(
(exam.maxMark | assignment.maxMark | project.maxMark)
as maxMark
)
The first version asks a Boolean question and then chooses a branch. The second version simply says which paths can produce the maximum mark.
Composability
Conditionals compose with the earlier path tails. The condition can filter, count or navigate. The branches can calculate, fold, use alternatives, or return constants.
u.course.(
code,
(if advanced ∧ assessment.project.Σexists
then assessment.project.estimatedHours.Σsum
else 0)
as projectHoursForAdvancedCourses
)
The expression reaches each course, checks a Boolean condition about that course, and then chooses the value to output. Each part is still a path expression.