Functional Programming - Improving Readability of Code

Coding is in many ways a form of communication. Just like any human language, a programming language allows us to express our intention in many different ways. A well written code can communicate its intention clearly and concisely to other developers. Functional Programming is a way of achieving this, and in the following example I’d like to illustrate how we can communicate better with Functional Programming constructs in Java 8.

Identifying Prime Numbers

Consider the rather simple task of printing the Prime numbers within a given List. Note that a Prime Number is a positive integer greater than 1 that is only divisible by 1 and itself. The program to achieve this using a simple imperative style may look like this:

boolean isPrime(int num) {
	boolean prime = true;
	if (num > 1) {
		for (int divisor = 2; divisor < num; divisor++) {
			if (num % divisor == 0) {
				prime = false;
				break;
			}
		}
	} else {
		prime = false;
	}
	return prime;
}

/**
 * Print prime numbers in a given list
 */
void printPrimes(List<Integer> values) {
	for (Integer num : values) {
		if (isPrime(num)) {
			System.out.println(num);
		}
	}
}

We can write the above in a declarative, functional way as follows:

boolean isPrime(int num) {
	return num > 1 &amp;&amp; IntStream.range(2, num)
				.noneMatch(divisor -> num % divisor == 0);
}

void printPrimes(List<Integer> values) {
	values.stream()
		.filter(Util::isPrime)
		.forEach(System.out::println);
}

Even though its a rather simple example, notice the lack of control structures (e.g. for/if) in the second approach. It is more like story telling instead of providing rigorous instructions to solve a problem. This is different from the imperative style, where we specify the details of how the problem needs to be solved as well as the control structure of the program. In this light, the second approach has the following advantages:

  • Since the details of how a task is performed is left out, the compiler/runtime can optimise how the tasks are carried out or even perform Lazy Evaluation
  • The cognitive load of understanding/following the control structures has been eliminated, thus improved clarity & readability
  • The second approach doesn’t require a variable, thus reduces mutable state - which is desirable in concurrency

Functional Program improves program correctness with immutability and side-effect free functions, hence there is little need for tricky and expensive synchronisation for shared mutable state. These properties make Functional Programming a natural choice for designing highly concurrent and distributed systems. Consider how easily the above program could be made concurrent and faster using Parallel Stream:

void printPrimes(List<Integer> values) {
	values.parallelStream()
		.filter(Util::isPrime)
		.forEach(System.out::println);
}

This highlights the ability of Functional Programming to scale horizontally in a distributed environment, which is increasingly important in the context of Big Data and multi-core CPU/GPU programming. For the complete code example please see: ImperativeDeclarativePrime.java

Fermi Telescope Finds Giant Structure in Our Galaxy

This is amazing - NASA finds two bubble like structures over and under the center of our galaxy. This could be related to the super massive galaxy at the center of our galaxy. It could be remnant of an explosion or eruption from the black hole.

fermi-explosion

This detection was made possible by the Fermi Satellite (2008) - Fermi scans the whole sky every 3 hours - scanning the sky in ever increasing detail NASA’s Fermi Telescope Finds Giant Structure in our Galaxy.

Google Map 5 Introduces 3D and Offline

Google Maps 5 for android introduces some awesome features:

  • Tilting: Drag down with two fingers to tilt the map. Tilt while zoomed in on one of the 100+ cities around the world with 3D buildings to see a skyline spring to life.
  • Rotating: Twist with two fingers to rotate the map. After tilting to see 3D buildings, rotate around them to gain a new perspective from any direction.
  • Smooth zooming: Slide two fingers together or apart, and see the map and labels continuously scale to any zoom level, stopping when your fingers stop.
  • Compass mode: Center the map on your location, and then tap the compass button in the top right corner. The map will flip into 3D mode and start rotating to match your perspective, while still keeping all the labels upright and readable.
  • Offline Caching and Rerouting: Rather than having a static set of maps when installed, Maps will automatically start caching the areas you visit the most when your device is plugged in and connected to WiFi. You’ll still need a connection to start a route, but if you miss a turn along the way, Google Maps Navigation will quickly get you back on track, even if you don’t have an Internet connection.

Apache Software Foundation Leaves JCP

Following a dispute over TCK licensing for the Apache Harmony project, ASF has quit the JCP. ASF explains their move here.

In the phrase “fail to uphold their responsibilities under the JSPA”, we are referring to Oracle’s refusal to provide the ASF’s Harmony project with a TCK license for Java SE that complies with Oracle’s obligations under the JSPA as well as public promises made to the Java community by officers of Sun Microsystems (recently acquired by Oracle.)  This breach of the JSPA was begun by Sun Microsystems in August of 2006 and is a policy that Oracle explicitly continues today.  For more information on this dispute, see our open letter to Sun Microsystems.

Further, they provide some strong conclusive remarks:

The Apache Software Foundation concludes that that JCP is not an open specification process - that Java specifications are proprietary technology that must be licensed directly from the spec lead under whatever terms the spec lead chooses; that the commercial concerns of a single entity, Oracle, will continue to seriously interfere with and bias the transparent governance of the ecosystem;  that it is impossible to distribute independent implementations of JSRs under open source licenses such that users are protected from IP litigation by expert group members or the spec lead; and finally, the EC is unwilling or unable to assert the basic power of their role in the JCP governance process.

It is a real shame they are leaving, as they have contributed significantly to the Java Ecosystem. This departure follow recent ones from Doug Lea and Tim Peierls who voted against Java SE JSRs. Looks like Java is going to have an interesting future ahead.

Hibernate Load Vs Get Differences

Programmers new to hibernate may face dilemmas trying to understand the subtle differences between hibernate’s get and load methods for retrieving an entity. I remember my struggle to grasp the differences, and thought I would compile the information I got from various web sources into one single post to help out others facing similar issues.

Here is a refresher on how these two methods can be used:

// Open the session
Session session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
// Load the Persistent entity using either Get or Load
Item itemByLoad = (Item) session.load(Item.class, new Long(1234));
//or should you use???
Item itemByGet = (Item) session.get(Item.class, new Long(1234));
tx.commit();
session.close();

Below we explore the various aspects of Load/Get operations in Hibernate to understand their differences.

Javadoc

  • Get: Return the actual instance of the given entity class with the given ID, or null if there is no such instance. (If the instance is already exists in the current Session, return that instance or proxy.)
  • Load: Return a proxy instance of the given entity class with the given ID, assuming that the instance exists in the database.

  • You should not use this method to determine if an instance exists (use get() instead).
  • Use this only to lazily retrieve an instance that you assume exists, where non-existence would be an actual error.

Querying for an instance that doesn’t exist in the database

  • Get: Database hit occurs· Returns null
  • Load: No database hit occurs· Returns a proxy· Calling getter/setter on the proxy throws ObjectNotFoundException  org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [User#123] 

Querying for an instance that exists in the database

  • Get: Database hit occurs· Returns the actual instance, not proxy i.e. no Lazy Loading optimization!
  • Load: Will always return a proxy (lazy loading optimization)

  • Database hit will not occur till you use getter/setter on the returned proxy.
  • If you don’t use getter/setter on the proxy load never generates a database hit, ie the object is never actually loaded from the database
  • The only exception to the above is when the object is already present in the persistence cache, it will return the cached instance instead of a proxy

Accessing properties from a detached entity

An entity becomes detached when it is outside of an active Hibernate Session.

  • Get: · All non-lazy properties can be accessed no Exception is thrown
  • Load: If you didn’t access any properties while the detached entity was in persistent within the persistent context, then your detached entity is basically a proxy placeholder – Calling any getter/setter will throw a LazyInitialization exception e.g.
session.beginTransaction();
User user=(User)session.load(User.class, new Long(1));
session.getTransaction().commit();
System.out.println(user.getPassword());

The above generates org.hibernate.LazyInitializationException: could not initialize proxy - no Session

Typical Usage Guidelines

  • Get: For the most part, you’ll probably use the get method most often in your code. If you ever want to use the JavaBean that you are retrieving from the database after the database transaction has been committed, you’ll want to use the get method, and quite frankly, that tends to be most of the time. For example, if you load a User instance in a Servlet, and you want to pass that instance to a Java Server Page for display purposes, you’d need to use the get method, otherwise, you’d have a LazyInitializationException in your JSP
  • Load: On the other hand, if your goal is largely transactional, and you are only going to be accessing the JavaBean of interest within a single unit of work that will pretty much end once the transaction is committed, you’ll want to use the load method.Furthermore, the load method may be the method of choice if you know, and are absolutely sure, that the entity you are searching for exists in the database with the primary key you are providing.

Example

The following illustrates the difference between Get/Load operation.

  • Get: Two SELECTs and one UPDATE are generated
  • Load: Only one SELECT and UPDATE for User are generated
public class PetService {
	public void purchasePet(Long ownerUserId, Long petId) {
		Session session = getSessionFactory().openSession();
		Transaction tx = session.beginTransaction();

		User owner = session.get(User.class, ownerUserId);
		/* or, using load 
		 * User owner = session.load( User.class, ownerUserId); */

		Pet purchasedPet = session.get(Pet.class, petId);
		/* or using load Pet 
		 * purchasedPet = session.load( Pet.class, petId); */

		owner.setPet(purchasedPet);

		tx.commit();
		session.close();
	}
}

Also see my other post regarding Hibernate Derived Properties.