Skip to main content

Web Application Development following Functional Programming Principles

After studying category theory and functional programming, I decided to put these concepts into practice by developing a simple web application. This project was inspired by the example in Chapter 11 of 'Programming in Haskell' by Graham Hutton. My goal was to take these theoretical programming ideas and see how they work in creating a real-world web application.

The key concepts of functional programming are:

  • Prioritize creating pure functions as much as possible. These are functions without side effects, making them simpler to test

  • Use composition of pure functions to construct more intricate functions

  • Use Functors, Applicatives, and Monads in scenarios that require pure functions, such as error handling or managing missing values, and when working with collections like trees and lists.

I wrote this application in Java, utilizing the Spring Boot framework. This decision was influenced by my previous work in developing enterprise applications with this technology stack. My objective was to investigate how functional programming (FP) concepts and techniques could be effectively applied in a real-world Java application. While Haskell, TypeScript, or React JS were potential alternatives, my goal was to create a project that was more than just a theoretical example, but rather one that had practical relevance to my professional work.


I also wanted to explore a few ideas beyond the typical development toolkit. I've been in search of a rendering framework that is both strongly typed and easily composable. The current state of the industry for Spring Boot is to use Thymeleaf as the template framework. I used Thymeleaf, and several other template libraries, in several projects but I see several drawbacks:

  • Separate HTML file: Initially easy to write but becomes challenging to maintain

  • No layout template model: Requires importing a separate library, adding more XML elements and attributes

  • Not strongly typed: Becomes error-prone over time.


This led me to explore Java-based DSLs (Domain-Specific Languages). Initially, I tried htmlflow, but eventually, I decided on J2HTML. I was looking for a commercial, predefined Admin Layout that simplifies development. This approach ensures that essential widgets, like forms, buttons, and alerts, are readily available, without the need for a deep dive into CSS/JS. Lately, I've been using Core UI (coreui.io), which is built on the Bootstrap framework but offers additional widgets ideal for medium-complexity enterprise applications. For my demos, the free version of Core UI suffices, and for full-scale applications, I use the pro version. Its extension of widgets is useful for developing enterprise applications of moderate complexity.

Design of the Game Engine

The Game Engine closely follows the [PiH] design. The Java classes correspond to Haskell types:

  • Player an enum in Java, a type in Haskell. A bit more involved in Java because there is a conversion from an enum to char which is implicit in Haskell. Another interesting point discovered is that Java enums implement Comparable with the natural order based on the order in the source code, which is similar to Haskell

  • Grid is a class in Java and a type in Haskell. Most operations convert nicely from Haskell to Java. I used streams instead whenever possible

  • All public operations in the Grid class are pure-function, with the convention that the object itself (this) is the first parameter in all operations.

  • GameNode, GameTree are classes in Java. There are no Haskell types for it but probably should for clarity. The public methods of these classes are pure functions.

Design of the User Interface

The user interface relies on Spring MVC. Controllers process requests, interact with services like our Game Engine and prepare views.

I used high-level views based on page templates, each with specific panels. For example, the T3PageTemplate renders the grid in a two-panels layout. This layout includes navigation links, user info, a right column card, and associated JS scripts. 

A page in the application is a dynamic ensemble of various elements – widgets, text, images, and links – all coming together to present a rich and complex dataset. Consider, for instance, the page that renders the grid. It's not just about displaying the grid; it also incorporates the brand, user information (whether the user is authenticated or not), and a user-dependent menu. You might imagine a class, GridPageView, with a render method that takes in all the necessary data for display. This method would then orchestrate various sub-views like HeaderView, SideBarView, and GridCardView, each with their components like UserView, GridView, MenuView. However, a challenge arises with this structure: it necessitates defining methods with extensive arguments. Moreover, if a nested widget requires a new data piece, it calls for modifying all the methods upstream, making the process cumbersome and less efficient.

Conclusions

I started this project aiming to apply category theory and functional programming concepts to developing web applications in Java. Did we meet these goals?

  • Application Completion and Functionality: I successfully built a working Tic-Tac-Toe application. It closely follows the logic of its Haskell counterpart, achieving our primary objective

  • Use of Functional Programming Concepts: The outcome here is somewhat mixed. I incorporated a significant number of pure functions, primarily as Java static methods or non-static methods not tied to shared objects. This strategy resulted in classes having many small static functions, an approach not typical in Java where non-static methods are often preferred for their override-ability in subclasses. This method minimized the use of subclassing, aligning with functional programming principles

  • Class Design and Methodology: Ultimately, our classes consisted either of static methods or instance methods when implementing an interface. This distinction highlights the functional programming approach within the Java framework

  • Constraints and Differences Relative to Haskell: There are features in Haskell, like currying – the conversion of a function with multiple parameters into a series of single-argument functions – that Java does not directly support.

For my next project, I plan to investigate further into several areas highlighted by this exercise:

  • I'm going to examine the concept of 'View' as a Functor. In this context, for any business object X, a View<X> would be its representation in the user interface. I'm interested in seeing how compositions in the business domain translate into UI compositions

  • Another direction: considering the preference for aggregation over inheritance, I'll explore how the design pattern “Builder” is used to create intricate UI components.

Popular posts from this blog

Performance Testing a New CRM

Performance testing  is challenging, frustrating, often underestimated typically getting attention only after an incident. How did we the performance test and what did we learn during the development and implementation of  web-services for a new CRM system?

What Can Category Theory Do for Me?

Category Theory is one of the hot topics in computer science. There are many blogs, youtube videos and books about it. It is an elusive subject, with the potential to be the ultimate unifier of everything (math, quantum physics, social justice), to allow us to write the best possible programs and many other lofty goals. I decided to explore the field and see how it can help me. Below is a summary of 12 weeks of reading and watching presentations about Category Theory. It took me some time to select the study material. In the end I decided to use David Spivak’s book (Category Theory for Sciences, David Spivak, 2014) and the youtube recording of a 2017 workshop. These provided both a rigorous approach and a lighter version in the youtube videos. In parallel we explored other sources for a more practical perspective. The CTfS book is a systematic introduction to Category Theory, with definitions and proofs. I liked that, it is a solid foundation. The examples are mostly from math (Set,

On Defining Messages

“Defining Message Formats” is the title of a message posted on the Service Oriented Architecture mailing list [1]  which attracted a lot of attention.  The post summarizes  the dilemma faced by solution architects when they have to define a service interface: 1. Base the internal message format on the external message standard (MISMO for this industry). This message set is bloated, but is mature, supports most areas of the business, and is extensible for attributes specific to this company and its processes. 2. Create an XML-based message set based on the company's enterprise data model, which the company has invested a great amount of money into, and includes a very high percentage of all attributes needed in the business. In a nutshell, we've generated an XML Schema from ER Studio, and will tinker with that construct types that define the payloads for messages. 3. Use MISMO mainly for its entity definitions, but simplify the structure to improve usability. We benefit from the