Java polymorphism, also known as generics. Java being an



& Haskell:

We Will Write a Custom Essay Specifically
For You For Only $13.90/page!

order now

A Comparison



Programming languages, concurrency and client server computing





Luke Mason


BSc (Hons) Computer Science



Table of Contents


The differentiation between Haskell and Java is enormous.

Complied to native binaries, Haskell’s data is immutable by default and its
language is non-strict. Java is ran inside a virtual machine; its language is
strict and its data mutable. Java’s community is entrenched within the
industry, where people interested in Haskell are generally academicals as the
syntax reminisces mathematical notation. Comparisons in modularity, functional
purity, polymorphism and concurrency shall be explored among other concepts,
with a reflection on the implications of findings throughout.


Java and Haskell fundamentally handle code reuse in
separate ways. A functional programming language like Haskell uses an
expressive type system which means code writing is generalised and will work
for any number of types. This allows for parametric polymorphism, also known as
generics. Java being an object orientated language uses single inheritance (or
essentially multiple inheritance in Java 8) to reuse code. This provides for
ad-hoc polymorphism. In 2018, generics have entered Java because it is a powerful
feature used in the functional programming paradigm. Haskell can achieve ad-hoc
polymorphism through its system of type classes and instances, despite the type
classes differing from Java’s. Lazy evaluation can be used with Haskell to
reuse code in a larger context, while maintaining efficiency.



1 id :: x -> x                 1 data List x = Cons
x (List x)

2 id i = i                     2             | Nil


Fig 1: Polymorphic id  function                                         Fig 2: Haskell Polymorphic list



1 class X {

2     public void aMethod(Number arg) {

3     . . .

4     }

5 }


Fig 3: Java polymorphic method 1

Java focuses
on presenting instructions to a CPU one at a time. This is based on von Neumann
architecture; a model for input/output and fetch/execute.

Purity is fundamental in functional languages like
Haskell. Destructive assignment is impossible to do in Haskell, unlike in Java.

All pure data structures in Haskell are immutable (or persistent), where most
standard data structures in Java are mutable.


1 int x = y;

2 x = y + z;


Fig 4: An example of destructive assignment in java


Using these structures in Java can
lead to problems that are difficult to diagnose, as output methods can be inconsistent.

In Haskell, functions with no side effects have the property of referential transparency.

The output is guaranteed to be consistent, as factors like the state of the
file system do not interfere. Stateless
computations isolate side effects, which makes input/output related bugs easier
to find, and pure functions easier to test. Haskell uses the type system to quarantine
input and output bound code from pure code also.

Both Haskell and Java are static. They both are safe
languages and “fail fast” if something goes wrong. In Haskell, the problem of null is mitigated. Algebraic types have
the ability to append a ‘does not exist’ state. It will transform a type a into the type Maybe a. Java is notorious for including the billion-dollar mistake. Tony Hoare,
inventor of the null pointer believes this has led to system crashes, innumerable
errors and vulnerabilities. Polymorphic recursion lets programmers define
recursive function that can be generalise type variable. Haskell has a fantastic
generalization story. Haskell’s type system is an elaboration of the Hindley
Milner type system which has been derived from System F. Haskell’s type system
is consistent and straightforward, as it follows the structure of secondary
school mathematics2.

Haskell’s type system is its most distinguishable feature and many extensions
have been proposed towards the system, in attempt to make it a dependently
typed language.


Haskell programs are made up of a collection of modules.

These modules have a combined purpose of creating abstract data types and
control name spaces. Java programs on the other hand are modelled via classes
and objects. A model view controller (MVC) pattern is often practised in Java
for separation of concerns. This ensures for maintainability and efficiency. In
Haskell, the separation of concerns definition
of algebraic types of identifying the type name, naming constructors and specifying
component types assist the developer to create simple and correct solutions.

The lazy evaluation method is used to evaluate a Haskell program, which means expressions
that are bound to variables are not evaluated, and are deferred until their
results are required. Both modular and object-oriented programming can be used together.3


1 Public
class Main {

2    Public static void main (String args) {

3           System.out.println(“Hello Brighton!”);

4    }



Fig 5: A class in Java.



Module Main where


main :: IO()

main = putStrLn(“Hello Brighton!”)


Fig 6: A module in Haskell.


Within Java, the simplest way to avoid
concurrency problems is by only using immutable data between threads. Java’s
data is mutable by default, so you can make classes immutable by doing a number
of tasks, e.g. declaring a class and its all fields final (please refer to appendix
A). Mutable data may exist
in this class which it uses to manage its state. On the outside the class and
attributes cannot be changed. As Haskell’s data is immutable by default,
special declaration is not needed within its syntax. Other methods can be used to
prevent corruption of shared data in Java, such as locks and thread synchronisation
(used by using synchronised in your code). If a variable is declared as volatile, it’s likely a thread will
read its most recent value. 4


Whether Java or Haskell is better suited for big data is
up for debate. In my own personal opinion, Haskell would be more appropriate
for big data websites like Amazon, Facebook and Google. Big data websites
usually rely on excellent user interfaces. This means that rapid application
development is important. Functional programming ensures for quick prototyping 5.

It is modular in the functionality dimension, where Java is modular in the
dimension of different components. Data in Haskell doesn’t need to be protected
by locks unlike Java, it allows for safe multithreading and the immutable data
structures aren’t subject to data race conditions. It is easier within Haskell
to handle large formulas by using lambda expressions.


1 ghci>filter ( x -> even x && x
> 10) 1..20


Fig 7: Haskell example of a number sorter of even numbers greater than ten6


 Lazy evaluation is
also an advantage when it comes to writing programs to search data. However,
Java has fantastic libraries where Haskell does not.

It’s clear that both the object
orientated and functional programming paradigms differ. In 2018 approaches from
these paradigms seem to merge into both Haskell and Java. For example, Java now
uses generics. Java’s data is typically mutable but can easily be made immutable
by using ensuring classes and variables are final.


In conclusion, Java is a general-purpose, Turing complete
language designed to have as few implementation dependencies as possible. Its
concurrent nature makes it a versatile programming language that can be applied
to a number of domains, and has borrowed functional programming paradigms over
the years. Haskell’s purity makes it an impressive language to solve formal
approaches to computing, due to its mathematical notation.

Appendix A: An java class that has been made
immutable. 7


1 import


3 public
final class Bill {


5    private final int amount;

6    private final DateTime dateTime;


8    public Bill(int amount, DateTime dateTime) { 

9         this.amount = amount;

10         this.dateTime = dateTime;

11   }


13   public int getAmount() {

14         return amount;

15   }


17   public DateTime getDateTime() {

18         return dateTime;

19   }

20 }