In this article I briefly explore Wealthfront’s extensive usage of expressive and fluent interfaces in Java such as Kawala, Guice, Mockito, and Guava. To the uninitiated, Java invokes parables of moronic XML, obtuse syntax, and Nile-like constructor calls. As a result, Java’s status as a living language is often questioned and it’s “uncoolness” is dogmatically spread. A common characteristic of programming languages and frameworks considered “cool” by the Silicon Valley hacker scene is expressiveness. I will show that modern Java frameworks such as Kawala, Guice, Mockito, and Guava corroborate Java’s adaptability. Java’s ability to give voice to newer, more expressive programming styles (despite political tomfoolery and slow progress on the, new, Java 7 specification) indicates that it will remain a leading choice for applications of any size.
Providing a definition of expressiveness is left as an exercise to the reader. Here, instead of a definition we’ll provide a few representative examples of non-Java expressive programming interfaces.
Node.js is a chief example of an emerging, “trendy” programming framework, with a non-mainstream, following. It capitalizes on Javascript’s conciseness to bring forth prose-like readability. The results are best exemplified by its Hello World example:
var http = require('http'); http.createServer(function (req, res) { res.writeHead(200, {'Content-Type': 'text/plain'}); res.end('=Hello Worldn'); }).listen(8124, "127.0.0.1");
Similarly, RSpec is a well-respected (and trendy) behavior-driven development tool for Ruby that integrates aspects of Test-Driven Development (which we reverently practice here at Wealthfront). The fact that its “Get Started Now” example is amply self-descriptive and can be presented with no further commentary speaks to its expressiveness:
require 'bowling' describe Bowling, "#score" do it "returns 0 for all gutter game" do bowling = Bowling.new 20.times { bowling.hit(0) } bowling.score.should == 0 end end
In both cases, syntax lends itself to form a localized miniature domain-specific language to effectively express the concern at hand, and nothing further.
import static org.mokcito.Mockito.*; [...] TradingSchedule schedule = mock(TradingSchedule.class); final DateTime weekend = [...]; when(schedule.canTradeAt(weekend)).thenReturn(false); NasdaqMarket m = NasdaqMarket.withTradingSchedule(schedule).build(); assertFalse(m.canScheduleTrade(weekend, SELL, 100, NASDAQ_WLTH)); verify(schedule).proposeAllowedDate(weekend);
bind(Integer.class).annotatedWith(named("login timeout seconds")).toInstance(10); bind(TransactionLog.class).toProvider(DatabaseTransactionLogProvider.class); bind(CreditCardProcessor.class).to(PaypalCreditCardProcessor.class); bind(Market.class).to(NasdaqMarket.class);
Requesting that a constructor receives its dependencies via dependency injection is as easy as specifying the @Inject annotation. Wealthfront’s entire backend application stack, processing immense amounts of market data daily, relies heavily on Guice for dependency resolution and configuration.
Guava allows the easy construction of type-safe ImmutableLists with a quick static call such as List s = ImmutableList.of(“A”, “B”, “C”). Guava includes a variety of functional methods to operate on its collections. For example, one could easily filter a list of integers based on parity:
List<integer> x = Iterables.filter(input, new Predicate<integer>() { public boolean apply(Integer input) {return (input % 2) == 0;}});