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.