Recent Posts
Archives

Posts Tagged ‘Immutability’

PostHeaderIcon [DevoxxPL2022] Are Immortal Libraries Ready for Immutable Classes? • Tomasz Skowroński

At Devoxx Poland 2022, Tomasz Skowroński, a seasoned Java developer, delivered a compelling presentation exploring the readiness of Java libraries for immutable classes. With a focus on the evolving landscape of Java programming, Tomasz dissected the challenges and opportunities of adopting immutability in modern software development. His talk provided a nuanced perspective on balancing simplicity, clarity, and robustness in code design, offering practical insights for developers navigating the complexities of mutable and immutable paradigms.

The Allure and Pitfalls of Mutable Classes

Tomasz opened his discourse by highlighting the appeal of mutable classes, likening them to a “shy green boy” for their ease of use and rapid development. Mutable classes, with their familiar getters and setters, simplify coding and accelerate project timelines, making them a go-to choice for many developers. However, Tomasz cautioned that this simplicity comes at a cost. As fields and methods accumulate, mutable classes grow increasingly complex, undermining their initial clarity. The internal state becomes akin to a data structure, vulnerable to unintended modifications, which complicates maintenance and debugging. This fragility, he argued, often leads to issues like null pointer exceptions and challenges in maintaining a consistent state, particularly in large-scale systems.

The Promise of Immutability

Transitioning to immutability, Tomasz emphasized its role in fostering robust and predictable code. Immutable classes, by preventing state changes after creation, offer a safeguard against unintended modifications, making them particularly valuable in concurrent environments. He clarified that immutability extends beyond merely marking fields as final or using tools like Lombok. Instead, it requires a disciplined approach to design, ensuring objects remain unalterable. Tomasz highlighted Java records and constructor-based classes as practical tools for achieving immutability, noting their ability to streamline code while maintaining clarity. However, he acknowledged that immutability introduces complexity, requiring developers to rethink traditional approaches to state management.

Navigating Java Libraries with Immutability

A core focus of Tomasz’s presentation was the compatibility of Java libraries with immutable classes. He explored tools like Jackson for JSON deserialization, noting that while modern libraries support immutability through annotations like @ConstructorProperties, challenges persist. For instance, deserializing complex objects may require manual configuration or reliance on Lombok to reduce boilerplate. Tomasz also discussed Hibernate, where immutable entities, such as events or finalized invoices, can express domain constraints effectively. By using the @Immutable annotation and configuring Hibernate to throw exceptions on modification attempts, developers can enforce immutability, though direct database operations remain a potential loophole.

Practical Strategies for Immutable Design

Tomasz offered actionable strategies for integrating immutability into everyday development. He advocated for constructor-based dependency injection over field-based approaches, reducing boilerplate with tools like Lombok or Java records. For RESTful APIs, he suggested mapping query parameters to immutable DTOs, enhancing clarity and reusability. In the context of state management, Tomasz proposed modeling state transitions in immutable classes using interfaces and type-safe implementations, as illustrated by a rocket lifecycle example. This approach ensures predictable state changes without the risks associated with mutable methods. Additionally, he addressed performance concerns, arguing that the overhead of object creation in immutable designs is often overstated, particularly in web-based systems where network latency dominates.

Testing and Tooling Considerations

Testing immutable classes presents unique challenges, particularly with tools like Mockito. Tomasz noted that while Mockito supports final classes in newer versions, mocking immutable objects may indicate design flaws. Instead, he recommended creating real objects via constructors for testing, emphasizing their intentional design for construction. For developers working with legacy systems or external libraries, Tomasz advised cautious adoption of immutability, leveraging tools like Terraform for infrastructure consistency and Java’s evolving ecosystem to reduce boilerplate. His pragmatic approach underscored the importance of aligning immutability with project goals, avoiding dogmatic adherence to either mutable or immutable paradigms.

Embracing Immutability in Java’s Evolution

Concluding his talk, Tomasz positioned immutability as a cornerstone of Java’s ongoing evolution, from records to potential future enhancements like immutable collections. He urged developers to reduce mutation in their codebases and consider immutability beyond concurrency, citing benefits in caching, hashing, and overall design clarity. While acknowledging that mutable classes remain suitable for certain use cases, such as JPA entities in dynamic domains, Tomasz advocated for a mindful approach to code design, prioritizing immutability where it enhances robustness and maintainability.

Links:

PostHeaderIcon [DevoxxBE2012] First Steps with Scala (Part 1/2)

In an engaging session, Dick Wall and Bill Venners, co-founders of Escalate Software and prominent figures in the Scala community, introduced newcomers to the Scala programming language. Dick, known for his JavaPosse involvement, and Bill, president of Artima and author of key Java texts, adapted their training curriculum to cover foundational elements. Their approach fused object-oriented and functional paradigms, emphasizing Scala’s blend of familiarity and innovation.

They commenced with the Scala REPL, a tool they use daily for experimentation. This interactive shell allows immediate code execution, inferring types and storing results for reuse, making it invaluable even for Java developers exploring libraries.

Dick and Holly—wait, Dick and Bill—highlighted Scala’s strong typing with inference, reducing boilerplate while maintaining safety. They demonstrated basic operations, showing how everything integrates into a unified hierarchy, unlike Java’s primitives and references.

Defining Variables and Immutability

Transitioning to variables, Dick and Bill distinguished between vals (immutable) and vars (mutable), promoting vals for reliability. This design choice encourages constant use without extra syntax, contrasting Java’s final keyword. They illustrated reassignment errors, noting REPL’s scoping allows redefinitions, mimicking nested blocks.

Type specifications, optional due to inference, follow names with colons, inverting Java’s order for natural flow. Examples showed string inferences and explicit declarations, underscoring flexibility.

They addressed mutability choices, advising private volatile vars for necessary changes, or mutable objects within immutable structures, depending on context.

Control Structures and Expressions

Dick and Bill explored control structures, revealing Scala’s expression-oriented nature. If statements return values, enabling concise assignments without ternaries. While loops, though imperative, yield Unit, encouraging functional alternatives.

For comprehensions, powerful for iteration, support guards and yields, transforming collections declaratively. They demonstrated filtering even numbers or yielding transformed lists, highlighting pattern matching integration.

Try-catch blocks, also expressions, handle exceptions functionally, with finally clauses for cleanup. This uniformity simplifies code, treating controls as value producers.

Functions and Closures

Delving into functions, they defined them as objects, enabling higher-order usage. Simple defs showed parameter typing and inference, with return types often omitted.

Function literals, akin to lambdas, capture environments as closures, allowing deferred execution. Examples illustrated anonymous functions for mapping or filtering, emphasizing Scala’s functional leanings.

They introduced by-name parameters for lazy evaluation, useful in custom controls like loops, mimicking built-in syntax without special privileges.

Collections and Functional Programming

Scala collections, immutable by default, support transformations via methods like map and filter. Dick and Bill showcased creating lists, accessing elements, and applying operations, yielding new collections without mutation.

They contrasted mutable variants, advising caution for concurrency. For comprehensions over collections generate new ones, combining iteration with functional purity.

Approaching functional style, they encouraged avoiding side effects, using recursion or folds for aggregations, fostering predictable code.

Advanced Basics and Q&A Insights

In Q&A, they addressed optimizations: Scala uses primitives internally, with @specialized for generics avoiding boxing. Profiling mirrors Java tools, with quirks in coverage.

Dick and Bill wrapped by previewing afternoon labs on Scala Koans, urging practice. Their session laid a solid groundwork, blending theory with practical demos, preparing attendees for Scala’s expressive power.

Links: