Recent Posts
Archives

Posts Tagged ‘FunctionalProgramming’

PostHeaderIcon [PHPForumParis2022] Exploring DDD and Functional Programming Practices – Benjamin Rambaud

Benjamin Rambaud, an accomplished PHP engineer at ekino, delivered an engaging presentation at PHP Forum Paris 2022, inviting developers to explore Domain-Driven Design (DDD) and functional programming to enhance their craft. With a nod to the collaborative spirit of the event, Benjamin adopted a market-like metaphor, encouraging attendees to “pick and choose” principles from DDD and functional programming to enrich their PHP projects. His talk, informed by his role as a co-organizer of AFUP Bordeaux, offered practical insights into improving code quality and project communication, drawing from established methodologies while urging developers to adapt them thoughtfully.

Foundations of Domain-Driven Design

Benjamin opened by demystifying DDD, a methodology focused on modeling complex business domains with precision. He emphasized the Ubiquitous Language, a shared vocabulary that aligns developers, stakeholders, and domain experts, fostering clearer communication. By prioritizing domain logic over technical details, DDD isolates business rules, making code more maintainable and expressive. Benjamin illustrated this with examples from his work at ekino, showing how DDD’s strategic patterns, like bounded contexts, help developers encapsulate business logic effectively, reducing framework dependency.

Leveraging Functional Programming

Shifting to functional programming, Benjamin highlighted its synergy with PHP’s multi-paradigm nature. He introduced concepts like pure functions, immutability, and value objects, which enhance testability and predictability. By integrating these principles, developers can create robust, error-resistant codebases. Benjamin drew from his experience with Drupal, demonstrating how functional programming complements DDD by isolating domain logic from framework-specific code, allowing for greater flexibility and maintainability in PHP projects.

Practical Implementation and Hexagonal Architecture

Delving into practical applications, Benjamin advocated for hexagonal architecture as a cornerstone of DDD in PHP. This approach uses ports and adapters to decouple business logic from external systems, enabling seamless integration with frameworks like Symfony. He cautioned against rigid adherence to frameworks, referencing resources like Mathias Verraes’ blog for deeper insights into DDD patterns. Benjamin’s practical advice, grounded in real-world examples, encouraged developers to experiment with repositories and interfaces tailored to their project’s needs, fostering adaptable and resilient code.

Balancing Frameworks and Principles

Concluding, Benjamin urged developers to understand their frameworks deeply while embracing external paradigms to avoid being constrained by default configurations. He emphasized that DDD and functional programming are not rigid doctrines but flexible tools to be adapted contextually. By encouraging exploration of languages like Elixir or OCaml, Benjamin inspired attendees to broaden their perspectives, enhancing their ability to craft high-quality, business-aligned PHP applications through thoughtful experimentation.

Links:

PostHeaderIcon [PHPForumParis2021] Exceptions: The Weak Spot in PHP’s Type System – Baptiste Langlade

Baptiste Langlade, a PHP developer at EFI Automotive, captivated the Forum PHP 2021 audience with a deep dive into the limitations of exceptions in PHP’s type system. With a decade of experience in PHP and open-source contributions, Baptiste explored how exceptions disrupt type safety and proposed functional programming-inspired solutions. His talk combined technical rigor with practical insights, urging developers to rethink error handling. This post covers four themes: the problem with exceptions, functional programming alternatives, automating error handling, and challenges with interfaces.

The Problem with Exceptions

Baptiste Langlade began by highlighting the inherent flaws in PHP’s exception system, describing it as a “hole in the type system’s racket.” Exceptions, he argued, bypass type checks, leading to unexpected runtime errors that static analysis struggles to catch. Drawing on his work at EFI Automotive, Baptiste illustrated how unchecked exceptions in complex systems, like document management, can lead to fragile code, emphasizing the need for more robust error-handling mechanisms.

Functional Programming Alternatives

Drawing inspiration from functional programming, Baptiste proposed alternatives like the Either monad to handle errors explicitly without exceptions. He demonstrated how returning values that encapsulate success or failure states can improve type safety and predictability. By sharing examples from his open-source packages, Baptiste showed how these patterns integrate with PHP, offering developers a way to write cleaner, more reliable code that aligns with modern type-safe practices.

Automating Error Handling

Baptiste emphasized the importance of automating error detection to address the limitations of manual exception testing. He noted that developers often miss edge cases when writing unit tests, leading to uncaught exceptions. Tools like static analyzers can help by enforcing explicit error handling, but Baptiste cautioned that PHP currently lacks native support for declaring thrown exceptions in method signatures, unlike languages like Java. His insights urged developers to adopt rigorous testing practices to mitigate these risks.

Challenges with Interfaces

Concluding his talk, Baptiste addressed the challenges of using exceptions with PHP interfaces. He explained that interfaces cannot enforce specific exception types, limiting their utility in ensuring type safety. By exploring workarounds, such as explicit documentation and custom error types, Baptiste provided practical solutions for developers. His talk encouraged the PHP community to push for language improvements, drawing on his experiences to advocate for a more robust type system.

Links:

PostHeaderIcon [ScalaDaysNewYork2016] Implicits Inspected and Explained: Demystifying Scala’s Power

At Scala Days New York 2016, Tim Soethout, a functional programmer at ING Bank, offered a comprehensive guide to Scala’s implicits, a feature often perceived as magical by developers transitioning from basic to advanced Scala programming. Tim’s presentation bridged this gap, providing clear explanations and practical examples to demonstrate how implicits enhance code expressiveness and flexibility.

Understanding Implicits

Tim Soethout began by defining implicits as a mechanism for providing values or conversions without explicit references, enabling concise and flexible code. Drawing parallels with object-oriented programming, Tim explained that implicits extend “is-a” and “has-a” relationships with “is-viewable-as,” allowing developers to add rich interfaces to existing types. For instance, in Akka, the ! (tell) operator uses an implicit sender parameter, simplifying message passing. Similarly, Scala’s Futures rely on implicit execution contexts to manage asynchronous operations, abstracting thread scheduling from developers.

Compiler Resolution of Implicits

A key focus of Tim’s talk was demystifying how the Scala compiler resolves implicits. He outlined the compiler’s search process, which prioritizes local scope, companion objects, and package objects related to the involved types. Tim cautioned against implicit conversions with mismatched semantics, as they can lead to unexpected behavior. Using a live coding demo, he illustrated how implicits enable expressive DSLs, such as JSON serialization libraries, by automatically resolving type-specific writers, thus reducing boilerplate code.

Type Classes and Extensibility

Tim explored type classes as a powerful application of implicits, allowing non-intrusive library extensions. By defining behaviors like JSON serialization in companion objects, developers can extend functionality without modifying core libraries. He demonstrated this with a JSON writer example, where implicits ensured type-safe serialization for complex data structures. Tim emphasized that this approach fosters loose coupling, making libraries more modular and easier to maintain.

Practical Debugging Tips

Addressing common challenges, Tim offered strategies for debugging implicits, such as inspecting bytecode or leveraging IDEs to trace implicit resolutions. He warned against chaining multiple implicit conversions, as the compiler restricts itself to a single conversion to avoid complexity. By sharing practical examples, Tim equipped developers with the tools to harness implicits effectively, ensuring they enhance rather than obscure code clarity.

Links:

PostHeaderIcon [ScalaDaysNewYork2016] Scala’s Road Ahead: Shaping the Future of a Versatile Language

Scala, a language renowned for blending functional and object-oriented programming, stands at a pivotal juncture as outlined by its creator, Martin Odersky, in his keynote at Scala Days New York 2016. Martin’s address explored Scala’s unique identity, recent developments like Scala 2.12 and the Scala Center, and the experimental Dotty compiler, offering a vision for the language’s evolution over the next five years. This talk underscored Scala’s commitment to balancing simplicity, power, and theoretical rigor while addressing community needs.

Scala’s Recent Milestones

Martin began by reflecting on Scala’s steady growth, evidenced by increasing job postings and Google Trends for Scala tutorials. The establishment of the Scala Center marks a significant milestone, providing a hub for community collaboration with support from industry leaders like Lightbend and Goldman Sachs. Additionally, Scala 2.12, set for release in mid-2016, optimizes for Java 8, leveraging lambdas and default methods to produce more compact and faster code. This release, with 33 new features and contributions from 65 committers, reflects Scala’s vibrant community and commitment to progress.

The Scala Center: Fostering Community Collaboration

The Scala Center, as Martin described, serves as a steward for Scala, focusing on projects that benefit the entire community. By coordinating contributions and fostering industrial partnerships, it aims to streamline development and ensure Scala’s longevity. While Martin deferred detailed discussion to Heather Miller’s keynote, he emphasized the center’s role in unifying efforts to enhance Scala’s ecosystem, making it a cornerstone for future growth.

Dotty: A New Foundation for Scala

Central to Martin’s vision is Dotty, a new Scala compiler built on the Dependent Object Types (DOT) calculus. This theoretical foundation, proven sound after an eight-year effort, provides a robust basis for evaluating new language features. Dotty, with a leaner codebase of 45,000 lines compared to the current compiler’s 75,000, offers faster compilation and simplifies the language’s internals by encoding complex features like type parameters into a minimal subset. This approach enhances confidence in language evolution, allowing developers to experiment with new constructs without compromising stability.

Evolving Scala’s Libraries

Looking beyond Scala 2.12, Martin outlined plans for Scala 2.13, focusing on revamping the standard library, particularly collections. Inspired by Spark’s lazy evaluation and pair datasets, Scala aims to simplify collections while maintaining compatibility. Proposals include splitting the library into a core module, containing essentials like collections, and a platform module for additional functionalities like JSON handling. This modular approach would enable dynamic updates and broader community contributions, addressing the challenges of maintaining a monolithic library.

Addressing Language Complexity

Martin acknowledged Scala’s reputation for complexity, particularly with features like implicits, which, while powerful, can lead to unexpected behavior if misused. To mitigate this, he proposed style guidelines, such as the principle of least power, encouraging developers to use the simplest constructs necessary. Additionally, he suggested enforcing rules for implicit conversions, limiting them to packages containing the source or target types to reduce surprises. These measures aim to balance Scala’s flexibility with usability, ensuring it remains approachable.

Future Innovations: Simplifying and Strengthening Scala

Martin’s vision for Scala includes several forward-looking features. Implicit function types will reduce boilerplate by abstracting over implicit parameters, while effect systems will treat side effects like exceptions as capabilities, enhancing type safety. Nullable types, modeled as union types, address Scala’s null-related issues, aligning it with modern languages like Kotlin. Generic programming improvements, inspired by libraries like Shapeless, aim to eliminate tuple limitations, and better records will support data engines like Spark. These innovations, grounded in Dotty’s foundations, promise a more robust and intuitive Scala.

Links:

PostHeaderIcon [DevoxxBE2013] Part 1: Thinking Functional Style

Venkat Subramaniam, an award-winning author and founder of Agile Developer, Inc., guides developers through the paradigm shift of functional programming on the JVM. Renowned for Functional Programming in Java and his global mentorship, Venkat uses Java 8, Groovy, and Scala to illustrate functional tenets. His session contrasts imperative statements with composable expressions, demonstrating how to leverage lambda expressions and higher-order functions for elegant, maintainable code.

Functional programming, Venkat posits, transcends syntax—it’s a mindset fostering immutability and data flow. Through practical examples, he showcases Groovy’s idiomatic functional constructs and Scala’s expression-driven purity, equipping attendees to rethink application design.

Functional Principles and Expressions

Venkat contrasts statements—imperative, mutation-driven blocks—with expressions, which compute and return values. He demos a Java 8 stream pipeline, transforming data without side effects, versus a loop’s mutability.

Expressions, Venkat emphasizes, enable seamless composition, fostering cleaner, more predictable codebases.

Groovy’s Functional Idioms

Groovy, though not purely functional, excels in functional style, Venkat illustrates. He showcases collect and findAll for list transformations, akin to Java 8 streams, with concise closures.

These idioms, he notes, simplify data processing, making functional patterns intuitive for Java developers.

Scala’s Expression-Driven Design

Scala’s expression-centric nature shines in Venkat’s examples: every construct returns a value, enabling chaining. He demos pattern matching and for-comprehensions, streamlining complex workflows.

This purity, Venkat argues, minimizes state bugs, aligning with functional ideals.

Higher-Order Functions and Composition

Venkat explores higher-order functions, passing lambdas as arguments. A Groovy example composes functions to filter and map data, while Scala’s currying simplifies partial application.

Such techniques, he asserts, enhance modularity, enabling parallelization for performance-critical tasks.

Practical Adoption and Parallelization

Venkat advocates starting with small functional refactors, like replacing loops with streams. He demos parallel stream processing in Java 8, leveraging multi-core CPUs.

This pragmatic approach, he concludes, bridges imperative habits with functional elegance, boosting scalability.

Links:

PostHeaderIcon [DevoxxFR2014] Reactive Programming with RxJava: Building Responsive Applications

Lecturer

Ben Christensen works as a software engineer at Netflix. He leads the development of reactive libraries for the JVM. Ben serves as a core contributor to RxJava. He possesses extensive experience in constructing resilient, low-latency systems for streaming platforms. His expertise centers on applying functional reactive programming principles to microservices architectures.

Abstract

This article provides an in-depth exploration of RxJava, Netflix’s implementation of Reactive Extensions for the JVM. It analyzes the Observable pattern as a foundation for composing asynchronous and event-driven programs. The discussion covers essential operators for data transformation and composition, schedulers for concurrency management, and advanced error handling strategies. Through concrete Netflix use cases, the article demonstrates how RxJava enables non-blocking, resilient applications and contrasts this approach with traditional callback-based paradigms.

The Observable Pattern and Push vs. Pull Models

RxJava revolves around the Observable, which functions as a push-based, composable iterator. Unlike the traditional pull-based Iterable, Observables emit items asynchronously to subscribers. This fundamental duality enables uniform treatment of synchronous and asynchronous data sources:

Observable<String> greeting = Observable.just("Hello", "RxJava");
greeting.subscribe(System.out::println);

The Observer interface defines three callbacks: onNext for data emission, onError for exceptions, and onCompleted for stream termination. RxJava enforces strict contracts for backpressure—ensuring producers respect consumer consumption rates—and cancellation through unsubscribe operations.

Operator Composition and Declarative Programming

RxJava provides over 100 operators that transform, filter, and combine Observables in a declarative manner. These operators form a functional composition pipeline:

Observable.range(1, 10)
          .filter(n -> n % 2 == 0)
          .map(n -> n * n)
          .subscribe(square -> System.out.println("Square: " + square));

The flatMap operator proves particularly powerful for concurrent operations, such as parallel API calls:

Observable<User> users = getUserIds();
users.flatMap(userId -> userService.getDetails(userId), 5)
     .subscribe(user -> process(user));

This approach eliminates callback nesting (callback hell) while maintaining readability and composability. Marble diagrams visually represent operator behavior, illustrating timing, concurrency, and error propagation.

Concurrency Control with Schedulers

RxJava decouples computation from threading through Schedulers, which abstract thread pools:

Observable.just(1, 2, 3)
          .subscribeOn(Schedulers.io())
          .observeOn(Schedulers.computation())
          .map(this::cpuIntensiveTask)
          .subscribe(result -> display(result));

Common schedulers include:
Schedulers.io() for I/O-bound operations (network, disk).
Schedulers.computation() for CPU-bound tasks.
Schedulers.newThread() for fire-and-forget operations.

This abstraction enables non-blocking I/O without manual thread management or blocking queues.

Error Handling and Resilience Patterns

RxJava treats errors as first-class citizens in the data stream:

Observable risky = Observable.create(subscriber -> {
    subscriber.onNext(computeRiskyValue());
    subscriber.onError(new RuntimeException("Failed"));
});
risky.onErrorResumeNext(throwable -> Observable.just("Default"))
     .subscribe(value -> System.out.println(value));

Operators like retry, retryWhen, and onErrorReturn implement resilience patterns such as exponential backoff and circuit breakers—critical for microservices in failure-prone networks.

Netflix Production Use Cases

Netflix employs RxJava across its entire stack. The UI layer composes multiple backend API calls for personalized homepages:

Observable<Recommendation> recs = userIdObservable
    .flatMap(this::fetchUserProfile)
    .flatMap(profile -> Observable.zip(
        fetchTopMovies(profile),
        fetchSimilarUsers(profile),
        this::combineRecommendations));

The API gateway uses RxJava for timeout handling, fallbacks, and request collapsing. Backend services leverage it for event processing and data aggregation.

Broader Impact on Software Architecture

RxJava embodies the Reactive Manifesto principles: responsive, resilient, elastic, and message-driven. It eliminates common concurrency bugs like race conditions and deadlocks. For JVM developers, RxJava offers a functional, declarative alternative to imperative threading models, enabling cleaner, more maintainable asynchronous code.

Links:

PostHeaderIcon [DevoxxBE2013] Lambda: A Peek Under the Hood

Brian Goetz, Java Language Architect at Oracle, offers an illuminating dissection of lambda expressions in Java SE 8, transcending syntactic sugar to reveal the sophisticated machinery powering this evolution. Renowned for Java Concurrency in Practice and leadership in JSR 335, Brian demystifies lambdas’ implementation atop invokedynamic from Java SE 7. His session, eschewing introductory fare, probes the VM’s strategies for efficiency, contrasting naive inner-class approaches with optimized bootstrapping and serialization.

Lambdas, Brian asserts, unlock expressive potential for applications and libraries, but their true prowess lies in performance rivaling or surpassing inner classes—without the bloat. Through benchmarks and code dives, he showcases flexibility and future-proofing, underscoring the iterative path to a robust design.

From Syntax to Bytecode: The Bootstrap Process

Brian traces lambdas’ lifecycle: source code desugars to invokedynamic callsites, embedding a “recipe” for instantiation. The bootstrap method, invoked once per callsite, crafts a classfile dynamically, caching for reuse.

This declarative embedding, Brian illustrates, avoids inner classes’ per-instance overhead, yielding leaner bytecode and faster captures—non-capturing lambdas hit 1.5x inner-class speeds in early benchmarks.

Optimization Strategies and Capture Semantics

Capturing lambdas, Brian explains, leverage local variable slots via synthetic fields, minimizing allocations. He contrasts “eager” (immediate class creation) with “lazy” (deferred) strategies, favoring the latter for reduced startup.

Invokedynamic’s dynamic binding enables profile-guided refinements, promising ongoing gains. Brian’s throughput metrics affirm lambdas’ edge, even in capturing scenarios.

Serialization and Bridge Methods

Serializing lambdas invokes writeReplace to a serialized form, preserving semantics without runtime overhead. Brian demos bridge methods for functional interfaces, ensuring compatibility.

Default methods, he notes, extend interfaces safely, avoiding binary breakage—crucial for library evolution.

Lessons from Language Evolution

Brian reflects on Lambda’s odyssey: discarded ideas like inner-class syntactic variants paved the way for invokedynamic’s elegance. This resilience, he posits, exemplifies evolving languages amid obvious-but-flawed intuitions.

Project Lambda’s resources—OpenJDK docs, JCP reviews—invite deeper exploration, with binary builds for experimentation.

Links:

PostHeaderIcon [DevoxxFR2013] WTF – What’s The Fold?

Lecturer

Olivier Croisier operates as a freelance Java expert, trainer, and speaker through Moka Technologies. With over twelve years in the field, he assists clients in Java 8 migrations, advanced stack development, and revitalizing team enthusiasm for coding.

Abstract

Olivier Croisier elucidates the fold concept from functional programming, demonstrating its abstraction of iteration for enhanced code expressiveness. Using Java 8 streams and Haskell parallels, he dissects implementations, applications in mapping/filtering/reducing, and performance implications. The analysis positions fold as a versatile pattern surpassing traditional loops, integrable even in pre-Java 8 environments.

Origins and Essence: Fold as Iterative Abstraction

Croisier traces fold to functional languages like Haskell, where it generalizes accumulation over collections. Left fold (foldl) processes sequentially; right fold (foldr) enables laziness.

In essence, fold applies a binary operation cumulatively: start with accumulator, combine with each element.

Java analogy: external iterators (for-loops) versus internal (streams). Fold internalizes control, yielding concise, composable code.

Implementing Fold in Java: From Basics to Streams

Pre-Java 8, Croisier crafts a utility:

public static <T, R> R fold(Collection<T> coll, R init, BiFunction<R, T, R> f) {
    R acc = init;
    for (T e : coll) acc = f.apply(acc, e);
    return acc;
}

Usage: sum integers—fold(list, 0, (a, b) -> a + b).

Java 8 streams natively provide reduce (fold alias):

int sum = list.stream().reduce(0, Integer::sum);

Parallel streams distribute: .parallelStream().reduce().

Croisier notes identity requirement for parallelism; non-associative operations risk inconsistencies.

Beyond Reduction: Mapping, Filtering, and Collection Building

Fold transcends summing; rebuild collections:

List<String> mapped = fold(list, new ArrayList<>(), (acc, e) -> { acc.add(transform(e)); return acc; });

Filter via conditional accumulation. This unifies operations—map/filter as specialized folds.

Haskell’s foldr constructs lists lazily, enabling infinite structures. Java’s eager evaluation limits but streams offer similar chaining.

Expressive Power and Performance Trade-offs

Croisier contrasts verbose loops with declarative folds, enhancing readability/maintainability. Encapsulate patterns in methods for reuse/optimization.

Performance: sequential folds match loops; parallel leverages multicore but incurs overhead (threading, combining).

JVM optimizations (invokedynamic for lambdas) potentially outperform anonymous classes. Croisier advocates testing under load.

Versus map-reduce: fold suits in-memory; Hadoop for distributed big data.

Integration Strategies and Broader Implications

Adopt incrementally: utility class for legacy code. Java 8+ embraces streams.

Croisier views fold as expressivity tool—not replacing conditionals but abstracting mechanics.

Implications: functional paradigms ease concurrency, prepare for multicore era. Fold’s versatility—from reductions to transformations—elevates code abstraction.

Links:

PostHeaderIcon [DevoxxFR2013] FLATMAP ZAT SHIT: Monads Explained to Geeks

Lecturer

François Sarradin is a Java and lambda developer, serving as a technical capitalization manager. He contributes to the Brown Bag Lunch initiative, sharing expertise through presentations.

Abstract

François Sarradin’s session introduces monads in functional programming, using Scala and Java 8 examples to demystify their utility. He addresses handling errors, asynchrony, and technical concerns without cluttering business logic, employing monadic structures like Try and Future. The talk analyzes code transformations for cleaner, composable designs, highlighting monads’ role in aspect-oriented programming and drawing parallels to AOP frameworks.

The Problem: Technical Debt Obscuring Business Logic

Sarradin illustrates a common plight: initial clean code accumulates technical safeguards—null checks, try-catch blocks, synchronization—eroding readability and productivity. He proposes separating concerns: keep business logic pure, inject technical aspects via mechanisms akin to aspect-oriented programming (AOP).

Using AOP tools like AspectJ or Spring AOP declares cross-cutting concerns (e.g., logging, error handling) separately, leveraging compilers for coherence. This maintains original code structure while addressing realities like exceptions or async calls.

An example application in Scala computes total balance across bank accounts, initially straightforward but vulnerable. Technical intrusions (e.g., if-null, try-catch) bloat it, prompting a search for elegant solutions.

Introducing Monads: Error Handling with Try

To manage errors without pervasive checks, Sarradin introduces the Try monad in Scala: a container wrapping success (Success(value)) or failure (Failure(exception)). This allows chaining operations via flatMap and map, propagating errors implicitly.

Transforming the balance app: wrap account retrieval in Try, use for-comprehensions (sugaring flatMap/map) for composition. If any step fails, the whole computation fails gracefully, without explicit exception handling.

Code evolves from imperative checks to declarative chains:

val total = for {
  account1 <- Try(getAccount(bank1))
  account2 <- Try(getAccount(bank2))
  balance1 <- Try(getBalance(account1))
  balance2 <- Try(getBalance(account2))
} yield balance1 + balance2

This yields Try[Double], inspectable via isSuccess, get, or getOrElse. Monads here abstract error propagation, enhancing modularity.

Java 8’s Optional partially mirrors this but lacks full monadic power; Sarradin implements a custom Try for illustration, using abstract classes with Success/Failure subclasses.

Extending to Asynchrony: Futures for Non-Blocking Computations

Asynchrony poses similar issues: callbacks or blocking awaits disrupt flow. Scala’s Future monad encapsulates eventual values, enabling composition without blocking.

In the app, wrap async calls in Future: use flatMap to chain, ensuring non-blocking execution. For-comprehensions again simplify:

val totalFuture = for {
  account1 <- Future(getAccountAsync(bank1))
  account2 <- Future(getAccountAsync(bank2))
  balance1 <- Future(getBalanceAsync(account1))
  balance2 <- Future(getBalanceAsync(account2))
} yield balance1 + balance2

totalFuture completes asynchronously; callbacks via onComplete handle results. This maintains sequential appearance while parallelizing under the hood.

Sarradin contrasts with Java 8’s CompletableFuture, which offers thenApply/thenCompose for similar chaining, though less idiomatic without for-comprehensions.

Monads as a Unifying Abstraction: Synthesis and Implications

Monads generalize: a type M[A] with map (transform value) and flatMap (chain computations). They inject contexts (error, future) into pure functions, separating concerns.

In the app, combining Try and Future (via Scalaz’s EitherT or custom) handles both errors and asynchrony. This AOP-like injection leverages type systems for safety, contrasting annotation-based AOP.

Java 8 approximates with lambdas and CompletableFuture/Optional, but lacks Scala’s expressiveness. Custom implementations reveal monads’ essence: abstract class with map/flatMap, subclasses for Success/Failure.

Sarradin concludes monads enhance composability, reducing boilerplate for robust, maintainable code in functional paradigms.

Relevant Links and Hashtags

Links:

PostHeaderIcon [DevoxxFR2013] Objects and Functions: Conflict Without a Cause?

Lecturer

Martin Odersky is a professor at EPFL in Lausanne, Switzerland, specializing in programming languages that blend object-oriented and functional paradigms. His research unifies these approaches, evidenced by designs like Pizza, GJ, and Functional Nets. He co-designed Java generics and authored the original javac compiler. Currently, he focuses on Scala, fusing functional and object-oriented programming while ensuring interoperability with Java and .NET.

Abstract

Martin Odersky’s lecture traces object-oriented programming’s (OOP) rise, parallels it with functional programming’s (FP) resurgence, and argues for their synthesis. Analyzing historical catalysts, methodological benefits, and modern hardware demands, he demonstrates how FP addresses parallelism and reactivity challenges. Through Scala examples, Odersky shows OOP and FP as complementary, enhancing modularity and abstraction without mutual exclusion.

Historical Roots and Catalysts for OOP Adoption

Odersky recounts his journey from Pascal compilers to modular languages, Java involvement, and Scala creation. OOP’s mainstreaming, he argues, stemmed not from encapsulation or reuse but practical necessities. Simula (1967) for simulations and Smalltalk (late 1970s) for GUI widgets inverted traditional data structures: fixed operations, unbounded implementations.

In procedural languages like C, this was cumbersome via function pointers; OOP simplified dynamic binding for unknown implementations. Odersky notes early confusion with Smalltalk, mirroring current FP bewilderment. OOP’s advantages – modeling, dependency inversion – emerged post-adoption, sparked by widget programming appeal.

Functional Programming’s Resurgence and Methodological Strengths

FP offers fewer errors, superior modularity, and productivity via higher abstractions and shorter code. Yet, despite 50-year existence, mainstream adoption lagged. Odersky identifies multicore and cloud computing as catalysts: parallelism for hardware utilization, reactivity for asynchronous events, distribution for delays/failures.

Mutable state exacerbates issues like cache coherence and non-determinism in concurrent environments. Immutable data mitigates races, enabling safe caching. Locks/threads scale poorly; even transactions retain problems. FP’s immutability fosters determinism, crucial for scalable systems.

Addressing Modern Computing Challenges with FP

Odersky outlines a triple challenge: parallel, reactive, distributed programming. Mutable state hinders each; FP excels by avoiding it.

For parallelism, he exemplifies mapping developer names: sequential in Scala, parallel via .par, yielding a parallel collection. Side effects risk chaos due to reordered executions, necessitating functional purity for correctness.

Reactivity example: an online store querying users, orders, products, stock. Synchronous calls block threads on slow services, degrading performance. Asynchronous futures prevent blocking; Scala’s for-comprehensions compose them elegantly, hiding complexity. Refactoring for parallelism pairs futures, executing concurrently.

For-comprehensions translate universally to map, flatMap, filter, allowing library-defined interpretations – sequential or async – without polluting domain logic.

Synthesizing OOP and FP: Beyond False Dichotomies

Communities often view OOP and FP oppositely, but Odersky argues orthogonality. Objects modularize (“what goes where”), providing containers with dynamic binding and inheritance. Essential for large codebases (e.g., million-line Scala systems), they prevent global namespace chaos – a Haskell limitation.

Redefine objects: eliminate mutable state dogma (e.g., immutable java.lang.String), structural equality over identity, focus on behavior. Scala embodies this fusion, modeling algebraic types with objects while importing FP capabilities.

Scala unifies scripting (winning JavaOne Script Bowl) and safe, performant systems (core for Twitter, LinkedIn). Odersky concludes OOP/FP synergy enhances development, urging exploration via Scala Days, courses, and talks.

Relevant Links and Hashtags

Links: