I would love to see that Kotlin would support the step-down rule in a bigger way…
The way I defined is most probably not the best way, so other options would be great.
Explicit:
fun highLevel0() = midLevel1() // not allowed, method not defined in StepDown
fun highLevel1() = midLevel1() //allowed
fun highLevel2() = lowLevel() //not allowed, move lowLevel up one level
@StepDown[highLevel1, highLevel2]{
fun midLevel1() = ...
@StepDown[midLevel1]{
fun lowLevel() = ...
}
}
My code
fun createResponse(selectedList: List<String>, include: Boolean, unselectedList: List<String>){
listOf(
selectedList.toSimpleResponse(positive = include),
ListResponse(
"Other brands",
unselectedList.associateWith { ListItem(it) }
),
Suggestion(listOf("no"))
)
}
@StepDown[createResponse]{
private fun List<String>.toSimpleResponse(positive: Boolean) = SimpleResponse(when{
this.isEmpty() -> emptyResponseText()
positive -> positiveResponseText(this)
else -> negativeResponseText(this)
})
@StepDown[toSimpleResponse]{
private fun emptyResponseText() = questions.random()
@StepDown[emptyResponseText]{
private val questions = listOf(
"Do you want to filter on brand?",
"Are there brands you are only interested in?"
)
}
private fun positiveResponseText(selectedList: List<String>) = "According to the current filter, you only want to see"+when {
selectedList.size == 1 -> "${selectedList.first()}."
else -> " the brands ${selectedList.toReadableString()}."
}+" Do you want to see more brands?"
private fun negativeResponseText(selectedList: List<String>)= "According to the current filter, you don't want to see "+when {
selectedList.size == 1 -> "${selectedList.first()}."
else -> "the brands ${selectedList.toReadableString()}."
} + "Do you want to exclude more brands?"
@StepDown[positiveResponseText, negativeResponseText]{
fun List<String>.toReadableString() = dropLast(1).joinToString() + " and " + last()
}
}
}
or just add stepDown:
fun highLevel1() = midLevel1() //allowed
fun highLevel2() = lowLevel() //not allowed, move lowLevel up one level
stepDown {
fun midLevel1() = ...
stepDown {
fun lowLevel() = ...
}
}
fun highLevel0() = midLevel1() // not allowed, move method above stepdown
My code
fun createResponse(selectedList: List<String>, include: Boolean, unselectedList: List<String>){
listOf(
selectedList.toSimpleResponse(positive = include),
ListResponse(
"Other brands",
unselectedList.associateWith { ListItem(it) }
),
Suggestion(listOf("no"))
)
}
stepDown {
private fun List<String>.toSimpleResponse(positive: Boolean) = SimpleResponse(when{
this.isEmpty() -> emptyResponseText()
positive -> positiveResponseText(this)
else -> negativeResponseText(this)
})
stepDown {
private fun emptyResponseText() = questions.random()
StepDown {
private val questions = listOf(
"Do you want to filter on brand?",
"Are there brands you are only interested in?"
)
}
private fun positiveResponseText(selectedList: List<String>) = "According to the current filter, you only want to see"+when {
selectedList.size == 1 -> "${selectedList.first()}."
else -> " the brands ${selectedList.toReadableString()}."
}+" Do you want to see more brands?"
private fun negativeResponseText(selectedList: List<String>)= "According to the current filter, you don't want to see "+when {
selectedList.size == 1 -> "${selectedList.first()}."
else -> "the brands ${selectedList.toReadableString()}."
} + "Do you want to exclude more brands?"
stepDown {
fun List<String>.toReadableString() = dropLast(1).joinToString() + " and " + last()
}
}
}