Writing functional code in Java
Apr-2016
So, with the onslaught of java 8, I, like many, was happy to believe java was finally a functionally compliant language. This is only somewhat true. Unfortunately, breaking old habits die hard in a language that makes them easy.
Why do we use mutable datatypes by default?
Mutability is a performance improvement, and should be treated as such. There are already some really great immutable data structure libraries out there for java, specifically guava, but I really can’t get behind some of the difficult interfaces for creating a changed version of an object that they offer. Because of this, I’ve created a new library to try and start making this process easier. I’m calling it barely-functional.
Lists
I love immutable lists. Whenever I don’t use immutable lists, that’s when I get into trouble, so here it is, I wrapped the calls to guava’s immutable list builder to do the lifting for me. I’m sick of typing ImmutableList.of(), and I want to use ImmutableMap.of(), so this is just no good.
Here it is, I’m drawing a line in the Java sand.
List ints = list(1, 2, 3, 4)); // [1, 2, 3, 4] List moreInts = push(ints, 5); // [1, 2, 3, 4, 5] List evenMore = unshift(ints, -1, 0); // [ -1, 0, 1, 2, 3, 4, 5] List firstNumberIsTwo = assoc(ints, 0, 2); // [ 2, 0, 1, 2, 3, 4, 5] List oneRemoved = remove(ints, 2); // [1, 2, 4] List oneInserted = insert(ints, 1, 6); // [1, 6, 2, 3, 4] |
Let’s also actually make it easy to get new lists with changed elements! Why do we make this hard?
Maps
I love guava maps! But once again, I am sick of typing ImmutableMap.of()! And i want arbitrary numbers of entries! And I want those entries to be succinct! So here’s the plan, we’re taking the letter e.
Map<string, integer=""> vals = map(e("a",1), e("b", 2)); // { "a" : 1, "b" : 2 } Map<string, integer=""> moreVals = assoc(vals, e("c", 3)); // { "a" : 1, "b" : 2, "c" : 3 } Map<string, integer=""> changeVals = assoc(vals, e("a", 3)); // { "a" : 3, "b" : 2, "c" : 3 } Map<string, integer=""> changeVals2 = assoc(vals, "b", 3); // { "a" : 3, "b" : 3, "c" : 3 } Map<string, integer=""> changeVals3 = dissoc(vals, "b"); // { "a" : 3, "c" : 3 } </string,></string,></string,></string,></string,> |
Sets
This is just like everything else.
Set ints = set(1, 2, 3); // (1, 2, 3) Set ints2 = assoc(ints, 4, 5); // (1, 2, 3, 4, 5) Set ints3 = dissoc(ints, 2, 3); // (1) Set union = union(ints, ints2); // (1, 2, 3, 4, 5) Set inter = intersection(ints, ints2); // (1, 2, 3) Set xor = xor(ints, ints2); // (4, 5) Set not1 = not(ints2, ints); // (4, 5) Set not2 = not(ints, ints2); // () |