This content is part of the Essential Guide: .NET programming language tutorial: Making more with .NET development

Functional programming in Java 8 vs. .NET: What you need to know

The 'which is better' debate over .NET and Java has been going on forever. Expert Tom Nolle weighs in on which is the better choice if your goal is functional programming.

Probably the most enduring and multifaceted debate in all of software development is whether the Java or Microsoft .NET platforms and ecosystems are best. Both have enthusiastic and loyal supporters, but there's also a large, uncommitted community that could swing the balance decisively.

Every time something new comes along, it presents an opportunity for such a swing, and functional programming is no different. Is functional programming in Java 8 better than .NET, or the other way around?

Modularity and composability are the goals of all modern software design. Historically, they've been achieved using object-oriented or service-oriented programming, where functions are built as independent components and composed using specified interfaces and rules. Complex functions would necessarily have complex interrelationships, making open composition difficult.

Start by doing the math

Functional programming in Java 8 or anything else is an almost-mathematical approach to the problem, where logic is built by assembling functions built, so the input to one is always the output of another. Variables are immutable, and only a function can provide a variable result. Essentially, logic is a function pipeline built from what are called lambda expressions.  The concept has been around in various forms for decades, but it's becoming more popular as modularity and composability become more and more important. Functional programming in Java 8 is supported, and so .NET programmers want to know how they can adopt the model.

Is functional programming in Java 8 better than .NET, or the other way around?

There are two basic paths to functional programming in .NET: Programmers can use C# and evolving features to support lambda functions, or they can use the open source functional language Microsoft announced in 2010 -- F#.  Most users of F# say they also use C#. And, in many cases, they use it within the same application. Many programmers try to stay with C# if they're familiar with it, but most who have made the transition to F# would agree it's the better choice. And it's wise to assume if you're going to do .NET functional programming, you're going to do it in F#.

For Java users, particularly those focusing on functional programming in Java 8 with all of its advances, the C# path is the most comparable. You can write functional code in C# and use constructs that enforce some of the key behaviors of functional programming -- like immutable variables and statelessness -- but you can also write object-oriented programming or imperative programs. This is comparable to Java 8's approach.

Learn about F#

F# is different, because it's one of the few languages that is designed for functional programming alone.  Most F# users admit the learning curve is a bit steep, but once you're over it, you can write better functional programs faster -- better than C# and better than Java 8. F# is also, arguably, the only commercial language for functional programming; the other options are more commonly used in academic environments.

The primary benefit its commercial bend gives F#, versus other functional languages, is its combination of easy integration and functional purity. You can access all of the .NET libraries, and also Java libraries that have been compiled to .NET -- a fairly straightforward task. But, at the same time, F# enforces functional and lambda purity in coding practices and generates more readable code. As a member of the .NET family, you can compile F# units and then use them in any of the other .NET languages, so there's no loss of .NET functionality or integrability. This is why .NET users are increasingly turning to F# for functional development; the transition is easy.

Understanding functional-friendly data structures and immutability of variables in F# is critical, and that concept can be hard to grasp for C# or Java programmers. Data structures are one of the few things that are harder in F#, which means not only that it will make a transition harder, but it might create temptation to move back to an object-oriented imperative model. It's wise to read up on functional data structures and the substitution of functions for mutable variables before you even dig deeply into F#, or you may find the framework of functional programming difficult. Simple "Hello, World" applications don't expose enough of the functional approach to be helpful. Look for samples of complex data structures, including mathematical structures.

There are no specific named classes in functional programming in Java 8 or elsewhere, and functional elements of an application should be clearly identified to prevent confusion or contamination. That means organizing your code is critical, especially in larger projects. Functional .NET programs should always be packaged and named to make the implementation language and target architecture -- F#, pure .NET -- clear. Consider reviewing the guidelines from the F# Core Engineering Group for your own projects to ensure readability of your package names. Readability of functional code is also enhanced by using consistent indenting to make function elements stand out.

Think microservices

While .NET functional programming has many integration advantages, many .NET developers struggle in relating functional programming to their broader applications, particularly web-based applications.  Functional programs are stateless, which means they aren't as useful as interfaces to GUI processes, where it's customary for the application to retain state to support multiphase dialogs. One technique to consider in helping this process along is to think of functional elements as microservices.  Microservices best practice would dictate that microservices are stateless and quite functional in nature, and functional programming in Java 8 or any other language mandates stateless components by design.

For .NET users committed to Azure, Microsoft supports functional programming as a web service, using its Functions product, and its focus is to handle event-driven elements of an application. The microservice thinking just recommended may help developers use Azure Functions to extend current logic, and even to extend Azure Functions with functional components in the data center. The benefits of Functions in event-handling are also a good primer on an important application of functional programming.

The Azure connection also demonstrates that functional programming is a natural partner to the cloud, and that may be the biggest reason why .NET users should be thinking about it. If your company believes in cloud computing, and if you still do in-house or even contract software development, then you should be taking a strong look at functional programming and the Microsoft-sanctioned tools, like F#, that support it.

Next Steps

When .NET meets the IoT

Where is .NET headed? A Microsoft exec explains

Dig Deeper on Software project management