Recent Posts
Archives

Posts Tagged ‘Kotlin’

PostHeaderIcon [KotlinConf2024] Kotlin 2.0 and Beyond: Evolving Language Features

Michail Zarečenskij, Kotlin’s lead language designer, captivated KotlinConf2024 with a deep dive into Kotlin 2.0’s advancements and future features. The K2 compiler, central to Kotlin 2.0, introduces a frontend intermediate representation (FEIR) and a new control flow engine, enhancing code consistency and smart casts. Michail outlined upcoming features like guarded conditions, context parameters, and union types for errors, addressing modern development challenges. Through code examples and audience Q&A, he showcased Kotlin’s evolution, ensuring it remains concise, safe, and expressive for millions of developers.

Kotlin’s Evolutionary Journey

Since its 1.0 release eight years ago, Kotlin has grown significantly, adding features like coroutines, functional interfaces, and multiplatform support post-launch. Michail highlighted gradual introductions, such as trailing commas and exhaustive when statements, alongside bug fixes for smart casts and type inference. Beyond language, Kotlin targets JVM, Native, and Web, with scripting, Android, and server-side capabilities. Supported by IntelliJ and Fleet plugins, Compose compiler plugins, and libraries like Serialization, Kotlin’s ecosystem thrives on community-driven open-source contributions, setting the stage for K2’s transformative impact.

The K2 Compiler: A Robust Foundation

The K2 compiler, powering Kotlin 2.0, addresses limitations of the original compiler, which struggled with unexpected features like multiplatform requirements. Michail explained K2’s redesigned architecture, enabling faster language evolution and multiplatform plugin support. Unlike the tightly coupled original, K2 separates compiler and IDE logic, simplifying maintenance. With over 80 features, including build tool enhancements, K2 prioritizes performance, cutting compilation times, and correctness, fixing longstanding issues. Tested on 10M lines of code, K2 ensures stability, making it a cornerstone for future language advancements.

Frontend Intermediate Representation: Consistent Code

K2’s frontend intermediate representation (FEIR) transforms complex language constructs into simpler forms earlier in compilation, ensuring consistent analysis. Michail demonstrated with a mutable list increment example, where K2 resolves operator and conversion issues that tripped the old compiler. By desugaring expressions, FEIR handles nullable operators and delegate properties robustly, supporting intricate combinations of operators and extensions. This consistency empowers developers to compose features confidently, reducing errors in scenarios like nullable assignments or generic type operations, strengthening Kotlin’s expressiveness.

Control Flow Engine: Smarter Analysis

The new control flow engine in K2 enhances code execution analysis, detecting unreachable code and potential bugs. Michail showcased improved smart casts, such as local variables contributing to type safety. For example, extracting a nullability check to a variable now supports smart casts, unlike the old compiler. Inline functions gain implicit “call-in-place” contracts, enabling smart casts in lambdas. Logical operator smart casts, like merging types after an “or” check, further refine type inference, making Kotlin’s type system more intuitive and reducing manual casts.

Enhanced Smart Casts in Kotlin 2.0

Smart casts, a Kotlin hallmark, see significant upgrades in 2.0. Michail presented examples where K2 applies smart casts across nullability checks, type checks, and inline function lambdas. For instance, checking a variable’s type and nullability now triggers dual smart casts in appropriate blocks. Logical “or” operations infer supertypes, enabling method calls without explicit casting. These enhancements reduce cognitive load, letting developers focus on logic rather than type management. Compatibility with existing smart casts and contracts ensures a seamless transition, boosting code safety.

Guarded Conditions: Concise Control Flow

Set for beta in Kotlin 2.1, guarded conditions in when expressions eliminate restrictive single-check limitations. Michail illustrated with a UI-rendering example, where repeated variable checks cluttered code. Guarded conditions allow additional “if” clauses in when branches, reducing repetition and nesting. Context-sensitive resolution, planned for Kotlin 2.2, further simplifies sealed type handling by omitting base class names when types are known. These features streamline control flow, enhancing readability and maintainability, especially in complex UI or data-processing logic.

Context Parameters: Flexible APIs

Context parameters, moving to beta in Kotlin 2.2, enhance API design by allowing multiple receivers. Michail demonstrated with an autoclose scope, where context parameters enable extension functions within specific scopes, improving IDE autocompletion. This addresses limitations in single-receiver functions, making APIs more extensible and discoverable. By moving receivers to a context section, developers gain flexibility in defining operations, aligning with Kotlin’s focus on expressive, type-safe APIs. The feature’s popularity in experimental form underscores its potential to reshape library design.

Union Types for Errors: Robust Error Handling

Michail previewed union types for errors, targeting error and exception handling without general union types due to type checker complexity. In a sequence search example, union types distinguish “not found” from “null” results, eliminating extra variables and unchecked casts. Planned for future releases, this feature introduces a dedicated error type category with a “throw” method, compatible with exceptions. Smart casts automatically apply, streamlining error handling. Q&A clarified that multicatch support, akin to Java, is a goal, enhancing Kotlin’s robustness in production code.

Links:

PostHeaderIcon [KotlinConf2024] KotlinConf2024 Keynote: Powering the Future with Kotlin 2.0

KotlinConf2024, hosted in Copenhagen, welcomed 2,000 attendees and thousands online, kicking off with a vibrant keynote celebrating Kotlin’s evolution. Igor Tolstoy, Kotlin Project Lead at JetBrains, unveiled Kotlin 2.0, powered by the K2 compiler, promising double compilation speeds and robust multiplatform capabilities. Joined by speakers from Meta, Google, Amazon, and JetBrains, the keynote showcased Kotlin’s adoption in 20M lines of code at Meta, Google’s multiplatform push, and Amazon’s AWS SDK. From Compose Multiplatform to AI-driven tools, the event underscored Kotlin’s role in modern development, fueled by a thriving ecosystem.

A Global Stage for Kotlin Innovation

KotlinConf2024 buzzed with energy, uniting 2,000 in-person attendees, online viewers, and 71 global events across 37 countries. The conference featured five parallel sessions, lightning talks, a coach challenge, and code labs by Touchlab. A lively party with a live band and quiz, plus a closing panel, kept spirits high. Attendees donned T-shirts with words like “love,” “code,” and “nothing,” encouraged to form phrases for social media with #KotlinConf. Sponsors, including American Express, powered the event, with their booths bustling in the exhibit hall. The KotlinConf app, built with Compose Multiplatform, guided attendees, urging them to vote on sessions to shape future lineups.

Kotlin 2.0: The K2 Compiler Revolution

Igor Tolstoy introduced Kotlin 2.0, a milestone driven by the K2 compiler. This rewrite delivers a 2x compilation speed boost, slashing wait times for builds. Tested across 10M lines of code from 40 JetBrains and community projects, K2 ensures stability, with 18,000 developers and companies like Meta adopting early versions. The IntelliJ K2 mode, nearing beta, accelerates code highlighting by 1.8x, set to become default in IntelliJ 24.3. Avoiding major syntax changes, K2 fixes longstanding issues, enhancing code consistency and enabling faster language evolution without breaking existing projects.

Meta’s Kotlin Journey: Scaling Android

Eve Maler, an Android engineer from Meta, shared their Kotlin adoption, now spanning 20M lines of code. Since embracing Kotlin-first development three years ago, Meta reduced code by 10%, boosting reliability and developer preference. K2’s incremental compilation cut build times by up to 20%, with 95% of modules now using K2. Tools like IntelliJ’s J2K converter automate Java-to-Kotlin transitions, converting tens of thousands of lines weekly. Meta’s frameworks, including Litho and Dex optimizations, fully support Kotlin, paving the way for a mono-language Android experience, enhancing developer productivity.

Google’s Multiplatform Commitment

Jeffrey van Gogh from Google highlighted their investment in Kotlin, with 33M lines of code internally, doubling since 2023. Kotlin 2.0’s stability thrilled Google, who contributed compiler fixes and ported tools like Android Lint and Compose plugins to K2. The Compose compiler plugin now ships with Kotlin distributions, simplifying updates. Google announced official Android support for Kotlin Multiplatform (KMP) at Google I/O, enabling shared business logic across mobile, web, and desktop. Jetpack libraries like Room and DataStore now support KMP, with Android Studio integrating native KMP tooling, signaling a hybrid model balancing native and shared code.

Compose Multiplatform: Cross-Platform UI

Sebastian Aigner and Ekaterina Petrova celebrated Compose Multiplatform’s stability on Android and desktop, with iOS nearing beta and web in alpha. Used in thousands of apps, including McDonald’s, Compose reduced crashes and unified teams by sharing business logic. New APIs, like Jetpack Navigation and type-safe resources, enhance cross-platform development. iOS-specific improvements, such as VoiceOver integration and refined scroll physics, ensure native experiences. Web support leverages Kotlin/Wasm for high-performance browser apps. Compose’s flexibility lets developers choose how much code to share, from logic to full UI, meeting users across platforms.

Tooling Evolution: Amper and Fleet

JetBrains introduced Amper, a new build tool simplifying multiplatform project setup with minimal configuration. A Kotlin JVM project requires just one line, with dependencies easily added. Amper integrates with IntelliJ and Android Studio, offering quick fixes for project creation. Fleet, a preview multiplatform IDE, unifies Kotlin and Swift development, supporting Xcode projects and cross-language debugging. These tools automate environment checks, provide UI previews, and integrate JetBrains’ AI Assistant for code generation, streamlining workflows and lowering barriers for KMP adoption.

Ecosystem Growth: Libraries and AWS

The Kotlin ecosystem thrives, with a 50% rise in open-source multiplatform solutions. Libraries like Ktor, Serialization, and DateTime gain multiplatform APIs, while new additions like Kandy (data visualization) and DataFrame (data processing) expand capabilities. Amazon’s Julia detailed their AWS SDK for Kotlin, now generally available, built on Smithy for idiomatic APIs. Supporting hundreds of services, including Amazon Bedrock, the SDK leverages coroutines for pagination and streams. Amazon’s internal Kotlin use surged 6x, with teams like Prime Video reporting higher quality and productivity.

AI-Powered Development with JetBrains

Svetlana Isakova closed with JetBrains’ AI Assistant, written in Kotlin and integrated into IntelliJ and Fleet. It offers context-aware code completion, refactoring, and explanations, understanding project structures and dependencies. A Kotlin-specific language model, trained on open-source repositories, powers precise code generation, outperforming larger models in benchmarks. Available in IntelliJ 24.2, it supports multi-line completion and custom contexts. For enterprises, an on-premises version ensures compliance. Open-sourced datasets on Hugging Face further Kotlin’s AI advancements, equipping developers for the AI-driven future.

Links:

PostHeaderIcon [KotlinConf2023] Transforming Farmers’ Lives in Kenya: Apollo Agriculture’s Android Apps with Harun Wangereka

Harun Wangereka, a Software Engineer at Apollo Agriculture and a Google Developer Expert for Android, delivered an inspiring presentation at KotlinConf’23 about how his company is leveraging Android technology to change the lives of farmers in Kenya. His talk detailed Apollo Agriculture’s two core Android applications, built entirely in Kotlin, which are offline-first and utilize server-driven UI (SDUI) with Jetpack Compose to cater to the unique challenges of their user base. Harun is also active in Droidcon Kenya.

Apollo Agriculture’s mission is to empower small-scale farmers by bundling financing, high-quality farm inputs, agronomic advice, insurance, and market access. Their tech-based approach uses satellite data and machine learning for credit decisions and automated operations to maintain low costs and scalability. The customer journey involves signup via agents or SMS/USSD, kyc data collection (including GPS farm outlines), automated credit decisions (often within minutes), input pickup from agro-dealers, digital advice via voice trainings, and loan repayment post-harvest.

Addressing Unique Challenges in the Kenyan Context

Harun highlighted several critical challenges that shaped their app development strategy:
* Low-Memory Devices: Many agents and farmers use entry-level Android devices with limited RAM and storage. The apps need to be lightweight and performant.
* Low/Intermittent Internet Bandwidth: Internet connectivity can be unreliable and expensive. An offline-first approach is crucial, allowing agents to perform tasks without constant internet access and sync data later.
* Diverse User Needs and Rapid Iteration: The agricultural domain requires frequent updates to forms, workflows, and information provided to farmers and agents. A flexible UI system that can be updated without frequent app releases is essential.

These challenges led Apollo Agriculture to adopt a server-driven UI (SDUI) approach. Initially implemented with Anko (a deprecated Kotlin library for Android UI), they later rewrote this system entirely using Jetpack Compose.

Server-Driven UI with Jetpack Compose

The core of their SDUI system relies on JSON responses from the server that define the UI components, their properties, validations, and conditional logic.
Key aspects of their implementation include:
* Task-Based Structure: The app presents tasks to agents (e.g., onboarding a farmer, collecting survey data). Each task is represented by a JSON schema from the server.
* Dynamic Form Rendering: The JSON schema defines various UI elements like text inputs, number inputs, date pickers, location pickers (with map integration for capturing farm boundaries), image inputs (with compression), and more. These are dynamically rendered using Jetpack Compose.
* Stateful Composable Components: Harun detailed their approach to building stateful UI components in Compose. Each question or input field manages its own state (value, errors, visibility) using remember and mutableStateOf. Validation logic (e.g., required fields, min/max length) is also defined in the JSON and applied dynamically.
* Triggers and Conditionals: The JSON schema supports triggers (e.g., “on save”) and complex conditional logic using an internal tool called “Choice Expressions” and an implementation of JSON Schema. This allows UI elements or entire sections to be shown/hidden or enabled/disabled based on user input or other conditions, enabling dynamic and context-aware forms.
* Offline First: Task schemas and user data are stored locally, allowing full offline functionality. Data is synced with the server when connectivity is available.
* Testing: They extensively test their dynamic UI components and state logic in isolation, verifying state changes, validation behavior, and conditional rendering.

Harun shared examples of the JSON structure for defining UI elements, properties (like labels, hints, input types), validators, and conditional expressions. He walked through how a simple text input composable would manage its state, handle user input, and apply validation rules based on the server-provided schema.

Learnings and Future Considerations

The journey involved migrating from Anko to Jetpack Compose for their SDUI renderer, which Compose’s reactive DSL made more manageable and maintainable. They found Compose to be well-suited for building dynamic, stateful UIs.
Challenges encountered included handling keyboard interactions smoothly with scrolling content and managing the complexity of deeply nested conditional UIs.
When asked about open-sourcing their powerful form-rendering engine, Harun mentioned it’s a possibility they are considering, as the core logic is already modularized, and community input could be valuable. He also noted that while some pricing information is dynamic (e.g., based on farm size), they try to standardize core package prices to avoid confusion for farmers.

Harun Wangereka’s talk provided a compelling case study of how Kotlin and Jetpack Compose can be used to build sophisticated, resilient, and impactful Android applications that address real-world challenges in demanding environments.

Links:

PostHeaderIcon [KotlinConf2023] KotlinConf’23 Closing Panel: Community Questions and Future Insights

KotlinConf’23 concluded with its traditional Closing Panel, an open forum where attendees could pose their burning questions to a diverse group of experts from the Kotlin community, including key figures from JetBrains and Google. The panel, moderated by Hadi Hariri, featured prominent names such as Roman Elizarov, Egor Tolstoy, Maxim Shafirov (CEO of JetBrains), Svetlana Isakova, Pamela Hill, Sebastian Aigner (all JetBrains), Grace Kloba, Kevin Galligan, David Blanc, Wenbo, Jeffrey van Gogh (all Google), Jake Wharton (Cash App), and Zac Sweers (Slack), among others.

The session was lively, covering a wide range of topics from language features and tooling to ecosystem development and the future of Kotlin across different platforms.

Kotlin’s Ambitions and Language Evolution

One of the initial questions addressed Kotlin’s overarching goal, humorously framed as whether Kotlin aims to “get rid of other programming languages”. Roman Elizarov quipped they only want to get rid of “bad ones,” while Egor Tolstoy clarified that Kotlin’s focus is primarily on application development (services, desktop, web, mobile) rather than systems programming.

Regarding Kotlin 2.0 and the possibility of removing features, the panel indicated a strong preference for maintaining backward compatibility. However, if a feature were to be considered for removal, it would likely be something with a clearly superior alternative, such as potentially older ways of doing things if newer, more robust mechanisms (like K2 compiler plugins replacing older KAPT mechanisms, hypothetically) became the standard. The discussion also touched on the desire for a unified, official Kotlin style guide and formatter to reduce community fragmentation around tooling, though Zac Sweers noted that even with an official tool, community alternatives would likely persist.

Multiplatform, Compose, and Ecosystem

A significant portion of the Q&A revolved around Kotlin Multiplatform (KMP) and Compose Multiplatform.
* Dart Interoperability: Questions arose about interoperability between Kotlin/Native (especially for Compose on iOS which uses Skia) and Dart/Flutter. While direct, deep interoperability wasn’t presented as a primary focus, the general sentiment was that both ecosystems are strong, and developers choose based on their needs. The panel emphasized that Compose for iOS aims for a native feel and deep integration with iOS platform features.
* Compose UI for iOS and Material Design: A recurring concern was whether Compose UI on iOS would feel “too Material Design” and not native enough for iOS users. Panelists from JetBrains and Google acknowledged this, stressing ongoing efforts to ensure Compose components on iOS adhere to Cupertino (iOS native) design principles and feel natural on the platform. Jake Wharton added that making Kotlin APIs feel idiomatic to iOS developers is crucial for adoption.
* Future of KMP: The panel expressed strong optimism for KMP’s future, highlighting its stability and growing library support. They see KMP becoming the default way to build applications when targeting multiple platforms with Kotlin. The focus is on making KMP robust and ensuring a great developer experience across all supported targets.

Performance, Tooling, and Emerging Areas

  • Build Times: Concerns about Kotlin/Native build times, especially for iOS, were acknowledged. The team is continuously working on improving compiler performance and reducing build times, with K2 expected to bring further optimizations.
  • Project Loom and Coroutines: Roman Elizarov reiterated points from his earlier talk, stating that Loom is excellent for migrating existing blocking Java code, while Kotlin Coroutines offer finer-grained control and structured concurrency, especially beneficial for UI and complex asynchronous workflows. They are not mutually exclusive and can coexist.
  • Kotlin in Gaming: While not a primary focus historically, the panel acknowledged growing interest and some community libraries for game development with Kotlin. The potential for KMP in this area was also noted.
  • Documentation: The importance of clear, comprehensive, and up-to-date documentation was a recurring theme, with the panel acknowledging it as an ongoing effort.
  • AI and Kotlin: When asked about AI taking developers’ jobs, Zac Sweers offered a pragmatic take: AI won’t take your job, but someone who knows how to use AI effectively might. The panel highlighted that Kotlin is well-suited for building AI tools and applications.

The panel concluded with the exciting reveal of Kotlin’s reimagined mascot, Kodee (spelled K-O-D-E-E), a cute, modern character designed to represent the language and its community. Pins of Kodee were made available to attendees, adding a fun, tangible takeaway to the conference’s close.

Links:

PostHeaderIcon [KotlinConf2023] Java and Kotlin: A Mutual Evolution

At KotlinConf2024, John Pampuch, Google’s production languages lead, delivered a history lesson on Java and Kotlin’s intertwined journeys. Battling jet lag with humor, John traced nearly three decades of Java and twelve years of Kotlin, emphasizing their complementary strengths. From Java’s robust ecosystem to Kotlin’s pragmatic innovation, the languages have shaped each other, accelerating progress. John’s talk, rooted in his experience since Java’s 1996 debut, explored design goals, feature cross-pollination, and future implications, urging developers to leverage Kotlin’s developer-friendly features while appreciating Java’s stability.

Design Philosophies: Pragmatism Meets Robustness

John opened by contrasting the languages’ origins. Java, launched in 1995, aimed for simplicity, security, and portability, aligning tightly with the JVM and JDK. Its ecosystem, bolstered by libraries and tooling, set a standard for enterprise development. Kotlin, announced in 2011 by JetBrains, prioritized pragmatism: concise syntax, interoperability with Java, and multiplatform flexibility. Unlike Java’s JVM dependency, Kotlin targets iOS, web, and beyond, enabling faster feature rollouts. John noted Kotlin’s design avoids Java’s rigidity, embracing object-oriented principles with practical tweaks like semicolon-free lines. Yet Java’s self-consistency, seen in its holistic lambda integration, complements Kotlin’s adaptability, creating a synergy where both thrive.

Feature Evolution: From Lambdas to Coroutines

The talk highlighted key milestones. Java’s 2014 release of JDK 8 introduced lambdas, default methods, and type inference, transforming APIs to support functional programming. Kotlin, with 1.0 in 2016, brought smart casts, string templates, and named arguments, prioritizing developer ease. By 2018, Kotlin’s coroutines revolutionized JVM asynchronous programming, offering a simpler mental model than Java’s threads. John praised coroutines as a potential game-changer, though Java’s 2023 virtual threads and structured concurrency aim to close the gap. Kotlin’s multiplatform support, cemented by Google’s 2017 Android endorsement, outpaces Java’s JVM-centric approach, but Java’s predictable six-month release cycle since 2017 ensures steady progress. These advancements reflect a race where each language pushes the other forward.

Mutual Influences: Sealed Classes and Beyond

John emphasized cross-pollination. Java’s 2021 records, inspired by frameworks like Lombok, mirror Kotlin’s data classes, though Kotlin’s named parameters reduce boilerplate further. Sealed classes, introduced in Java 17 and Kotlin 1.5 around 2021, emerged concurrently, suggesting shared inspiration. Kotlin’s string templates, a staple since its early days, influenced Java’s 2024 preview of flexible string templates, which John hopes Kotlin might adopt for localization. Java’s exploration of nullability annotations, potentially aligning with Kotlin’s robust null safety, shows ongoing convergence. John speculated that community demand could push Java toward features like named arguments, though JVM changes remain a hurdle. This mutual learning, fueled by competition with languages like Go and Rust, drives excitement and innovation.

Looking Ahead: Pragmatism and Compatibility

John concluded with a call to action: embrace Kotlin’s compact, readable features while valuing Java’s compile-time speed and ecosystem. Kotlin’s faster feature delivery and multiplatform prowess contrast with Java’s backwards compatibility and predictability. Yet both share a commitment to pragmatic evolution, avoiding breaks in millions of applications. Questions from the audience probed Java’s nullability and virtual threads, with John optimistic about eventual alignment but cautious about timelines. His talk underscored that Java and Kotlin’s competition isn’t zero-sum—it’s a catalyst for better tools, ideas, and developer experiences, ensuring both languages remain vital.

Hashtags: #Java #Kotlin

PostHeaderIcon [KotlinConf2023] Dissecting Kotlin: Exploring Idiomatic Usage of Sealed Types, SAMs, and More with Huyen Tue Dao

Huyen Tue Dao, a respected Android and Kotlin developer (formerly of Trello, more recently Lead Android Developer at Adobe), returned to KotlinConf’23 with her insightful talk, “Dissecting Kotlin: Unsealing the Sealed, the SAM, and Other Syntax”. Continuing her exploration of what constitutes “idiomatic Kotlin,” Huyen examined several language and library features introduced or refined over the past few years, delving into their semantics, syntax, and underlying implementations to understand their best use cases and how they fit into Kotlin’s broader themes. She referenced Andre Breslav’s 2018 KotlinConf keynote, which emphasized Kotlin’s pragmatic goals: readability over concision, reuse over expressiveness, interoperability, and safety/tooling.

Huyen’s approach involved dissecting features to see if they guide developers toward more idiomatic Kotlin or present choices where idiomatic usage might be nuanced.

Sealed Hierarchies: Evolution and Flexibility

Huyen began by revisiting sealed classes and interfaces, a cornerstone for modeling restricted hierarchies, often used for representing states or a fixed set of types. Key evolutions she discussed include:
* Sealed Interfaces (Kotlin 1.5): Previously, sealed hierarchies were restricted to sealed class and abstract class. The introduction of sealed interface provided more flexibility, allowing classes to implement multiple sealed interfaces and enabling a wider range of domain modeling possibilities. She illustrated this by evolving a movie genre example, initially a sealed class, to use sealed interfaces for sub-genres, demonstrating how a class (e.g., a specific movie) could belong to multiple genre classifications.
* Unsealing Sealed Classes (Implicitly): While not “unsealing” in the sense of breaking the restriction, the ability for subclasses of sealed classes to be defined in different files within the same compilation unit and module (introduced before Kotlin 1.5 for sealed classes, and a natural fit for sealed interfaces) offers more organizational flexibility for larger hierarchies.
* Data Objects (Kotlin 1.9): For singleton instances within a sealed hierarchy (or elsewhere) that benefit from data class-like behavior (e.g., a meaningful toString()), Kotlin 1.9 introduced data object. This combines the singleton nature of object with the auto-generated toString, equals, and hashCode methods of data classes, providing a cleaner way to represent simple, named instances in a hierarchy.

A “bytecode break” showed that sealed classes are compiled as abstract classes with private constructors and that their permitted subclasses are often checked using instanceof and specific class metadata generated by the compiler.

Unsigned Integers and Value Classes: Expressiveness and Performance

Huyen then explored features aimed at enhancing expressiveness and performance around data representation:
* Unsigned Integer Types (UByte, UShort, UInt, ULong – Stable in Kotlin 1.5): These types provide a way to represent non-negative numbers, utilizing the full bit-width for the magnitude. This is particularly useful when interacting with native APIs (like C++) that use unsigned types, or when dealing with data where negative values are meaningless (e.g., quantities, bitmasks). They come with their own set of operations and ranges. Huyen highlighted how they avoid the complexities of two’s complement interpretation when only positive values are needed.
* Value Classes (Inline Classes became Value Classes, stable with JVM backend in Kotlin 1.5): Value classes (@JvmInline value class) are wrappers around a single underlying property. Their primary benefit is providing type safety for primitive-like data (e.g., Email, UserId, Frequency) without the runtime overhead of heap allocation for the wrapper object in many cases. When possible, the compiler “inlines” the value, using the underlying type directly in bytecode, thus avoiding object allocation and offering performance benefits similar to primitives while retaining type distinction at compile time. Huyen used an audio processing example with distinct types like Frequency, SamplingRate, and FramesPerBuffer to illustrate how value classes can prevent accidental misuse of simple types like Int or Float.

SAM Conversions and Functional Interfaces: Java Interop and Kotlin Idiom

Finally, Huyen discussed Single Abstract Method (SAM) interfaces and Kotlin’s fun interface:
* SAM Conversions for Java Interfaces: Kotlin has long supported SAM conversions for Java interfaces, allowing a lambda to be used where an instance of a Java interface with a single abstract method is expected.
* fun interface (Kotlin 1.4): To enable similar idiomatic usage for Kotlin-defined interfaces, Kotlin introduced fun interface. By marking a Kotlin interface with the fun keyword, developers explicitly opt-in to SAM conversion, allowing a lambda to be directly passed where an instance of that interface is required. This promotes a more functional style and reduces boilerplate for simple callback-like interfaces. This feature aims to provide compatible syntax between Java and Kotlin code for functional interfaces.

Huyen concluded by reiterating that while understanding syntax and semantics is helpful, “idiomatic Kotlin” ultimately is about what best solves the problem at hand for the developer and their team, aligning with Kotlin’s pragmatic principles.

Links:

PostHeaderIcon [KotlinConf’2023] Coroutines and Loom: A Deep Dive into Goals and Implementations

The advent of OpenJDK’s Project Loom and its virtual threads has sparked considerable discussion within the Java and Kotlin communities, particularly regarding its relationship with Kotlin Coroutines. Roman Elizarov, Project Lead for Kotlin at JetBrains, addressed this topic head-on at KotlinConf’23 in his talk, “Coroutines and Loom behind the scenes”. His goal was not just to answer whether Loom would make coroutines obsolete (the answer being a clear “no”), but to delve into the distinct design goals, implementations, and trade-offs of each, clarifying how they can coexist and even complement each other. Information about Project Loom can often be found via OpenJDK resources or articles like those on Baeldung.

Roman began by noting that Project Loom, introducing virtual threads to the JVM, was nearing stability, targeted for Java 21 (late 2023). He emphasized that understanding the goals behind each technology is crucial, as these goals heavily influence their design and optimal use cases.

Project Loom: Simplifying Server-Side Concurrency

Project Loom’s primary design goal, as Roman Elizarov explained, is to preserve the thread-per-request programming style prevalent in many existing Java server-side applications, while dramatically increasing scalability. Traditionally, assigning one platform thread per incoming request becomes a bottleneck due to the high cost of platform threads. Virtual threads aim to solve this by providing lightweight, JVM-managed threads that can run existing synchronous, blocking Java code with minimal or no changes. This allows legacy applications to scale much better without requiring a rewrite to asynchronous or reactive patterns.

Loom achieves this by “unmounting” a virtual thread from its carrier (platform) thread when it encounters a blocking operation (like I/O) that has been integrated with Loom. The carrier thread is then free to run other virtual threads. When the blocking operation completes, the virtual thread is “remounted” on a carrier thread to continue execution. This mechanism is largely transparent to the application code. However, Roman pointed out a potential pitfall: if blocking operations occur within synchronized blocks or native JNI calls that haven’t been adapted for Loom, the carrier thread can get “pinned,” preventing unmounting and potentially negating some of Loom’s benefits in those specific scenarios.

Kotlin Coroutines: Fine-Grained, Structured Concurrency

In contrast, Kotlin Coroutines were designed with different primary goals:

  1. Enable fine-grained concurrency: Allowing developers to easily launch tens of thousands or even millions of concurrent tasks without performance issues, suitable for highly concurrent applications like UI event handling or complex data processing pipelines.
  2. Provide structured concurrency: Ensuring that the lifecycle of coroutines is managed within scopes, simplifying cancellation and preventing resource leaks. This is particularly critical for UI applications where tasks need to be cancelled when UI components are destroyed.

Kotlin Coroutines achieve this through suspendable functions (suspend fun) and a compiler-based transformation. When a coroutine suspends, it doesn’t block its underlying thread; instead, its state is saved, and the thread is released to do other work. This is fundamentally different from Loom’s approach, which aims to make blocking calls non-problematic for virtual threads. Coroutines explicitly distinguish between suspending and non-suspending code, a design choice that enables features like structured concurrency but requires a different programming model than traditional blocking code.

Comparing Trade-offs and Performance

Roman Elizarov presented a detailed comparison:

  • Programming Model: Loom aims for compatibility with existing blocking code. Coroutines introduce a new model with suspend functions, which is more verbose for simple blocking calls but enables powerful features like structured concurrency and explicit cancellation. Forcing blocking calls into a coroutine world requires wrappers like withContext(Dispatchers.IO), while Loom handles blocking calls transparently on virtual threads.
  • Cost of Operations:
    • Launching: Launching a coroutine is significantly cheaper than starting even a virtual thread, as coroutines are lighter weight objects.
    • Yielding/Suspending: Suspending a coroutine is generally cheaper than a virtual thread yielding (unmounting/remounting), due to compiler optimizations in Kotlin for state machine management. Roman showed benchmarks indicating lower memory allocation and faster execution for coroutine suspension compared to virtual thread context switching in preview builds of Loom.
  • Error Handling & Cancellation: Coroutines have built-in, robust support for structured cancellation. Loom’s virtual threads rely on Java’s traditional thread interruption mechanisms, which are less integrated into the programming model for cooperative cancellation.
  • Debugging: Loom’s virtual threads offer a debugging experience very similar to traditional threads, with understandable stack traces. Coroutines, due to their state-machine nature, can sometimes have more complex stack traces, though IDE support has improved this.

Coexistence and Future Synergies

Roman Elizarov concluded that Loom and coroutines are designed for different primary use cases and will coexist effectively.

  • Loom excels for existing Java applications using the thread-per-request model that need to scale without major rewrites.
  • Coroutines excel for applications requiring fine-grained, highly concurrent operations, structured concurrency, and explicit cancellation management, often seen in UI applications or complex backend services with many interacting components.

He also highlighted a potential future synergy: Kotlin Coroutines could leverage Loom’s virtual threads for their Dispatchers.IO (or a similar dispatcher) when running on newer JVMs. This could allow blocking calls within coroutines (those wrapped in withContext(Dispatchers.IO)) to benefit from Loom’s efficient handling of blocking operations, potentially eliminating the need for a large, separate thread pool for I/O-bound tasks in coroutines. This would combine the benefits of both: coroutines for structured, fine-grained concurrency and Loom for efficient handling of any unavoidable blocking calls.

Links:

Hashtags: #Kotlin #Coroutines #ProjectLoom #Java #JVM #Concurrency #AsynchronousProgramming #RomanElizarov #JetBrains

PostHeaderIcon [KotlinConf’23] The Future of Kotlin is Bright and Multiplatform

KotlinConf’23 kicked off with an energizing keynote, marking a highly anticipated return to an in-person format in Amsterdam. Hosted by Hadi Hariri from JetBrains, the session brought together key figures from both JetBrains and Google, including Roman Elizarov, Svetlana Isakova, Egor Tolstoy, and Grace Kloba (VP of Engineering for Android Developer Experience at Google), to share exciting updates and future directions for the Kotlin language and its ecosystem. The conference also boasted a global reach with KotlinConf Global events held across 41 countries. For those unable to attend, the key announcements from the keynote are also available in a comprehensive blog post on the official Kotlin blog.

The keynote began by celebrating Kotlin’s impressive growth, with compelling statistics underscoring its widespread adoption, particularly in Android development where it stands as the most popular language, utilized in over 95% of the top 1000 Android applications. A significant emphasis was placed on the forthcoming Kotlin 2.0, which is centered around the revolutionary new K2 compiler. This compiler promises significant performance improvements, enhanced stability, and a robust foundation for the language’s future evolution. The K2 compiler is nearing completion and is slated for release as Kotlin 2.0. Additionally, the IntelliJ IDEA plugin will also adopt the K2 frontend, ensuring alignment with IntelliJ releases and a consistent developer experience.

The Evolution of Kotlin: K2 Compiler and Language Features

The K2 compiler was a central theme of the keynote, signifying a major milestone for Kotlin. This re-architected compiler frontend, which also powers the IDE, is designed to be faster, more stable, and to enable quicker development of new language features and tooling capabilities. Kotlin 2.0, built upon the K2 compiler, is set to bring these profound benefits to all Kotlin developers, improving both compiler performance and IDE responsiveness.

Beyond the immediate horizon of Kotlin 2.0, the speakers provided a glimpse into potential future language features that are currently under consideration. These exciting prospects included:

Prospective Language Enhancements

  • Static Extensions: This feature aims to allow static resolution of extension functions, which could potentially improve performance and code clarity.
  • Collection Literals: The introduction of a more concise syntax for creating collections, such as using square brackets for lists, with efficient underlying implementations, is on the cards.
  • Name-Based Destructuring: Offering a more flexible way to destructure objects based on property names rather than simply their positional order.
  • Context Receivers: A powerful capability designed to provide contextual information to functions in a more implicit and structured manner. This feature, however, is being approached with careful consideration to ensure it aligns well with Kotlin’s core principles and doesn’t introduce undue complexity.
  • Explicit Fields: This would provide developers with more direct control over the backing fields of properties, offering greater flexibility in certain scenarios.

The JetBrains team underscored a cautious and deliberate approach to language evolution, ensuring that any new features are meticulously designed and maintainable within the Kotlin ecosystem. Compiler plugins were also highlighted as a powerful mechanism for extending Kotlin’s capabilities without altering its core.

Kotlin in the Ecosystem: Google’s Investment and Multiplatform Growth

Grace Kloba from Google took the stage to reiterate Google’s strong and unwavering commitment to Kotlin. She shared insights into Google’s substantial investments in the Kotlin ecosystem, including the development of Kotlin Symbol Processing (KSP) and the continuous emphasis on Kotlin as the default choice for Android development. Google officially championed Kotlin for Android development as early as 2017, a pivotal moment for the language’s widespread adoption. Furthermore, the Kotlin DSL is now the default for Gradle build scripts within Android Studio, significantly enhancing the developer experience with features such as semantic syntax highlighting and advanced code completion. Google also actively contributes to the Kotlin Foundation and encourages community participation through initiatives like the Kotlin Foundation Grants Program, which specifically focuses on supporting multiplatform libraries and frameworks.

Kotlin Multiplatform (KMP) emerged as another major highlight of the keynote, emphasizing its increasing maturity and widespread adoption. The overarching vision for KMP is to empower developers to share code across a diverse range of platforms—Android, iOS, desktop, web, and server-side—while retaining the crucial ability to write platform-specific code when necessary for optimal integration and performance. The keynote celebrated the burgeoning number of multiplatform libraries and tools, including KMM Bridge, which are simplifying KMP development workflows. The future of KMP appears exceptionally promising, with ongoing efforts to further enhance the developer experience and expand its capabilities across even more platforms.

Compose Multiplatform and Emerging Technologies

The keynote also featured significant advancements in Compose Multiplatform, JetBrains’ declarative UI framework for building cross-platform user interfaces. A particularly impactful announcement was the alpha release of Compose Multiplatform for iOS. This groundbreaking development allows developers to write their UI code once in Kotlin and deploy it seamlessly across Android and iOS, and even to desktop and web targets. This opens up entirely new avenues for code sharing and promises accelerated development cycles for mobile applications, breaking down traditional platform barriers.

Finally, the JetBrains team touched upon Kotlin’s expansion into truly emerging technologies, such as WebAssembly (Wasm). JetBrains is actively developing a new compiler backend for Kotlin specifically targeting WebAssembly, coupled with its own garbage collection proposal. This ambitious effort aims to deliver high-performance Kotlin code directly within the browser environment. Experiments involving the execution of Compose applications within the browser using WebAssembly were also mentioned, hinting at a future where Kotlin could offer a unified development experience across an even broader spectrum of platforms. The keynote concluded with an enthusiastic invitation to the community to delve deeper into these subjects during the conference sessions and to continue contributing to Kotlin’s vibrant and ever-expanding ecosystem.

Hashtags: #Keynote #JetBrains #Google #K2Compiler #Kotlin2 #Multiplatform #ComposeMultiplatform #WebAssembly

PostHeaderIcon [KotlinConf2023] Compose Multiplatform on iOS: Sharing UIs Across Ecosystems with Sebastian Aigner and Nikita Lipsky

At KotlinConf’23, Sebastian Aigner (Developer Advocate at JetBrains) and Nikita Lipsky (Software Developer for Kotlin at JetBrains) presented an exciting overview of Compose Multiplatform, focusing on its then-Alpha support for iOS. Their session detailed how this JetBrains initiative enables developers to write their user interface once in Kotlin and deploy it across Android, iOS, desktop, and web, fostering significant code sharing and development efficiency. The official documentation for Compose Multiplatform offers further insights.

The presentation began by recapping the classic Kotlin Multiplatform (KMP) use case, which allows sharing of business logic while retaining access to platform-specific APIs. Compose Multiplatform builds upon this by providing a solution for sharing the UI layer itself, addressing scenarios where building and maintaining separate native UIs for each platform is not feasible due to time, resources, or the desire for rapid market entry. While the talk focused on iOS and Android, the speakers emphasized that Compose Multiplatform also supports desktop (stabilized in late 2021) and web targets.

Architecture and Jetpack Compose Foundations

A key point underscored by Sebastian and Nikita was that Compose Multiplatform is built upon Jetpack Compose, Google’s modern declarative UI toolkit for Android, which is 100% Kotlin. This means developers familiar with Jetpack Compose can leverage their existing knowledge and skills to build UIs for iOS and other platforms. The JetBrains team collaborates closely with Google, regularly upstreaming changes to the Jetpack Compose repositories.

Nikita Lipsky delved into the architecture, explaining that official Jetpack Compose itself is already a Kotlin Multiplatform project at its core, with its lowest levels defining Kotlin Multiplatform sources. The composable function concept is an extension to the Kotlin language requiring compiler support, and the entire Compose system is managed by the Compose Runtime. For iOS, Compose Multiplatform renders UI elements by drawing directly onto a CAPI (Canvas API) provided by Skiko, a graphics library that abstracts over Skia (for Android and desktop) and CoreGraphics (for iOS). This allows for consistent rendering across platforms.

Live Demos and iOS Integration

The session featured live demonstrations showcasing the capabilities of Compose Multiplatform on iOS. Sebastian Aigner walked through a sample application, highlighting how standard Jetpack Compose code for UI elements, state management (using remember), layouts (like Column), and modifiers can be shared and run on iOS simulators and devices. He demonstrated features like text input, button interactions, and even integration with iOS-specific functionalities like the share sheet, emphasizing the goal of seamless interoperability.

The speakers also discussed the importance of providing solid accessibility integrations and ensuring smooth performance, even on high-refresh-rate displays, which is an ongoing area of focus for the Kotlin/Native and Compose Multiplatform teams. Interoperability with existing iOS UI code (SwiftUI and UIKit) was also presented as a key feature, allowing for gradual adoption. Developers can embed Compose Multiplatform views within existing SwiftUI applications or, conversely, embed native iOS views within a Compose Multiplatform UI. This flexibility is crucial for teams looking to integrate Compose into their established projects incrementally.

Getting Started and Future Outlook

Sebastian and Nikita provided clear guidance on how developers can start experimenting with Compose Multiplatform for iOS. They pointed to project templates, sample applications available on the Compose Multiplatform GitHub repository (including to-do list apps and code viewers), and updated KMP production samples that now include branches with Compose-based UI implementations. The new memory manager in Kotlin/Native was also mentioned as a significant improvement, simplifying multi-threaded programming for all Kotlin targets, including iOS.

While acknowledging that the iOS target was in Alpha and some areas were still works in progress, the overall message was one of excitement and a call to action for the community. They encouraged developers to explore the technology, provide feedback, and contribute to its evolution. The vision is a future where developers can agree on a delightful way to write UIs for all their target platforms using Kotlin.

Links:

PostHeaderIcon [KotlinConf2023] KotlinConf’23 Keynote: The Future of Kotlin is Bright and Multiplatform

KotlinConf’23 kicked off with an energizing keynote, marking a much-anticipated return to an in-person format in Amsterdam. Hosted by Hadi Hariri of JetBrains, the session brought together key figures from both JetBrains and Google, including Roman Elizarov, Svetlana Isakova, Egor Tolstoy, and Grace Kloba (VP Engineering for Android Developer Experience at Google), to share exciting updates and future directions for the Kotlin language and its ecosystem. The conference also featured a global reach with KotlinConf Global events in 41 countries. The main announcements from the keynote are also available in a blog post on the Kotlin blog.

The keynote celebrated Kotlin’s impressive growth, with statistics highlighting its widespread adoption, particularly in Android development where it’s the most popular language, used in over 95% of the top 1000 Android apps. A major focus was the upcoming Kotlin 2.0, centered around the new K2 compiler, which promises significant performance improvements, stability, and a foundation for future language evolution. The K2 compiler is nearing completion and is set to be released as Kotlin 2.0. The IntelliJ IDEA plugin will also adopt the K2 frontend, aligning with IntelliJ releases.

The Evolution of Kotlin: K2 Compiler and Language Features

The K2 compiler was a central theme of the keynote, marking a major milestone for Kotlin. This new compiler front-end, which also powers the IDE, is designed to be faster, more stable, and enable the development of new language features and tooling capabilities more rapidly. Kotlin 2.0, built on K2, is expected to bring these benefits to all Kotlin developers, enhancing both compiler performance and IDE responsiveness.

Looking beyond Kotlin 2.0, the speakers provided a glimpse into potential future language features that are under consideration. These included:
* Static Extensions: Allowing extension functions to be resolved statically, potentially improving performance and clarity.
* Collection Literals: Introducing a more concise syntax for creating collections, like using square brackets for lists, with efficient implementations.
* Name-Based Destructuring: Offering a more flexible way to destructure objects based on property names rather than just position.
* Context Receivers: A powerful feature for providing contextual information to functions in a more implicit and structured manner. This feature, however, is being approached carefully to ensure it aligns well with Kotlin’s principles.
* Explicit Fields: Providing more control over backing fields for properties.

The team emphasized a careful approach to evolving the language, ensuring new features are well-designed and maintainable. Compiler plugins were also highlighted as an avenue for extending Kotlin’s capabilities.

Kotlin in the Ecosystem: Google’s Investment and Multiplatform Growth

Grace Kloba from Google took the stage to reiterate Google’s strong commitment to Kotlin. She shared insights into Google’s investments in the Kotlin ecosystem, including the development of Kotlin Symbol Processing (KSP) and the continued focus on making Kotlin the default choice for Android development. Google officially supported Kotlin for Android development by early 2017. The Kotlin DSL is now the default for Gradle build scripts in Android Studio, enhancing developer experience with features like semantic highlighting and code completion. Google also actively contributes to the Kotlin Foundation and encourages the community to participate through programs like the Kotlin Foundation Grants Program, which focuses on supporting multiplatform libraries and frameworks.

Kotlin Multiplatform (KMP) was another major highlight, showcasing its growing maturity and adoption. The vision for KMP is to allow developers to share code across various platforms—Android, iOS, desktop, web, and server-side—while retaining the ability to write platform-specific code when needed. The keynote celebrated the increasing number of multiplatform libraries and tools, including KMM Bridge, that simplify KMP development. The future of KMP looks bright, with efforts to further improve the developer experience and expand its capabilities.

Compose Multiplatform and Emerging Technologies

The keynote also showcased the advancements in Compose Multiplatform, JetBrains’ declarative UI framework for building cross-platform user interfaces. A significant announcement was the alpha release of Compose Multiplatform for iOS, enabling developers to write their UI once in Kotlin and deploy it on both Android and iOS, and even desktop and web. This opens up new possibilities for code sharing and faster development cycles for mobile applications.

Finally, the team touched upon Kotlin’s expansion into emerging technologies like WebAssembly (Wasm). JetBrains is developing a new compiler backend for Kotlin targeting WebAssembly with its garbage collection proposal, aiming for high-performance Kotlin code in the browser. Experiments with running Compose applications in the browser using WebAssembly were also mentioned, hinting at a future where Kotlin could offer a unified development experience across an even wider range of platforms. The keynote concluded with an invitation for the community to dive deeper into these topics during the conference and to continue contributing to Kotlin’s vibrant ecosystem.

Links: