Kotlin Syntax

Learning Kotlin syntax is essential for modern Android development and server-side programming. Kotlin syntax offers a perfect blend of conciseness and readability, making it an ideal choice for developers transitioning from Java or starting fresh. This comprehensive guide will walk you through every aspect of Kotlin syntax, from basic declarations to advanced features that make Kotlin syntax so powerful and developer-friendly.

Variables and Data Types in Kotlin

Kotlin syntax provides two main ways to declare variables: var for mutable variables and val for immutable ones. Understanding this fundamental aspect of Kotlin syntax is crucial for writing effective code.

Mutable Variables (var)

var userName = "Alice"  // Type inferred as String  
var userAge: Int = 25   // Explicit type declaration  
userName = "Bob"        // Can be reassigned  

Immutable Variables (val)

val pi = 3.14159        // Type inferred as Double  
val maxUsers: Int = 100 // Explicit type declaration  
// pi = 3.14            // Compilation error - cannot reassign  

Kotlin syntax supports various primitive data types including Int, Long, Float, Double, Boolean, Char, and String. The type inference feature in Kotlin syntax eliminates the need for explicit type declarations in most cases.

Functions in Kotlin Syntax

Function declaration is one of the most important aspects of Kotlin syntax. Kotlin functions are declared using the fun keyword, and Kotlin syntax offers multiple ways to define them.

Basic Function Declaration

fun greetUser(name: String): String {  
    return "Hello, $name!"  
}  
  
// Single-expression function  
fun addNumbers(a: Int, b: Int) = a + b  

Function with Default Parameters

fun createUser(name: String, age: Int = 18, isActive: Boolean = true): String {  
    return "User: $name, Age: $age, Active: $isActive"  
}  

Kotlin syntax allows functions to have default parameter values, making function calls more flexible and reducing the need for method overloading.

Control Flow in Kotlin

Kotlin syntax provides intuitive control flow statements that are both powerful and easy to read.

If-Else Expressions

val score = 85  
val grade = if (score >= 90) {  
    "A"  
} else if (score >= 80) {  
    "B"  
} else {  
    "C"  
}  

When Expressions

The when expression in Kotlin syntax is more powerful than Java’s switch statement:

fun getSeasonMessage(month: Int): String {  
    return when (month) {  
        12, 1, 2 -> "Winter season"  
        in 3..5 -> "Spring season"  
        in 6..8 -> "Summer season"  
        in 9..11 -> "Fall season"  
        else -> "Invalid month"  
    }  
}  

Loops in Kotlin Syntax

// For loop with range  
for (i in 1..5) {  
    println("Number: $i")  
}  
  
// For loop with collection  
val fruits = listOf("apple", "banana", "orange")  
for (fruit in fruits) {  
    println("Fruit: $fruit")  
}  
  
// While loop  
var counter = 0  
while (counter < 3) {  
    println("Counter: $counter")  
    counter++  
}  

Collections in Kotlin

Kotlin syntax provides powerful collection types with built-in functions that make data manipulation straightforward.

Lists

// Immutable list  
val readOnlyList = listOf("kotlin", "java", "python")  
  
// Mutable list  
val mutableList = mutableListOf<String>()  
mutableList.add("swift")  
mutableList.add("dart")  

Maps

// Immutable map  
val countryMap = mapOf("US" to "United States", "UK" to "United Kingdom")  
  
// Mutable map  
val cityMap = mutableMapOf<String, Int>()  
cityMap["New York"] = 8000000  
cityMap["London"] = 9000000  

Sets

val uniqueNumbers = setOf(1, 2, 3, 2, 1) // Contains only 1, 2, 3  
val mutableSet = mutableSetOf<String>()  
mutableSet.add("unique")  

Classes and Objects in Kotlin

Kotlin syntax makes object-oriented programming more concise compared to Java while maintaining full functionality.

Class Declaration

class Student(val name: String, var age: Int) {  
    var grade: String = "A"  
      
    fun study(subject: String) {  
        println("$name is studying $subject")  
    }  
      
    fun getInfo(): String {  
        return "Student: $name, Age: $age, Grade: $grade"  
    }  
}  

Data Classes

Kotlin syntax includes data classes that automatically generate equals(), hashCode(), toString(), and copy() methods:

data class Product(val name: String, val price: Double, val category: String)  

Null Safety in Kotlin

One of the most important features of Kotlin syntax is null safety, which helps prevent the dreaded NullPointerException.

Nullable Types

var nullableString: String? = null  
var nonNullString: String = "Hello"  
  
// Safe call operator  
val length = nullableString?.length  
  
// Elvis operator  
val displayText = nullableString ?: "Default text"  
  
// Not-null assertion  
val forceLength = nullableString!!.length // Use with caution  

Extension Functions

Kotlin syntax allows you to extend existing classes with new functionality through extension functions:

fun String.isPalindrome(): Boolean {  
    val cleaned = this.lowercase().replace(" ", "")  
    return cleaned == cleaned.reversed()  
}  
  
// Usage  
val text = "A man a plan a canal Panama"  
println(text.isPalindrome()) // true  

Higher-Order Functions and Lambdas

Kotlin syntax supports functional programming concepts with higher-order functions and lambda expressions.

Lambda Expressions

val numbers = listOf(1, 2, 3, 4, 5)  
  
// Filter even numbers  
val evenNumbers = numbers.filter { it % 2 == 0 }  
  
// Map to squares  
val squares = numbers.map { it * it }  
  
// Custom higher-order function  
fun processNumbers(numbers: List<Int>, operation: (Int) -> Int): List<Int> {  
    return numbers.map(operation)  
}  

String Templates

Kotlin syntax includes powerful string interpolation features that make string formatting much cleaner:

val name = "Alice"  
val age = 30  
val city = "New York"  
  
// Simple string template  
val greeting = "Hello, $name!"  
  
// Expression in template  
val message = "Next year, $name will be ${age + 1} years old"  
  
// Multi-line string with trimIndent  
val address = """  
    Name: $name  
    Age: $age  
    City: $city  
""".trimIndent()  

Complete Example: Student Management System

Here’s a comprehensive example that demonstrates various Kotlin syntax features in a practical application:

data class Student(  
    val id: Int,  
    val name: String,  
    var grade: Double,  
    val subjects: MutableList<String> = mutableListOf()  
) {  
    fun addSubject(subject: String) {  
        if (!subjects.contains(subject)) {  
            subjects.add(subject)  
        }  
    }  
      
    fun getGradeLevel(): String = when {  
        grade >= 90 -> "Excellent"  
        grade >= 80 -> "Good"  
        grade >= 70 -> "Average"  
        else -> "Needs Improvement"  
    }  
}  
  
class StudentManager {  
    private val students = mutableListOf<Student>()  
      
    fun addStudent(student: Student) {  
        students.add(student)  
        println("Added student: ${student.name}")  
    }  
      
    fun findStudentById(id: Int): Student? {  
        return students.find { it.id == id }  
    }  
      
    fun getStudentsByGradeRange(minGrade: Double, maxGrade: Double): List<Student> {  
        return students.filter { it.grade in minGrade..maxGrade }  
    }  
      
    fun getAverageGrade(): Double {  
        return if (students.isNotEmpty()) {  
            students.map { it.grade }.average()  
        } else 0.0  
    }  
      
    fun printAllStudents() {  
        students.forEach { student ->  
            println("ID: ${student.id}, Name: ${student.name}, Grade: ${student.grade}")  
            println("Grade Level: ${student.getGradeLevel()}")  
            println("Subjects: ${student.subjects.joinToString(", ")}")  
            println("---")  
        }  
    }  
}  
  
// Extension function for Student  
fun Student.isHonorStudent(): Boolean = grade >= 85  
  
fun main() {  
    val manager = StudentManager()  
      
    // Create students  
    val student1 = Student(1, "Alice Johnson", 92.5)  
    student1.addSubject("Mathematics")  
    student1.addSubject("Physics")  
    student1.addSubject("Chemistry")  
      
    val student2 = Student(2, "Bob Smith", 78.0)  
    student2.addSubject("History")  
    student2.addSubject("English")  
      
    val student3 = Student(3, "Carol Davis", 88.5)  
    student3.addSubject("Biology")  
    student3.addSubject("Mathematics")  
      
    // Add students to manager  
    manager.addStudent(student1)  
    manager.addStudent(student2)  
    manager.addStudent(student3)  
      
    // Find student by ID  
    val foundStudent = manager.findStudentById(2)  
    foundStudent?.let { student ->  
        println("Found student: ${student.name} with grade ${student.grade}")  
    }  
      
    // Get students in grade range  
    val goodStudents = manager.getStudentsByGradeRange(80.0, 100.0)  
    println("\nStudents with grades between 80-100:")  
    goodStudents.forEach { println("${it.name}: ${it.grade}") }  
      
    // Check honor students using extension function  
    println("\nHonor Students:")  
    manager.getStudentsByGradeRange(0.0, 100.0)  
        .filter { it.isHonorStudent() }  
        .forEach { println("${it.name} is an honor student with grade ${it.grade}") }  
      
    // Calculate and display average grade  
    val averageGrade = manager.getAverageGrade()  
    println("\nClass average grade: ${"%.2f".format(averageGrade)}")  
      
    // Print all students  
    println("\nAll Students:")  
    manager.printAllStudents()  
      
    // Demonstrate null safety  
    val nullableStudent: Student? = manager.findStudentById(999)  
    val studentName = nullableStudent?.name ?: "Student not found"  
    println("\nSearching for student ID 999: $studentName")  
      
    // Lambda expressions with collections  
    val topStudents = manager.getStudentsByGradeRange(0.0, 100.0)  
        .filter { it.grade >= 85 }  
        .sortedByDescending { it.grade }  
        .take(2)  
      
    println("\nTop 2 Students:")  
    topStudents.forEach { student ->  
        val gradeInfo = "Grade: ${student.grade} (${student.getGradeLevel()})"  
        println("${student.name} - $gradeInfo")  
    }  
}  

Expected Output:

Added student: Alice Johnson  
Added student: Bob Smith  
Added student: Carol Davis  
Found student: Bob Smith with grade 78.0  
  
Students with grades between 80-100:  
Alice Johnson: 92.5  
Carol Davis: 88.5  
  
Honor Students:  
Alice Johnson is an honor student with grade 92.5  
Carol Davis is an honor student with grade 88.5  
  
Class average grade: 86.33  
  
All Students:  
ID: 1, Name: Alice Johnson, Grade: 92.5  
Grade Level: Excellent  
Subjects: Mathematics, Physics, Chemistry  
---  
ID: 2, Name: Bob Smith, Grade: 78.0  
Grade Level: Average  
Subjects: History, English  
---  
ID: 3, Name: Carol Davis, Grade: 88.5  
Grade Level: Good  
Subjects: Biology, Mathematics  
---  
  
Searching for student ID 999: Student not found  
  
Top 2 Students:  
Alice Johnson - Grade: 92.5 (Excellent)  
Carol Davis - Grade: 88.5 (Good)  

This comprehensive example showcases the elegance and power of Kotlin syntax, demonstrating how various language features work together to create clean, readable, and maintainable code. The Kotlin syntax makes it easy to express complex logic while maintaining type safety and null safety throughout your applications.