irahardianto / kotlin-idioms
Kotlin coding idioms: compile-time null safety, data classes, sealed hierarchies, coroutines and Flow concurrency, and Kotest/MockK testing. Use when developing, refactoring, or reviewing Kotlin backend, Android, or multiplatform code.
Kotlin Idioms and Patterns
Kotlin rewards conciseness, null safety, and coroutine-based concurrency. Idiomatic Kotlin = safe, expressive, interop-aware.
Scope: Kotlin coding idioms. Test naming: .agents/rules/testing-strategy.md.
Null Safety
?for nullable types — never platform types without annotation:`kotlin
fun findById(id: String): Task? // explicitly nullable
fun getById(id: String): Task // guaranteed non-null — throws if not found`- Prefer
?.let {}and?:(Elvis) over null checks. - Never
!!in production — userequireNotNullwith a message.
Data Classes and Sealed Types
data classfor DTOs and domain objects:`kotlin
data class CreateTaskRequest(val title: String, val priority: Priority)`sealed class/sealed interfacefor restricted hierarchies:`kotlin
sealed interface TaskResult {
data class Success(val task: Task) : TaskResult
data class NotFound(val id: String) : TaskResult
data class ValidationError(val errors: List<String>) : TaskResult
}`Exhaustive
whenwith sealed types:`kotlin
when (result) {
is TaskResult.Success -> ok(result.task)
is TaskResult.NotFound -> notFound(result.id)
is TaskResult.ValidationError -> badRequest(result.errors)
}`
Coroutines
- Structured concurrency —
coroutineScope,supervisorScope. - Never
GlobalScope.launch— always scoped. Flowfor reactive streams:`kotlin
fun observeTasks(): Flow<List<Task>> = flow {
while (currentCoroutineContext().isActive) {
emit(storage.getAll())
delay(5.seconds)
}
}`
Naming
- PascalCase for classes. camelCase for functions, properties.
- No
get/setprefixes — use properties. - Backtick function names only in tests:
`should create task when valid`()
Testing
kotest or JUnit 5 + MockK:
`kotlin
@Test
funcreate task returns task when valid() {
val result = service.create("Test", Priority.HIGH)
assertThat(result.title).isEqualTo("Test")
}`
Formatting and Static Analysis
| Tool | Purpose | Command |
|---|---|---|
ktlint | Formatting | ktlint --format |
detekt | Static analysis | detekt --config detekt.yml |
| Kotlin compiler | Null safety | Built-in |
Related
- Code Idioms and Conventions .agents/rules/code-idioms-and-conventions.md
- Testing Strategy .agents/rules/testing-strategy.md
- Error Handling Principles .agents/rules/error-handling-principles.md