This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Map map = new HashMap(); //you're forced to create a temporary variable | |
map.put(1, "one"); | |
map.put(2, "two"); //because you can't chain these void method calls(mutators) | |
... | |
return map; |
Nothing wrong with it, but wouldn't it be nice to be able to chain those calls and avoid declaring that local variable?
I am currently reading "The Joy of Clojure" and came across the doto macro in clojure, which enables you to do the above like so:
(doto (new java.util.HashMap) ; or just (java.util.HashMap.)
(.put 1 "One")
(.put 2 "Two"))
Nice! But alas, I am forced to use Java by day so I tried to figure out the best approach to do this. The first one comes to mind is this:
new HashMap<Integer, String>(){{
put(1, "one");
put(2, "Two");
}};
Which works perfectly except that it assumes you are the one constructing the object. So I tried a more functional approach:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static <K> Doto<K> doto(K k){ | |
return new Doto(k); | |
} | |
public static class Doto<T>{ | |
private T t; | |
private Doto(T t){ | |
this.t = t; | |
} | |
public T DO(FVoid<T> f){ | |
f.apply(t); | |
return t; | |
} | |
} | |
public interface FVoid<T>{ | |
public void apply(T t); | |
} | |
//Which can be used like so : | |
doto(Maps.<Integer, String>newHashMap()).DO(new FVoid<HashMap<Integer, String>>(){ | |
public void apply(HashMap<Integer, String> map){ | |
map.put(1, "one"); | |
map.put(2, "Two"); | |
} | |
}); |
I believe I've gone and made it worse :(
I also tried a js implementation, which is pretty redundant for maps/objects as object literals are built in:
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function doto(m, f){f(m); return m;} | |
//var result = {1: "One", 2: "Two"} | |
var result = doto({}, function(m){ m[1] = "One"; m[2] = "Two"}); |
I would love to see some alternate solutions/improvements or maybe event implementations in other languages!