Skip to content

Commit 8e81747

Browse files
authored
Kotlin / Bob / DigDeeper: Add a pattern matching approach using when-expression (#629)
* Add approach to introduction * Add snippet.txt and content.md * Add entry in config.json * Fix typo in config.json * Reduce snippet length to 8 lines * Use proposed one-liner in function isYelling
1 parent 09e762d commit 8e81747

File tree

4 files changed

+89
-0
lines changed

4 files changed

+89
-0
lines changed

exercises/practice/bob/.approaches/config.json

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,15 @@
2222
"authors": [
2323
"bobahop"
2424
]
25+
},
26+
{
27+
"uuid": "7aebc1df-c23a-42c9-90c4-f022e40d67e9",
28+
"slug": "when-expression",
29+
"title":"when expression",
30+
"blurb": "Use a when expression to return the answer.",
31+
"authors": [
32+
"micha-b"
33+
]
2534
}
2635
]
2736
}

exercises/practice/bob/.approaches/introduction.md

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,23 @@ object Bob {
5656

5757
For more information, check the [Answer `List` approach][approach-answer-list].
5858

59+
## Approach: `when` expression
60+
61+
```kotlin
62+
object Bob {
63+
fun hey(statement: String): String =
64+
when {
65+
statement.isQuestion() && statement.isYelling() -> "Calm down, I know what I'm doing!"
66+
statement.isQuestion() -> "Sure."
67+
statement.isYelling() -> "Whoa, chill out!"
68+
statement.isSilence() -> "Fine. Be that way!"
69+
else -> "Whatever."
70+
}
71+
}
72+
```
73+
74+
For more information, check the [`when` expression approach][approach-when]
75+
5976
## Which approach to use?
6077

6178
The choice between `if` expressions and answers `List` can be made by perceived readability.
@@ -65,3 +82,4 @@ The choice between `if` expressions and answers `List` can be made by perceived
6582
[dry]: https://en.wikipedia.org/wiki/Don%27t_repeat_yourself
6683
[approach-if]: https://exercism.org/tracks/kotlin/exercises/bob/approaches/if-expressions
6784
[approach-answer-list]: https://exercism.org/tracks/kotlin/exercises/bob/approaches/answer-list
85+
[approach-when]: https://exercism.org/tracks/kotlin/exercises/bob/approaches/when-expression
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# `when` expressions
2+
3+
```kotlin
4+
object Bob {
5+
fun hey(statement: String): String =
6+
when {
7+
statement.isQuestion() && statement.isYelling() -> "Calm down, I know what I'm doing!"
8+
statement.isQuestion() -> "Sure."
9+
statement.isYelling() -> "Whoa, chill out!"
10+
statement.isSilence() -> "Fine. Be that way!"
11+
else -> "Whatever."
12+
}
13+
14+
private fun String.isSilence(): Boolean = this.isBlank()
15+
private fun String.isQuestion(): Boolean = this.trim().endsWith('?')
16+
private fun String.isYelling(): Boolean = any(Char::isLetter) && toUpperCase() == this
17+
}
18+
```
19+
20+
In this approach you have a `when` expression containing different so-called branches that can be matched using the corresponding patterns.
21+
As soon as one of these patterns on the left side of the arrow (`->`) is matched ...
22+
23+
1. the value on the right side
24+
2. the block on the right side is executed and the value retuned from the block
25+
26+
... is returned from the `when` expression.
27+
28+
Only one branch is matched in one execution of the `when` expression. The branches are matched from top to bottom and the first branch in which the condition evaluates to `true` is selected.
29+
If none of the given conditions matches the `else` branch is selected and returned.
30+
31+
~~~~exercism/caution
32+
Depending on what patterns are on the left side of your branches the order of branches is important to the correct execution of the `when` expression since the first matching branch is selected.
33+
~~~~
34+
35+
An [object declaration][object] is used to define `Bob` as essentially a [singleton][singleton] object instantiation of the class.
36+
This is sufficient, since there is no object state that needs to change with each call of the `hey` method.
37+
38+
Inside this object there are some `private` [extension methods as members][extension-members] of the `object`. This adds these methods to the `String` data type for `private` usage of these methods in this `object`. This allows calling the methods directly on the `String` instead of passing the `String` to the method.
39+
(More about extension methods in general [here][extension-general])
40+
41+
These extension methods check for:
42+
43+
1. `isSilence()`: a blank string
44+
2. `isQuestion()`: a string with the last non-whitespace-character being a question mark
45+
3. `isYelling()`: a string with all letters in uppercase
46+
47+
When combining these methods as in the `when` expression above you can map all the cases required by the exercise.
48+
49+
50+
[when]: https://kotlinlang.org/docs/control-flow.html#when-expression
51+
[object]: https://kotlinlang.org/docs/object-declarations.html#object-declarations-overview
52+
[singleton]: https://en.wikipedia.org/wiki/Singleton_pattern
53+
[extension-members]: https://kotlinlang.org/docs/extensions.html#declaring-extensions-as-members
54+
[extension-general]: https://kotlinlang.org/docs/extensions.html
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
fun hey(statement: String): String =
2+
when {
3+
statement.isQuestion() && statement.isYelling() -> "Calm down, I know what I'm doing!"
4+
statement.isQuestion() -> "Sure."
5+
statement.isYelling() -> "Whoa, chill out!"
6+
statement.isSilence() -> "Fine. Be that way!"
7+
else -> "Whatever."
8+
}

0 commit comments

Comments
 (0)