From bae9c377c51a7d8d58e5d5fb43ab51dbf3e53f5c Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Tue, 24 Dec 2024 17:32:55 +0000 Subject: [PATCH 01/13] algebraic data types and pattern matching with java Signed-off-by: Magnus Smith --- ...25-01-09-algebraic-data-types-with-java.md | 425 ++++++++++++++++++ 1 file changed, 425 insertions(+) create mode 100644 _posts/2025-01-09-algebraic-data-types-with-java.md diff --git a/_posts/2025-01-09-algebraic-data-types-with-java.md b/_posts/2025-01-09-algebraic-data-types-with-java.md new file mode 100644 index 000000000..772fc053b --- /dev/null +++ b/_posts/2025-01-09-algebraic-data-types-with-java.md @@ -0,0 +1,425 @@ +--- +title: Exploring Algebraic Data Types with Java +date: 2025-01-09 00:00:00 Z +categories: +- Tech +tags: +- Java +author: magnussmith +summary: In this post we explore the power of Algebraic Data Types with Pattern Matching in Java. +image: magnussmith/assets/java.jpg +--- + + +# Introduction + +## Domain Modeling + +When we develop an application, we frequently need to model some aspect of business to describe and solve a business problem. We do this by creating a conceptual representation of the real-world problem that we are trying to solve. This allows us to understand the "domain" where our software operates. + +Think of it like creating a blueprint before constructing a building. You identify the key elements, their relationships, and how they interact. The blueprint guides the software design and ensures it accurately reflects the business problem. + +Essentially, Domain Modeling works in four stages: + +1. **Identify Key Concepts:** Start by identifying the important concepts, entities, and relationships within the domain. +2. **Create a Model:** Represent these concepts and their relationships using a model such as a class diagram. +3. **Define Attributes and Behavior:** For each concept, you define its attributes (properties) and behavior (actions). +4. **Refine the Model:** Now iteratively refine the model based on feedback, further analysis, and discussions with domain experts. + +### Relationship to Types and Objects in software: + +Domain modeling is closely tied to the concepts of types and objects in object-oriented programming: + +* **Types:** The concepts in the domain model often translate directly into types (classes) in our code. For example, the "Book" concept might become a `Book` class. +* **Objects:** Instances of these types represent specific objects in the domain. Each `Book` object would represent a particular book in the library. +* **Attributes:** Attributes in the domain model become properties (fields) of the class. +* **Behavior:** The behavior defined in the domain model is implemented as methods in the class. + +### Example: + +Imagine you're building an e-commerce system. Your domain model might include concepts like "Customer," "Product," "Order," and "Payment." These would translate into classes in your code. Each customer would be represented by a `Customer` object, each product by a `Product` object, and so on. + +### Relationship to an Algebra + +The relationship between a domain model and an algebra might seem abstract at first, but it's a powerful concept with practical implications in software design, especially when dealing with complex systems. + +#### Domain Model as a Foundation: + +* **Types as Sets:** In the domain model, each concept (e.g., "Customer," "Product," "Order") can be thought of as a set of possible values. For instance, "Customer" represents the set of all possible customers. +* **Relationships as Functions:** Relationships between concepts can be modeled as functions. For example, an "Order" might have a function `getCustomer()` that maps an order to its corresponding customer. + +#### Algebraic Structures: + +* **Operations:** An algebra defines operations on these sets. In an e-commerce example, we might have operations like "add product to order," "calculate total price," or "apply discount." +* **Laws and Properties:** These operations adhere to certain laws and properties (like associativity, commutativity, etc.). These laws reflect the business rules and constraints of your domain. + +#### Connecting the Pieces: + +* **Domain Model Informs the Algebra:** The domain model provides the basis for defining the sets and operations in the algebra. It ensures that the algebra accurately reflects our real-world problem. +* **Algebra Provides Structure:** The algebraic structure helps us reason about the behavior of your system and ensures consistency. For example, the "add product to order" operation might need to be associative (the order in which you add products shouldn't matter). +* **Implementation:** In code, we implement the algebra using classes, methods, and data structures. The algebraic laws guide the implementation and help you avoid inconsistencies. + +### Benefits of this Approach: + +* **Rigour and Precision:** Using an algebraic approach brings rigour and precision to the domain model. It helps us clearly define the behavior of a system. +* **Testability:** Algebraic laws can be used to create comprehensive test cases, ensuring that your implementation adheres to the domain rules. +* **Maintainability:** A well-defined algebra makes code more modular and easier to maintain. Changes in the domain can be reflected by modifying the algebra and its implementation. + +### Example: + +Consider a banking system. Your domain model might include concepts like "Account" and "Transaction." We could define an algebra with operations like "deposit," "withdraw," and "transfer." These operations would need to satisfy certain laws, such as: + +* **Consistency:** `withdraw(account, amount)` should only succeed if the account has sufficient funds. +* **Associativity:** Multiple deposits or withdrawals should result in the same final balance regardless of the order. + +By implementing these algebraic laws in our code, we ensure that the banking system behaves correctly and consistently. + + + + +## Algebraic Data Types (ADTs) + +Algebraic Data Types (ADTs) are a way to structure data in functional programming languages. They provide a mechanism to create composite data types by combining other simpler types. ADTs help us to model complex data structures using simpler building blocks, much like building with LEGOs. Think of them as custom, compound data types that you design for your specific needs. + +ADTs are prevalent in functional programming due to their ability to enhance code safety, readability, and maintainability in a structured and type-safe manner. + +### Benefits of using ADTs + +### Readability + +ADTs make code more readable by explicitly defining the structure and possible values of complex data. This makes it easier to understand and reason about the code, improving maintainability. + +### Constraint Enforcement + +ADTs leverage the type system to enforce constraints on data. The compiler can detect errors at compile time, preventing runtime issues that might arise from invalid data structures or operations. + +### Boilerplate Reduction + +Compared to using classes or structs alone, ADTs can often reduce the amount of boilerplate code needed to define and manipulate complex data. For example, pattern matching with ADTs often eliminates the need for lengthy `if-else` chains or `switch` statements. + +ADTs accurately model data that has a limited set of possible states or variations. This is particularly useful for representing: + +- **State machines:** Each state can be a variant of an ADT. +- **Abstract Syntax Trees (ASTs):** Used in compilers and interpreters to represent the structure of code. +- **Error Handling:** An ADT can represent either a successful result or a specific error. + +In essence, ADTs help us model the application domain by defining custom data types that are tailor-made for a specific application and enforced by the type system. They provide a powerful tool for tackling complexity in software engineering. + +### Why "Algebraic"? + +In the context of Algebraic Data Types (ADTs), "algebra" refers to the operations used to combine types and the relationships between those operations and the types: + +- **Objects:** The types that make up the algebra. +- **Operations:** The ways to combine types to create new types. +- **Laws:** The relationships between the types and the operations. + +In ADTs, the algebra consists of two primary operators: **x** (`product`) and **+** (`sum`). + +## Product Types + +Product types represent a combination of data where a type holds values of several other types simultaneously. + +- Think of it as an "AND" relationship. +- A `Point` might be a product type consisting of an `x` coordinate AND a `y` coordinate. +- It defines values. +- Logical AND operator. +- Product types bundle two or more arbitrary types together such that `T = A AND B AND C`. +- The product is the [Cartesian product](https://www.ucl.ac.uk/~ucahmto/0005_2021/Ch2.S5.html) of all their components. + +In code, we see this as tuples, POJOs, structs, or records. In set theory, this is the Cartesian product. + +~~~ java +public record TextStyle(Weight weight, Font font){} +public enum Font { SERIF, SANS_SERIF, MONOSPACE } +public enum Weight { NORMAL, LIGHT, HEAVY } +~~~ + +This is called a **product** type because the *set of all possible values* is the Cartesian product of the possible values of its components. For example: + +In abstract syntax: + +`TextStyle = Weight ⨯ Font` + +`6 = 3 x 3` + +## Sum Types + +Sum types represent a choice between different types, where a value can be one of several possible types, but only one at a time. + +- Think of it as an "OR" relationship. +- A `Shape` might be a sum type, as it could be a `Circle` OR a `Square` OR a `Triangle`. +- Defines variants. +- Logical OR operator. +- Sum types are built with the '+' operator and combine types with OR, as in `T = A OR B OR C`. +- The sum is the union of the value sets of the alternatives. + +Traditionally, sum types are more common in functional languages like Haskell (as data types) or Scala (as sealed traits of case classes). Java introduced a version with sealed interfaces of records in Java 17. A very simple version in Java is an `enum` type, though enums cannot have additional data associated with them once instantiated. + +An important property of ADTs is that they can be sealed or closed. This means that their definition contains all possible cases, and no further cases can exist. This allows the compiler to exhaustively verify all alternatives. + +We can define a `Status` as a disjunction, the relation of three distinct alternatives: + +~~~ haskell +Under Review | Accepted | Rejected +~~~ +Example: A Status type united with a Boolean type + +`Status + Boolean` + +This is a **Sum** because the number of items in the resulting type is the sum of the number of items in each subtype. + +`3 + 2 = 5` + + + + +## Combining Product and Sum Types + +Product and sum types can be combined, and they follow the distributive law of numerical algebra: + +`(a * b + a * c) <=> a * (b +c)` + +For example, we could define a DNS Record as a sum type: + +~~~ haskell +DnsRecord( + AValue(ttl, name, ipv4) + | AaaaValue(ttl, name, ipv6) + | CnameValue(ttl, name, alias) + | TxtValue(ttl, name, name) +) +~~~ + +But we could also refactor it to a product of a product and sums: + +~~~ haskell +DnsRecord(ttl, name, + AValue(ipv4) + | AaaaValue(ipv6) + | CnameValue(alias) + | TxtValue(value) +) +~~~ + +At the type level we can change ordering in using the same commutative law we would in algebra + +Commutativity + +`(a * b) <=> (b * a)` +`(a + b) <=> (b + a)` + +Associativity + +`(a + b) + c <=> a + (b + c)` +`(a * b) * c <=> a * (b * c)` + + +## A Historical Perspective + +The concept of ADTs traces back to the early days of functional programming languages like ML and Hope in the 1970s. They were then popularised by languages like Haskell, which uses them as a fundamental building block. + +Let's take a quick tour of how ADTs (or their approximations) have been handled in different languages: + +- **C:** C lacks built-in support for ADTs but can simulate them by using `structs` for product types and `unions` (combined with an `enum` for type tracking) for a rudimentary form of sum types. + The tagged union (also called a disjoint union) is a data structure used to hold a value that can take on several different, but fixed, types. Only one of the types can be in use at any one time, and a tag field explicitly indicates which one is in use. Here, the tag is a value that indicates the variant of the enum stored in the union. However, unions are notoriously unsafe, as they don't enforce type checking at compile time. + +~~~ c + union vals { + char ch; + int nt; + }; + + struct tagUnion { + char tag; // Tag to track the active type + union vals val; + }; +~~~ + +- **Haskell**: Haskell a functional language elegantly expresses ADTs with its data keyword. Haskell's type system is specifically designed to support the creation and manipulation of ADTs. + +~~~ haskell + data Shape = Circle Float | Rectangle Float Float +~~~ + + This defines Shape as a sum type that can be either a Circle with a radius (Float) or a Rectangle with width and height (Float). + +- **Scala**: Scala uses case classes for product types and `sealed traits` with `case classes/objects` for sum types. This provides a robust and type-safe way to define ADTs. + +~~~ scala + sealed trait Shape + case class Circle(radius: Double) extends Shape + case class Rectangle(width: Double, height: Double) extends Shape +~~~ + +- **Java** (Pre-Java 17): Historically, Java relied on class hierarchies and the Visitor pattern to mimic sum types. This approach was verbose, requiring a lot of boilerplate code and was prone to errors if not carefully implemented. Product types were typically represented by classes with member variables. + + +## ADTs in Java + +Java's records and sealed interfaces provide an elegant mechanism for implementing ADTs. + +- **Records:** Introduced in Java 14, records offer a concise syntax for defining immutable data carriers, providing *nominal* types and components with *human-readable* names. +- **Sealed Interfaces:** Introduced in Java 17, sealed interfaces allow classes and interfaces to have more control over their permitted subtypes. This enables precise data modeling as *sealed* hierarchies of immutable records. The compiler knows all possible subtypes at compile time, a crucial requirement for safe sum types. +- **Pattern Matching:** Pattern matching is a powerful feature that enhances Java's `instanceof` operator and `switch` expressions/statements. It allows developers to concisely and safely extract data from objects based on their structure. This capability streamlines type checking and casting, leading to more readable and less error-prone code. The evolution of pattern matching in Java is noteworthy. Initially introduced in Java 16 to enhance the `instanceof` operator [JEP 394](https://openjdk.org/jeps/394), it was later extended to `switch` expressions and statements in Java 17 [JEP 406](https://openjdk.org/jeps/496). This expansion broadened the applicability of pattern matching, enabling more expressive and safer code constructs. + +Restricting the possible implementations of a type enables exhaustive pattern matching and makes invalid states unrepresentable. This is particularly useful for general domain modeling with type safety. + + + + +### Why not just use enums? + +~~~ java +enum Task = { + NotStarted, + Started, + Completed, + Cancelled; +} + +sealed interface TaskStatus{ + record NotStarted(...) implements TaskStatus + record Started(...) implements TaskStatus + record Completed(...) implements TaskStatus + record Cancelled(...) implements TaskStatus +} +~~~ + +It is possible to associate data with an enum constant, such as the mass and radius of the planet + +~~~ java +enum Planet { + MERCURY (3.303e+23, 2.4397e6), + VENUS (4.869e+24, 6.0518e6), + EARTH (5.976e+24, 6.37814e6), +... +} +~~~ +sealed records work at a higher level. Where enums enumerate a fixed list of `instances` sealed records enumerate a fixed list of `kinds of instances` + +~~~ java + +sealed interface Celestial { + record Planet(String name, double mass, double radius) implements Celestial {} + record Star(String name, double mass, double temperature) implements Celestial {} + record Comet(String name, double period) implements Celestial {} +} + +~~~ + +Unlike enums, records allow us to attach arbitrary attributes to each of the enumerated states. We are no longer restricted to fixed constants. + +In the Celestial example, we see a `sum of products`. This is a useful technique for modeling complex domains in a flexible but type-safe manner. For sums of products to work, we have to commit to the subtypes, which is a form of tight coupling. This works well if we are sure the subtypes are unlikely to change. We trade some future flexibility for an exhaustive list of subtypes that allows better reasoning about shapes, especially when it comes to pattern matching. + + + +### Making use of ADTs + +Traditionally, Java developers used the Visitor pattern to handle operations on different data types within a hierarchy. However, this approach has several drawbacks, as we will see when we compare using a sum type with Pattern Matching: + +### Using Visitor Pattern + + + + +~~~jshelllanguage +Shapes: +Circle with radius: 5.00, area: 78.54, perimeter: 31.42 +Triangle with sides: 3.00, 3.00, 3.00, area: 3.90, perimeter: 9.00 +Rectangle with width: 3.00 , height: 5.00, area: 15.00, perimeter: 16.00 +Pentagon with side: 5.60, area: 53.95, perimeter: 28.00 + +Shapes scaled by 2: +Circle with radius: 10.00, area: 314.16, perimeter: 62.83 +Triangle with sides: 6.00, 6.00, 6.00, area: 15.59, perimeter: 18.00 +Rectangle with width: 6.00 , height: 10.00, area: 60.00, perimeter: 32.00 +Pentagon with side: 11.20, area: 215.82, perimeter: 56.00 +~~~ + +#### Explanation: + +1. `Shape` is a sealed interface, allowing only permitting `Circle`,` Rectangle`,` Triangle` and `Pentagon` to implement it. + +2. `ShapeVisitor` Interface: + + Defines the visit methods for each shape type. + + The generic type T allows visitors to return different types of results. + +3. accept Method in Shape: + + Each shape class implements the accept method, which takes a ShapeVisitor and calls the appropriate visit method on the visitor. + +4. Concrete Visitors: + + `AreaCalculator`: Calculates the area of a shape. + + `PerimeterCalculator`: Calculates the perimeter of a shape. + + `InfoVisitor`: Generates a string with information about the shape (including area and perimeter). + + `ScaleVisitor`: Scales a shape by a given factor. + +The Visitor pattern heavily relies on polymorphism, specifically double dispatch. +1. **First Dispatch (Dynamic)**: When `accept(visitor)` is called the correct `accept` method is chosen at runtime based upon the actual type of shape. This is standard dynamic polymorphism. +2. **Second Dispatch (Within Visitor**): Inside the `accept` method `this` is now statically known to the concrete shape type (e.g triangle). Therefore the compiler can statically choose the correct `visit` method in the `Visitor` to call, based upon the type of the current visitor, passed in as an argument to the `accept()` method. + +### Using Pattern Matching + +Lets look at the same model with pattern matching + + + + +Output: + +~~~jshelllanguage +Shapes: [Circle[radius=5.0], Triangle[side1=3.0, side2=3.0, side3=3.0], Rectangle[width=3.0, height=5.0], Pentagon[side=5.6]] +Circle with radius: 5.00, area: 78.54, perimeter: 31.42 +Triangle with sides: 3.00, 3.00, 3.00, area: 3.90, perimeter: 9.00 +Rectangle with width: 3.00 , height: 5.00, area: 15.00, perimeter: 16.00 +Pentagon with side: 5.60, area: 53.95, perimeter: 28.00 + +Shapes scaled by 2: [Circle[radius=5.0], Triangle[side1=3.0, side2=3.0, side3=3.0], Rectangle[width=3.0, height=5.0], Pentagon[side=5.6]] +Circle with radius: 10.00, area: 314.16, perimeter: 62.83 +Triangle with sides: 6.00, 6.00, 6.00, area: 15.59, perimeter: 18.00 +Rectangle with width: 6.00 , height: 10.00, area: 60.00, perimeter: 32.00 +Pentagon with side: 11.20, area: 215.82, perimeter: 56.00 +~~~ + +#### Explanation: +1. `Shape` is a sealed interface, only permitting `Circle`,` Rectangle`,` Triangle` and `Pentagon` to implement it. +3. `Shapes` demonstrates using pattern matching with switch to handle different Shape types and perform operations like calculating area, perimeter or scaling. The compiler ensures that all possible Shape types are covered in the switch. + +### Comparing Pattern Matching with the Visitor Pattern + +When we compare pattern matching to the visitor pattern we are actually looking at two different approaches to the [expression problem](https://en.wikipedia.org/wiki/Expression_problem) +The `Expression Problem` in computer science highlights the challenge of extending data structures and operations independently. + +Specifically, it's difficult to: + +- **Add new data types**: Without modifying existing code that operates on those data types. +- **Add new operations**: Without modifying existing data types. + +#### Visitor Pattern + +The visitor pattern is a solution that favours extending operations over extending data types: + +- **Adding new operations (Easy)**: Create a new Visitor +- **Adding new data type (Hard)**: Adding a new type to the hierarchy with the Visitor pattern requires modifying the visitor interface and all its implementations with a new `visit` method, violating the Open/Closed Principle. +- **Verbosity**: The Visitor pattern requires a lot of boilerplate code, with separate visitor interfaces and classes for each operation +- **Exhaustiveness Checking**: The compiler cannot guarantee that all possible types are handled in the Visitor pattern, leading to potential runtime errors. + +##### Patten Matching + +- **Add new operations (Easy)**: Add a new pattern matching function +- **Add new data type (Easier)**: Only update the pattern matching code that needs to deal with the new data type +- **Verbosity**: ADTs with pattern matching are more concise. +- **Exhaustiveness Checking**: With sealed types and pattern matching, the compiler can perform exhaustiveness checking, ensuring that all cases are handled. + +In summary, ADTs, particularly in modern Java with records, sealed interfaces, and pattern matching, offer a more elegant, type-safe, and maintainable approach to modeling complex data and their behavior, compared to traditional techniques like the Visitor pattern. + + + +References: + +- [Where does the name "algebraic data type" come from?](https://blog.poisson.chat/posts/2024-07-26-adt-history.html) + + \ No newline at end of file From e9d4e87bb2ef7e26bbaacd35f25b4379cdf73524 Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Wed, 8 Jan 2025 16:23:57 +0000 Subject: [PATCH 02/13] algebraic data types and pattern matching with java --- _posts/2025-01-09-algebraic-data-types-with-java.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2025-01-09-algebraic-data-types-with-java.md b/_posts/2025-01-09-algebraic-data-types-with-java.md index 772fc053b..1909d27af 100644 --- a/_posts/2025-01-09-algebraic-data-types-with-java.md +++ b/_posts/2025-01-09-algebraic-data-types-with-java.md @@ -6,7 +6,7 @@ categories: tags: - Java author: magnussmith -summary: In this post we explore the power of Algebraic Data Types with Pattern Matching in Java. +summary: In this post we explore the power of Algebraic Data Types(ADT) with Pattern Matching in Java. We look at how they help us model complex business domains and how using them with pattern matching gives improvements on the traditional Visitor Pattern image: magnussmith/assets/java.jpg --- + + -# Introduction -## Domain Modeling +![Algebraic Data Types and Pattern Matchinch with Java](/data/development/idea/blog/magnussmith/assets/adt_pattern_matching_java.webp) + +# Introduction When we develop an application, we frequently need to model some aspect of business to describe and solve a business problem. We do this by creating a conceptual representation of the real-world problem that we are trying to solve. This allows us to understand the "domain" where our software operates. +## Domain Modelling + Think of it like creating a blueprint before constructing a building. You identify the key elements, their relationships, and how they interact. The blueprint guides the software design and ensures it accurately reflects the business problem. -Essentially, Domain Modeling works in four stages: +Essentially, Domain Modelling works in four stages: 1. **Identify Key Concepts:** Start by identifying the important concepts, entities, and relationships within the domain. 2. **Create a Model:** Represent these concepts and their relationships using a model such as a class diagram. -3. **Define Attributes and Behavior:** For each concept, you define its attributes (properties) and behavior (actions). +3. **Define Attributes and Behaviour:** For each concept, you define its attributes (properties) and behaviour (actions). 4. **Refine the Model:** Now iteratively refine the model based on feedback, further analysis, and discussions with domain experts. ### Relationship to Types and Objects in software: -Domain modeling is closely tied to the concepts of types and objects in object-oriented programming: +Domain modelling is closely tied to the concepts of types and objects in object-oriented programming: * **Types:** The concepts in the domain model often translate directly into types (classes) in our code. For example, the "Book" concept might become a `Book` class. * **Objects:** Instances of these types represent specific objects in the domain. Each `Book` object would represent a particular book in the library. * **Attributes:** Attributes in the domain model become properties (fields) of the class. -* **Behavior:** The behavior defined in the domain model is implemented as methods in the class. +* **Behaviour:** The behaviour defined in the domain model is implemented as methods in the class. ### Example: From ee4c71f3440600dbe1ce1407d28e148b1b56ef20 Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Sun, 12 Jan 2025 17:35:52 +0000 Subject: [PATCH 05/13] added an image and corrected spelling --- ...2025-01-08-algebraic-data-types-with-java.md | 2 +- .../assets/adt_pattern_matching_java.webp | Bin 0 -> 81456 bytes 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 magnussmith/assets/adt_pattern_matching_java.webp diff --git a/_posts/2025-01-08-algebraic-data-types-with-java.md b/_posts/2025-01-08-algebraic-data-types-with-java.md index 8b72c1d66..79ff41aee 100644 --- a/_posts/2025-01-08-algebraic-data-types-with-java.md +++ b/_posts/2025-01-08-algebraic-data-types-with-java.md @@ -17,7 +17,7 @@ image: magnussmith/assets/java.jpg -![Algebraic Data Types and Pattern Matchinch with Java](/data/development/idea/blog/magnussmith/assets/adt_pattern_matching_java.webp) +![Algebraic Data Types and Pattern Matchinch with Java](../magnussmith/assets/adt_pattern_matching_java.webp) # Introduction diff --git a/magnussmith/assets/adt_pattern_matching_java.webp b/magnussmith/assets/adt_pattern_matching_java.webp new file mode 100644 index 0000000000000000000000000000000000000000..1a2c486d6846a656368f181bc236e5bcdfa5f3be GIT binary patch literal 81456 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%0D7^6=X?zbCxQ%aB=*JKm%1C+iFj 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 Date: Sun, 12 Jan 2025 17:39:12 +0000 Subject: [PATCH 06/13] added an image and corrected spelling --- _posts/2025-01-08-algebraic-data-types-with-java.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2025-01-08-algebraic-data-types-with-java.md b/_posts/2025-01-08-algebraic-data-types-with-java.md index 79ff41aee..9ebca4124 100644 --- a/_posts/2025-01-08-algebraic-data-types-with-java.md +++ b/_posts/2025-01-08-algebraic-data-types-with-java.md @@ -1,5 +1,5 @@ --- -title: Exploring Algebraic Data Types with Java +title: Algebraic Data Types and Pattern Matching with Java date: 2025-01-08 00:00:00 Z categories: - Tech From 17adf1187a4a8637bb2d1aa5d48839614cd941ee Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Sun, 12 Jan 2025 17:46:21 +0000 Subject: [PATCH 07/13] added an image and corrected spelling --- _posts/2025-01-08-algebraic-data-types-with-java.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2025-01-08-algebraic-data-types-with-java.md b/_posts/2025-01-08-algebraic-data-types-with-java.md index 9ebca4124..063b28cba 100644 --- a/_posts/2025-01-08-algebraic-data-types-with-java.md +++ b/_posts/2025-01-08-algebraic-data-types-with-java.md @@ -17,7 +17,7 @@ image: magnussmith/assets/java.jpg -![Algebraic Data Types and Pattern Matchinch with Java](../magnussmith/assets/adt_pattern_matching_java.webp) +![Algebraic Data Types and Pattern Matchinch with Java]({{site.baseurl}}/magnussmith/assets/adt_pattern_matching_java.webp) # Introduction From 07a43382aea8fff539eb0dd5bc0a4d7211103765 Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Sun, 19 Jan 2025 11:53:39 +0000 Subject: [PATCH 08/13] review changes --- .../2025-01-08-algebraic-data-types-with-java.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/_posts/2025-01-08-algebraic-data-types-with-java.md b/_posts/2025-01-08-algebraic-data-types-with-java.md index 063b28cba..fbb9ddc45 100644 --- a/_posts/2025-01-08-algebraic-data-types-with-java.md +++ b/_posts/2025-01-08-algebraic-data-types-with-java.md @@ -228,7 +228,8 @@ The concept of ADTs traces back to the early days of functional programming lang Let's take a quick tour of how ADTs (or their approximations) have been handled in different languages: -- **C:** C lacks built-in support for ADTs but can simulate them by using `structs` for product types and `unions` (combined with an `enum` for type tracking) for a rudimentary form of sum types. +### C +C lacks built-in support for ADTs but can simulate them by using `structs` for product types and `unions` (combined with an `enum` for type tracking) for a rudimentary form of sum types. The tagged union (also called a disjoint union) is a data structure used to hold a value that can take on several different, but fixed, types. Only one of the types can be in use at any one time, and a tag field explicitly indicates which one is in use. Here, the tag is a value that indicates the variant of the enum stored in the union. However, unions are notoriously unsafe, as they don't enforce type checking at compile time. ~~~ c @@ -243,7 +244,8 @@ Let's take a quick tour of how ADTs (or their approximations) have been handled }; ~~~ -- **Haskell**: Haskell a functional language elegantly expresses ADTs with its data keyword. Haskell's type system is specifically designed to support the creation and manipulation of ADTs. +### Haskell +Haskell a functional language elegantly expresses ADTs with its data keyword. Haskell's type system is specifically designed to support the creation and manipulation of ADTs. ~~~ haskell data Shape = Circle Float | Rectangle Float Float @@ -251,7 +253,8 @@ Let's take a quick tour of how ADTs (or their approximations) have been handled This defines Shape as a sum type that can be either a Circle with a radius (Float) or a Rectangle with width and height (Float). -- **Scala**: Scala uses case classes for product types and `sealed traits` with `case classes/objects` for sum types. This provides a robust and type-safe way to define ADTs. +### Scala +Scala uses case classes for product types and `sealed traits` with `case classes/objects` for sum types. This provides a robust and type-safe way to define ADTs. ~~~ scala sealed trait Shape @@ -259,7 +262,8 @@ Let's take a quick tour of how ADTs (or their approximations) have been handled case class Rectangle(width: Double, height: Double) extends Shape ~~~ -- **Java** (Pre-Java 17): Historically, Java relied on class hierarchies and the Visitor pattern to mimic sum types. This approach was verbose, requiring a lot of boilerplate code and was prone to errors if not carefully implemented. Product types were typically represented by classes with member variables. +### Java +(Pre-Java 17): Historically, Java relied on class hierarchies and the Visitor pattern to mimic sum types. This approach was verbose, requiring a lot of boilerplate code and was prone to errors if not carefully implemented. Product types were typically represented by classes with member variables. ## ADTs in Java @@ -411,7 +415,7 @@ The visitor pattern is a solution that favours extending operations over extendi - **Verbosity**: The Visitor pattern requires a lot of boilerplate code, with separate visitor interfaces and classes for each operation - **Exhaustiveness Checking**: The compiler cannot guarantee that all possible types are handled in the Visitor pattern, leading to potential runtime errors. -##### Patten Matching +##### Pattern Matching - **Add new operations (Easy)**: Add a new pattern matching function - **Add new data type (Easier)**: Only update the pattern matching code that needs to deal with the new data type From bb9a9d5f9fe019dbcd09b902bb5a25e4a620caca Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Sun, 19 Jan 2025 12:07:11 +0000 Subject: [PATCH 09/13] review changes --- _posts/2025-01-08-algebraic-data-types-with-java.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2025-01-08-algebraic-data-types-with-java.md b/_posts/2025-01-08-algebraic-data-types-with-java.md index fbb9ddc45..b548791a0 100644 --- a/_posts/2025-01-08-algebraic-data-types-with-java.md +++ b/_posts/2025-01-08-algebraic-data-types-with-java.md @@ -148,7 +148,7 @@ In abstract syntax: `TextStyle = Weight ⨯ Font` -`6 = 3 x 3` +`9 = 3 x 3` ## Sum Types From 36b54b9d9b19e80845ee675ee48cb4536d9d7862 Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Sun, 19 Jan 2025 12:31:40 +0000 Subject: [PATCH 10/13] review changes --- _posts/2025-01-08-algebraic-data-types-with-java.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/_posts/2025-01-08-algebraic-data-types-with-java.md b/_posts/2025-01-08-algebraic-data-types-with-java.md index b548791a0..b5272315e 100644 --- a/_posts/2025-01-08-algebraic-data-types-with-java.md +++ b/_posts/2025-01-08-algebraic-data-types-with-java.md @@ -17,7 +17,7 @@ image: magnussmith/assets/java.jpg -![Algebraic Data Types and Pattern Matchinch with Java]({{site.baseurl}}/magnussmith/assets/adt_pattern_matching_java.webp) +![Algebraic Data Types and Pattern Matching with Java]({{site.baseurl}}/magnussmith/assets/adt_pattern_matching_java.webp) # Introduction @@ -185,7 +185,7 @@ This is a **Sum** because the number of items in the resulting type is the sum o Product and sum types can be combined, and they follow the distributive law of numerical algebra: -`(a * b + a * c) <=> a * (b +c)` +`(a * b + a * c) <=> a * (b + c)` For example, we could define a DNS Record as a sum type: From 5d23b2809bc1db315e593741eb3ab87cc2269343 Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Sun, 19 Jan 2025 13:07:17 +0000 Subject: [PATCH 11/13] review changes --- ...25-01-08-algebraic-data-types-with-java.md | 28 +++++++++---------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/_posts/2025-01-08-algebraic-data-types-with-java.md b/_posts/2025-01-08-algebraic-data-types-with-java.md index b5272315e..6805f7ec7 100644 --- a/_posts/2025-01-08-algebraic-data-types-with-java.md +++ b/_posts/2025-01-08-algebraic-data-types-with-java.md @@ -31,8 +31,8 @@ Essentially, Domain Modelling works in four stages: 1. **Identify Key Concepts:** Start by identifying the important concepts, entities, and relationships within the domain. 2. **Create a Model:** Represent these concepts and their relationships using a model such as a class diagram. -3. **Define Attributes and Behaviour:** For each concept, you define its attributes (properties) and behaviour (actions). -4. **Refine the Model:** Now iteratively refine the model based on feedback, further analysis, and discussions with domain experts. +3. **Define Attributes and Behaviour:** For each concept, we define its attributes (properties) and behaviour (actions). +4. **Refine the Model:** Iteratively refine the model based on feedback, further analysis, and discussions with domain experts. ### Relationship to Types and Objects in software: @@ -54,22 +54,22 @@ The relationship between a domain model and an algebra might seem abstract at fi #### Domain Model as a Foundation: * **Types as Sets:** In the domain model, each concept (e.g., "Customer," "Product," "Order") can be thought of as a set of possible values. For instance, "Customer" represents the set of all possible customers. -* **Relationships as Functions:** Relationships between concepts can be modeled as functions. For example, an "Order" might have a function `getCustomer()` that maps an order to its corresponding customer. +* **Relationships as Functions:** Relationships between concepts can be modelled as functions. For example, an "Order" might have a function `getCustomer()` that maps an order to its corresponding customer. #### Algebraic Structures: * **Operations:** An algebra defines operations on these sets. In an e-commerce example, we might have operations like "add product to order," "calculate total price," or "apply discount." -* **Laws and Properties:** These operations adhere to certain laws and properties (like associativity, commutativity, etc.). These laws reflect the business rules and constraints of your domain. +* **Laws and Properties:** These operations adhere to certain laws and properties (associativity, commutativity, etc.). These laws reflect the business rules and constraints of your domain. #### Connecting the Pieces: * **Domain Model Informs the Algebra:** The domain model provides the basis for defining the sets and operations in the algebra. It ensures that the algebra accurately reflects our real-world problem. -* **Algebra Provides Structure:** The algebraic structure helps us reason about the behavior of your system and ensures consistency. For example, the "add product to order" operation might need to be associative (the order in which you add products shouldn't matter). +* **Algebra Provides Structure:** The algebraic structure helps us reason about the behaviour of your system and ensures consistency. For example, the "add product to order" operation might need to be associative (the order in which you add products shouldn't matter). * **Implementation:** In code, we implement the algebra using classes, methods, and data structures. The algebraic laws guide the implementation and help you avoid inconsistencies. ### Benefits of this Approach: -* **Rigour and Precision:** Using an algebraic approach brings rigour and precision to the domain model. It helps us clearly define the behavior of a system. +* **Rigour and Precision:** Using an algebraic approach brings rigour and precision to the domain model. It helps us clearly define the behaviour of a system. * **Testability:** Algebraic laws can be used to create comprehensive test cases, ensuring that your implementation adheres to the domain rules. * **Maintainability:** A well-defined algebra makes code more modular and easier to maintain. Changes in the domain can be reflected by modifying the algebra and its implementation. @@ -87,7 +87,7 @@ By implementing these algebraic laws in our code, we ensure that the banking sys ## Algebraic Data Types (ADTs) -Algebraic Data Types (ADTs) are a way to structure data in functional programming languages. They provide a mechanism to create composite data types by combining other simpler types. ADTs help us to model complex data structures using simpler building blocks, much like building with LEGOs. Think of them as custom, compound data types that you design for your specific needs. +Algebraic Data Types (ADTs) are a way to structure data in functional programming languages. They provide a mechanism to create composite data types by combining other simpler types. ADTs help us to model complex data structures using simpler building blocks, much like building with LEGO. Think of them as custom, compound data types that you design for your specific needs. ADTs are prevalent in functional programming due to their ability to enhance code safety, readability, and maintainability in a structured and type-safe manner. @@ -230,7 +230,7 @@ Let's take a quick tour of how ADTs (or their approximations) have been handled ### C C lacks built-in support for ADTs but can simulate them by using `structs` for product types and `unions` (combined with an `enum` for type tracking) for a rudimentary form of sum types. - The tagged union (also called a disjoint union) is a data structure used to hold a value that can take on several different, but fixed, types. Only one of the types can be in use at any one time, and a tag field explicitly indicates which one is in use. Here, the tag is a value that indicates the variant of the enum stored in the union. However, unions are notoriously unsafe, as they don't enforce type checking at compile time. + The tagged union (also called a disjoint union) is a data structure used to hold a value that can take on several different, but fixed, types. Only one of the types can be in use at any one time; a tag field explicitly indicates which one is in use. Here, the tag is a value that indicates the variant of the enum stored in the union. However, unions are notoriously unsafe, as they don't enforce type checking at compile time. ~~~ c union vals { @@ -271,10 +271,10 @@ Scala uses case classes for product types and `sealed traits` with `case classes Java's records and sealed interfaces provide an elegant mechanism for implementing ADTs. - **Records:** Introduced in Java 14, records offer a concise syntax for defining immutable data carriers, providing *nominal* types and components with *human-readable* names. -- **Sealed Interfaces:** Introduced in Java 17, sealed interfaces allow classes and interfaces to have more control over their permitted subtypes. This enables precise data modeling as *sealed* hierarchies of immutable records. The compiler knows all possible subtypes at compile time, a crucial requirement for safe sum types. +- **Sealed Interfaces:** Introduced in Java 17, sealed interfaces allow classes and interfaces to have more control over their permitted subtypes. This enables precise data modelling as *sealed* hierarchies of immutable records. The compiler knows all possible subtypes at compile time, a crucial requirement for safe sum types. - **Pattern Matching:** Pattern matching is a powerful feature that enhances Java's `instanceof` operator and `switch` expressions/statements. It allows developers to concisely and safely extract data from objects based on their structure. This capability streamlines type checking and casting, leading to more readable and less error-prone code. The evolution of pattern matching in Java is noteworthy. Initially introduced in Java 16 to enhance the `instanceof` operator [JEP 394](https://openjdk.org/jeps/394), it was later extended to `switch` expressions and statements in Java 17 [JEP 406](https://openjdk.org/jeps/496). This expansion broadened the applicability of pattern matching, enabling more expressive and safer code constructs. -Restricting the possible implementations of a type enables exhaustive pattern matching and makes invalid states unrepresentable. This is particularly useful for general domain modeling with type safety. +Restricting the possible implementations of a type enables exhaustive pattern matching and makes invalid states unrepresentable. This is particularly useful for general domain modelling with type safety. @@ -307,7 +307,7 @@ enum Planet { ... } ~~~ -sealed records work at a higher level. Where enums enumerate a fixed list of `instances` sealed records enumerate a fixed list of `kinds of instances` +sealed records work at a higher level. Where enums enumerate a fixed list of `instances`, sealed records enumerate a fixed list of `kinds of instances` ~~~ java @@ -321,7 +321,7 @@ sealed interface Celestial { Unlike enums, records allow us to attach arbitrary attributes to each of the enumerated states. We are no longer restricted to fixed constants. -In the Celestial example, we see a `sum of products`. This is a useful technique for modeling complex domains in a flexible but type-safe manner. For sums of products to work, we have to commit to the subtypes, which is a form of tight coupling. This works well if we are sure the subtypes are unlikely to change. We trade some future flexibility for an exhaustive list of subtypes that allows better reasoning about shapes, especially when it comes to pattern matching. +In the Celestial example, we see a `sum of products`. This is a useful technique for modelling complex domains in a flexible but type-safe manner. For sums of products to work, we have to commit to the subtypes, which is a form of tight coupling. This works well if we are sure the subtypes are unlikely to change. We trade some future flexibility for an exhaustive list of subtypes that allows better reasoning about shapes, especially when it comes to pattern matching. @@ -350,7 +350,7 @@ Pentagon with side: 11.20, area: 215.82, perimeter: 56.00 #### Explanation: -1. `Shape` is a sealed interface, allowing only permitting `Circle`,` Rectangle`,` Triangle` and `Pentagon` to implement it. +1. `Shape` is a sealed interface, only permitting `Circle`,` Rectangle`,` Triangle` and `Pentagon` to implement it. 2. `ShapeVisitor` Interface: + Defines the visit methods for each shape type. @@ -422,7 +422,7 @@ The visitor pattern is a solution that favours extending operations over extendi - **Verbosity**: ADTs with pattern matching are more concise. - **Exhaustiveness Checking**: With sealed types and pattern matching, the compiler can perform exhaustiveness checking, ensuring that all cases are handled. -In summary, ADTs, particularly in modern Java with records, sealed interfaces, and pattern matching, offer a more elegant, type-safe, and maintainable approach to modeling complex data and their behavior, compared to traditional techniques like the Visitor pattern. +In summary, ADTs, particularly in modern Java with records, sealed interfaces, and pattern matching, offer a more elegant, type-safe, and maintainable approach to modelling complex data and their behaviour, compared to traditional techniques like the Visitor pattern. From b3f2e716b033b2bf6c5de67b311edfa94bed81a8 Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Sun, 19 Jan 2025 13:15:33 +0000 Subject: [PATCH 12/13] updated publish date --- ...ith-java.md => 2025-01-20-algebraic-data-types-with-java.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename _posts/{2025-01-08-algebraic-data-types-with-java.md => 2025-01-20-algebraic-data-types-with-java.md} (99%) diff --git a/_posts/2025-01-08-algebraic-data-types-with-java.md b/_posts/2025-01-20-algebraic-data-types-with-java.md similarity index 99% rename from _posts/2025-01-08-algebraic-data-types-with-java.md rename to _posts/2025-01-20-algebraic-data-types-with-java.md index 6805f7ec7..dccfdc292 100644 --- a/_posts/2025-01-08-algebraic-data-types-with-java.md +++ b/_posts/2025-01-20-algebraic-data-types-with-java.md @@ -1,6 +1,6 @@ --- title: Algebraic Data Types and Pattern Matching with Java -date: 2025-01-08 00:00:00 Z +date: 2025-01-20 00:00:00 Z categories: - Tech tags: From 99d7244c4e7f6821c2a7201d7545b0d1b15f7033 Mon Sep 17 00:00:00 2001 From: Magnus Smith Date: Mon, 20 Jan 2025 07:55:32 +0000 Subject: [PATCH 13/13] regenerate page --- _posts/2025-01-20-algebraic-data-types-with-java.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/_posts/2025-01-20-algebraic-data-types-with-java.md b/_posts/2025-01-20-algebraic-data-types-with-java.md index dccfdc292..cb0389243 100644 --- a/_posts/2025-01-20-algebraic-data-types-with-java.md +++ b/_posts/2025-01-20-algebraic-data-types-with-java.md @@ -6,7 +6,7 @@ categories: tags: - Java author: magnussmith -summary: In this post we explore the power of Algebraic Data Types(ADT) with Pattern Matching in Java. We look at how they help us model complex business domains and how using them together gives improvements on the traditional Visitor Pattern +summary: In this post we explore the power of Algebraic Data Types(ADT) with Pattern Matching in Java. We look at how they help us model complex business domains and how using them together gives improvements on the traditional Visitor Pattern. image: magnussmith/assets/java.jpg ---