Skip to main content

Posts

Showing posts from May, 2013

Null safety in Kotlin

Kotlin is a statically typed JVM language developed by Jetbrains. It has some good documentation so today I will focus on a tiny part of it - null safety.

There are at least couple of approaches to null handling in JVM languages:

Java doesn’t go much further than C - every reference (“pointer”) can be null, whether you like it or not. If it’s not a primitive, every single field, parameter or return value can be null.

Groovy has similar background but adds some syntactic sugar, namely Elvis Operator (?:) and Safe Navigation Operator (?.).

Clojure renames null to nil, additionally treating it as false in boolean expressions. NullPointerException is still possible.

Scala is first to adopt systematic, type safe Option[T] monad (Java 8 will have Optional<T> as well!) Idiomatic Scala code should not contain nulls but when interoperating with Java you must sometimes wrap nullable values.

Kotlin takes yet another approach. References that can be null have different type, thus null-safety …

Lazy sequences implementation for Java 8

I just published LazySeq library on GitHub - result of my Java 8 experiments recently. I hope you will enjoy it. Even if you don't find it very useful, it's still a great lesson of functional programming in Java 8 (and in general). Also it's probably the first community library targeting Java 8!

IntroductionLazy sequence is a data structure that is being computed only when its elements are actually needed. All operations on lazy sequences, like map() and filter() are lazy as well, postponing invocation up to the moment when it is really necessary. Lazy sequence is always traversed from the beginning using very cheap first/rest decomposition (head() and tail()). An important property of lazy sequences is that they can represent infinite streams of data, e.g. all natural numbers or temperature measurements over time.

Lazy sequence remembers already computed values so if you access Nth element, all elements from 1 to N-1 are computed as well and cached. Despite that LazySeq (…

Java 8: CompletableFuture in action

After thoroughly exploring CompletableFuture API in Java 8 we are prepared to write a simplistic web crawler. We solved similar problem already using ExecutorCompletionService, Guava ListenableFuture and Scala/Akka. I choose the same problem so that it's easy to compare approaches and implementation techniques.

First we shall define a simple, blocking method to download the contents of a single URL:

private String downloadSite(final String site) { try { log.debug("Downloading {}", site); final String res = IOUtils.toString(new URL("http://" + site), UTF_8); log.debug("Done {}", site); return res; } catch (IOException e) { throw Throwables.propagate(e); } } Nothing fancy. This method will be later invoked for different sites inside thread pool. Another method parses the String into an XML Document (let me leave out the implementation, no one wants to look at it):

private Document parse(String xml) //.…

Java 8: Definitive guide to CompletableFuture

Java 8 is coming so it's time to study new features. While Java 7 and Java 6 were rather minor releases, version 8 will be a big step forward. Maybe even too big? Today I will give you a thorough explanation of new abstraction in JDK 8 - CompletableFuture<T>. As you all know Java 8 will hopefully be released in less than a year, therefore this article is based on JDK 8 build 88 with lambda support. CompletableFuture<T> extends Future<T> by providing functional, monadic (!) operations and promoting asynchronous, event-driven programming model, as opposed to blocking in older Java. If you opened JavaDoc of CompletableFuture<T> you are surely overwhelmed. About fifty methods (!), some of them being extremely cryptic and exotic, e.g.:

public <U,V> CompletableFuture<V> thenCombineAsync( CompletableFuture<? extends U> other, BiFunction<? super T,? super U,? extends V> fn, Executor executor) Don't worry, but keep reading. …

Synchronising Multithreaded Integration Tests revisited

I recently stumbled upon an article Synchronising Multithreaded Integration Tests on Captain Debug's Blog. That post emphasizes the problem of designing integration tests involving class under test running business logic asynchronously. This contrived example was given (I stripped some comments):

public class ThreadWrapper { public void doWork() { Thread thread = new Thread() { @Override public void run() { System.out.println("Start of the thread"); addDataToDB(); System.out.println("End of the thread method"); } private void addDataToDB() { // Dummy Code... try { Thread.sleep(4000); } catch (InterruptedException e) { e.printStackTrace(); } } }; thread.start(); System.out.println("Off and running..."); …

Lazy sequences in Scala and Clojure

Lazy sequences (also known as streams) are an interesting functional data structure which you might have never heard of. Basically lazy sequence is a list that is not fully known/computed until you actually use it. Imagine a list that is very expensive to create and you don't want to compute too much - but still allow clients to consume as much as they want or need. Similar to iterator, however iterators are destructive - once you read them, they're gone. Lazy sequences on the other hand remember already computed elements.

Notice that this abstraction even allows us to construct and work with infinite streams! It's perfectly possible to create a lazy sequence of prime numbers or Fibonacci series. It's up to the client to decide how many elements they want to consume - and only that many are going to be generated. Compare it to eager list - that has to be precomputed prior to first usage and iterator - that forgets about already computed values.

Remember however that l…