Saturday 29 October 2016

The Martingale using Lambdas

I created a small blog post some time ago regarding the Martingale System of Gambling.

In it, a programming example is available, which could be rewritten using the Lambda style in Java 8.

I am going to attempt doing just that and post my results below.

ForEach

When I was following the MOOC course of Oracle1, Simon Ritter quite emphatically mentioned trying not to use the foreach method when not required.

But let us try it now, as a seemingly perfectly reasonable first step on a slippery slope to hell.

What we need is a stream of random numbers, and then run the foreach on it.
So far, so good.

Still doesn't look very much better, and perhaps even a little bit worse.

Mapping

Let's try to make it better.

For this we are going to use an "Account" class. Like this:

This class will be used in the Lambda, like so:

Conclusion

Lambdas can make your code look a lot cleaner. However, they can never replace all the loops in your code, as witnessed in the example above.

I'd really like to use collect or reduce instead of the forEach in the example, but I don't think I can.

But if anyone has any suggestions on how to fix it, please tell me.

For the source code to the "Bet" class, check out https://gist.github.com/maartenl/a804f4ac435f491b57c7ae810d5fd577.

Peek and Debugging

Peek is very valuable if you wish to do some debugging of your new Lambdas.

Using the following:
new Random()
           .ints(0, 37)
           .peek(System.out::println)
           .mapToObj(x -> Bet.getBet(x))
           .peek(System.out::println)
           .forEach(x
                   ->
                   {
                     if (x == Bet.RED)
                     {
                       account.add();
                     } else
                     {
                       account.subtract();
                     }
           });

You get some nice output to see what's happening:
10
BLACK
29
BLACK
11
BLACK
19
RED
26
BLACK
34
RED
34
RED

References

[1] Oracle - Announcing: JDK 8 MOOC: Lambdas and Streams!
https://blogs.oracle.com/javatraining/entry/announcing_jdk_8_mooc_lambdas
[2] The Java™ Tutorials > Collections > Aggregate Operations - Reduction
https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html
Wikipedia - Roulette
https://en.wikipedia.org/wiki/Roulette

Thursday 20 October 2016

Potential heap pollution via varargs parameter

Reifiable versus Non-Reifiable

Type erasure is an important "feature" of Generics in Java. It means generics are not available at runtime, as they are effectively removed during compiling.

The reference in [1] has a much better explanation.

To quote:
“A reifiable type is a type whose type information is fully available at runtime.”
“Non-reifiable types are types where information has been removed at compile-time by type erasure.”

Generics versus Arrays

In Java, generics are non-reifiable and arrays are reifiable.

Problems can occur when we combine these two together.

Combining these two together can happen when using the varargs construction in Java.

The reason for this is that the varargs way of using method parameters is translated within the method as a array.

This can cause Heap pollution2 when combined with Generics.

As the compiler doesn't know when this happens (it depends on how the method deals with it), it throws out the warning.

Hence the need for the @SafeVarargs3 annotation for those methods where the software designers are certain the problem does not occur.

References

[1] Non-Reifiable Types
http://docs.oracle.com/javase/tutorial/java/generics/nonReifiableVarargsType.html
[2] 9.6.3.7. @SafeVarargs
http://docs.oracle.com/javase/specs/jls/se7/html/jls-9.html#jls-9.6.3.7
[3] Oracle JavaDoc - SafeVarargs
http://docs.oracle.com/javase/7/docs/api/java/lang/SafeVarargs.html
StackOverflow - Potential heap pollution via varargs parameter
http://stackoverflow.com/questions/12462079/potential-heap-pollution-via-varargs-parameter

Thursday 13 October 2016

The Joel Test

I found a link regarding a job opportunity at a Banking establishment1. (I don't know how long that link is going to stay current, sorry about that.)

They included a little list of the software practices that they follow. Apparently it is called the "Joel Test"2.

So I thought I'd mention it here, for those interested about comparing companies.

References

[1] StackOverflow - Mid-Level Java Developer at Leading Sustainable Bank
http://stackoverflow.com/jobs/122285/mid-level-java-developer-at-leading-sustainable-triodos-bank?med=clc&ref=small-sidebar-tag-themed-java
[1] The Joel Test: 12 Steps to Better Code by Joel Spolsky
http://www.joelonsoftware.com/articles/fog0000000043.html

Thursday 6 October 2016

Window Shades Buttons

At work, we have window shades on the outside of the office building that we work in. Inside there are buttons (visible in the picture on the left) that we can use to regulate the lowering and the raising of the window shades.

As a software engineer there's a major mismatch regarding the buttons. A zoomed in version is available below:

The buttons are binary (on or off). There's two buttons, one for up and one for down. Purely functionally it means there are four different options for the buttons to be in:
up is off and down is on
the window shade will travel down until it covers the entire window
up is on and down is off
the window shade will move up, until the entire window is free
up is off and down is off
the window shade will not move
up is on and down is on
the window shade will not move
Clearly there are two combinations possible, that cause the same result. Namely, the window shade will not move.

So on some mornings, I need to turn "down" on to drop the shades and on some days I need to turn "up" off to drop the shades. And I frequently get it wrong.

This extra difficulty could have been eliminated with a three state button, that has the default state of "will not move" and "up" and "down" for special states.

I know it seems trivial, but it is the little things that get on some peoples nerves the most.