Friday 14 October 2016

Highlights from the Plenary Sessions

Java 8

One of several talks on the magic that is now available via Java 8: Invoke allows us to abstract out a method definition and decide on it at run-time. As an example, imagine three methods that all take the same arguements:

Money doMoney(Trade t, market m)
Trade doTrade(Trade t, market m)
Par doPar(Trade t, market m)

At run-time you have to decide which method to call. So you create an abstracted method that contains the methods in a map

invoke(Key k, Trade t, market m) {
  map.put("m", doMoney)
  map.put("t", doTrade)
  map.put("p", doPar)
  ...
}

Then call the abstracted method. Note there is no need to edit the original methods (as would be the case with reflection).

Multi-threaded nature and parellel streams are great but difficult to get right because of shared mutable state. Hence go for immutable beans:

  • final classes/fields/types
  • use factories instead of constructors

Optional Interface: Prevents methods returning null. Instead of getValue (which can return null), use findValue (which returns actual value or default - never null).

Continuous Delivery

Case study of how they do deployment at LMAX Exchange.

Before they began using continuous deployment, their release cycles went like this:
freeze, release, panic, bug-fix, repeat.

LMAX exchange has 300 booleans hence 2^300 possible states in among 3 million lines-of-code. When he asked the CEO to choose two from speed, stability and features, the answer was stability, twice.

They use subversion with no branching(!), all commits are to the trunk. All commits tested via Jenkins (12,000 tests, 20-30 mins per build). Using a program (Scotty) for deployment (similar to SixDevEnv). Release contains a snapshot of all artefacts and configurations necessary (including firewall rules and load balancing config). Last stage before deployment is a staging area, which has identical hardware and data as production. Staging uses a copy of prod data, with data fields santitised (e.g. "Fred Bloggs" replaced with "First01 Second01").

Sonatype

The average application has 106 components (weblib + comlib?). Many libraries have CVSS advisory vulnerabilities, yet they still get downloaded and built-in. Sonatype plug-in for Eclipse lets you find the status of current and alternative versions and allows you to upgrade. You can set a build failure threshold if, for example CVSS > 5. Also provides a developer-friendly description of the vulnerability.

Serverless Cloud 

Everyone is into the rent-a-server market these days. There is Paas (Platform as a Service; where you rent a server) or Iaas (Infrastructure as a Service; where you rent a data-centre). Now there is FaaS (Functions as a Service), where you rent the server only long enough to run your program and are billed by CPU cycle-time. There are many players:

  • MS Azure Cloud Functions (quite good, actually)
  • AWS Lambda (from Amazon; terrible UI)
  • IBM BlueMix and OpenWhisk
  • Google Cloud Functions (still in beta)
  • Auth0 Webtask (very easy to use)

The demo tracked the output from a temperature sensor as is weaved its way backwards and forwards between several frameworks. Code fragments written mainly in Node.js (MS suppports C#...). No version control so an external repository is recommended.

Wednesday 12 October 2016

Day 1: Functional Programming

Brian May lookalike, Russel Winder, used to be a theoretical physicist working in QCD before he took up functional programming. He is a man who is very certain of his opinions. He began the workshop by declaring that Java is dead! He then qualified that by saying that Java is dead in the same way that Cobol is dead - it will take a thousand years before it finally disappears. Also, Scala is on the way out - apparently.

First, we compared the classic imperative paradigm, in which we dictate what the computer must do:
  • explicit iteration (loops)
  • mutable variables (watch for surprises: should use "final")
Contrast with the declarative paradigm, in which we let the runtime environment decide how to achieve the desired result:
  • implicit iteration (let the JVM work out the best way to iterate depending on the hardware)
  • immutable variables (harder to get it wrong).
We then moved on to the Hello World example - calculating factorials. If he were to condescend to use Java, he insisted on it being Java 9. At a push, he would go to Java 8 but not a minor revision lower. For the example, we used Frege (also know as, Haskall for the JVM). We started with a TDD approach, at which point he mentioned that the latest wisdom is to move from:
  • Example-based testing: x -> !; check for (0, 1), (1, 1), (7, x5040) etc.
to
  • Property-based testing: n=0, f(n)=1; n>0, f(n)=n*f(n-1) (Test uses recursion...). Examples are generated randomly by the JVM.
We then moved on to the fizzbuzz problem. We are looking for 1 ,2, fizz, 4, buzz, fizz, 7, 8, fizz, 10, 11, fizz, 13, 14, fizzbuzz,... and so on. Our first attempt was:

fizzbuzz = iterator 100 []
  where iterator 0 a = reverse a
        iterator i a = iterator(i-1)(a ++ [fb i]
  where fb x = if x mod 15 == 0 then "fizzbuzz"
               else if x mod 5 == 0 then "buzz"
               else if x mod 3 == 0 then "fizz"
               else show x

This works, but the fb function is basically Fortran and we are explicitly iterating. In a functional paradigm, this becomes:

choose x = if x mod 15 == 0 then "fizzbuzz"
           else if x mod 5 == 0 then "buzz"
           else if x mod 3 == 0 then "fizz"
           else show x
fizzbuzz = map choose [1..100]
main = println fizzbuzz

So the map function applies the choose algorithm to each element of the list (implicit iteration) However, we still have a Fortrany block in the choose method. Luckily, we have more functions:

fizzes = cycle ["", "", "fizz"]
buzzes = cycle ["", "", "", "", "buzz"]
fizzbuzzes = zipWith (++) fizzes buzzes
result = zipWith chooser fizzbuzzes [1..]
  where chooser s n = if s != "" then s
                      else show n
main = println (take 100 result)

The cycle function returns an infinite list that cycles among the elements. zipWith interleaves two lists into a list of 2-tuples. chooser takes each 2-tuple off the list and tests its elements.
  • fizzes gives us "", "", fizz, "", "", fizz, etc.
  • buzzes gives "", "", "", "", buzz, "", etc.
  • fizzbuzzes interleaves the fizzes and buzzes ("", ""), ("",""), (fizz, ""), ("",""), ("",buzz), etc.
  • result interleaves numbers with the fizzbuzzes, but uses the chooser function to decide what to select - if there's a word print it, else print the number.
The logical structure is reduced to a simple if..else, the iteration disappears and the infinite lists are never instantiated; we only use, at run-time, as much of the list as we need.

The next part of the workshop consisted of translating the solution above into Java. The key feature used was the Stream Interface, which allows us to connect to the fizzes and buzzes lists without instantiating them. The StreamUtils package provided the zipWith function and iteration was avoided by implementing the map-reduce pattern.

Finally, we embarked on yet another functional language, Kotlin. Actually, it turns out this one has procedural and object-oriented elements to it. Chatting to Brian later, I mentioned that I was beginning to suffer from language-fatigue, as yet another new language becomes the flavour of the month. What was wrong with Scala, I asked. His reply was that Scala was the first-pass at an enterprise-grade functional language. He thought it a solid effort, but feared that it had some basic design flaws that will limit it eventually. In his opinion, Kotlin is the real deal...