1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
|
<!DOCTYPE html>
<html>
<head>
<title>
The Codex »
A New Kind of Java
</title>
<link
rel='stylesheet'
type='text/css'
href='http://fonts.googleapis.com/css?family=Buenard:400,700&subset=latin,latin-ext'>
<link
rel="stylesheet"
type="text/css"
href="../media/css/reset.css">
<link
rel="stylesheet"
type="text/css"
href="../media/css/grimoire.css">
</head>
<body>
<div id="shell">
<ol id="breadcrumbs">
<li class="crumb-0 not-last">
<a href="../">index</a>
</li>
<li class="crumb-1 not-last">
<a href="./">java</a>
</li>
<li class="crumb-2 last">
a-new-kind-of
</li>
</ol>
<div id="article">
<h1 id="a-new-kind-of-java">A New Kind of Java</h1>
<p>Java 8 is almost here. You can <a href="http://jdk8.java.net/download.html">play with the early access
previews</a> right now, and I think you
should, even if you don't like Java very much. There's so much <em>potential</em> in
there.</p>
<h2 id="the-one-more-thing">The “One More Thing”</h2>
<p>The Java 8 release comes with a slew of notable library improvements: the new
<a href="http://openjdk.java.net/jeps/150"><code>java.time</code></a> package, designed by the folks
behind the extremely capable Joda time library; <a href="http://openjdk.java.net/jeps/118">reflective
access</a> to parameter names; <a href="http://openjdk.java.net/jeps/133">Unicode
6.2</a> support; numerous others. But all of
these things are dwarfed by the “one last thing”:</p>
<p><strong>Lambdas</strong>.</p>
<h2 id="ok-so">Ok, So..?</h2>
<p>Here's the thing: all of the “modern” languages that see regular use - C#,
Python, Ruby, the various Lisps including Clojure, and Javascript - have
language features allowing easy creation and use of one-method values. In
Python, that's any object with a <code>__call__</code> method (including function
objects); in Ruby, it's blocks; in Javascript, it's <code>function() {}</code>s. These
features allow <em>computation itself</em> to be treated as a value and passed
around, which in turn provides a very powerful and succinct mechanism for
composing features.</p>
<p>Java's had the “use” side down for a long time; interfaces like <code>Runnable</code> are
a great example of ways to expose “function-like” or “procedure-like” types to
the language without violating Java's bureaucratic attitude towards types and
objects. However, the syntax for creating these one-method values has always
been so verbose and awkward as to discourage their use. Consider, for example,
a simple “task” for a thread pool:</p>
<pre><code>pool.execute(new Runnable() {
@Override
public void run() {
System.out.println("Hello, world!");
}
});
</code></pre>
<p>(Sure, it's a dumb example.)</p>
<p>Even leaving out the optional-but-recommended <code>@Override</code> annotation, that's
still five lines of code that only exist to describe to the compiler how to
package up a block as an object. Yuck. For more sophisticated tasks, this sort
of verbosity has lead to multi-role “event handler” interfaces, to amortize
the syntactic cost across more blocks of code.</p>
<p>With Java 8's lambda support, the same (dumb) example collapses to</p>
<pre><code>pool.execute(() -> System.out.println("Hello, world"));
</code></pre>
<p>It's the same structure and is implemented very similarly by the compiler.
However, it's got much greater informational density for programmers reading
the code, and it's much more pleasant to write.</p>
<p>If there's any justice, this will completely change how people design Java
software.</p>
<h2 id="event-driven-systems">Event-Driven Systems</h2>
<p>As an example, I knocked together a simple “event driven IO” system in an
evening, loosely inspired by node.js. Here's the echo server I wrote as an
example application, in its entirety:</p>
<pre><code>package com.example.onepointeight;
import java.io.IOException;
public class Echo {
public static void main(String[] args) throws IOException {
Reactor.run(reactor ->
reactor.listen(3000, client ->
reactor.read(client, data -> {
data.flip();
reactor.write(client, data);
})
)
);
}
}
</code></pre>
<p>It's got a bad case of Javascript “arrow” disease, but it demonstrates the
expressive power of lambdas for callbacks. This is built on NIO, and runs in a
single thread; as with any decent multiplexed-IO application, it starts to
have capacity problems due to memory exhaustion well before it starts to
struggle with the number of clients. Unlike Java 7 and earlier, though, the
whole program is short enough to keep in your head without worrying about the
details of how each callback is converted into an object and without having to
define three or four extra one-method classes.</p>
<h2 id="contextual-operations">Contextual operations</h2>
<p>Sure, we all know you use <code>try/finally</code> (or, if you're up on your Java 7,
<code>try()</code>) to clean things up. However, context isn't always as tidy as that:
sometimes things need to happen while it's set up, and un-happen when it's
being torn down. The folks behind JdbcTemplate already understood that, so you
can already write SQL operations using a syntax similar to</p>
<pre><code>User user = connection.query(
"SELECT login, group FROM users WHERE username = ?",
username,
rows -> rows.one(User::fromRow)
);
</code></pre>
<p>Terser <strong>and</strong> clearer than the corresponding try-with-resources version:</p>
<pre><code>try (PreparedStatement ps = connection.prepare("SELECT login, group FROM users WHERE username = ?")) {
ps.setString(1, username);
try (ResultSet rows = rs.execute()) {
if (!rows.next())
throw new NoResultFoundException();
return User.fromRow(rows);
}
}
</code></pre>
<h2 id="domain-specific-languages">Domain-Specific Languages</h2>
<p>I haven't worked this one out, yet, but I think it's possible to use lambdas
to implement conversational interfaces, similar in structure to “fluent”
interfaces like
<a href="http://docs.oracle.com/javaee/6/api/javax/ws/rs/core/UriBuilder.html">UriBuilder</a>.
If I can work out the mechanics, I'll put together an example for this, but
I'm half convinced something like</p>
<pre><code>URI googleIt = Uris.create(() -> {
scheme("http");
host("google.com");
path("/");
queryParam("q", "hello world");
});
</code></pre>
<p>is possible.</p>
</div>
<div id="comments">
<div id="disqus_thread"></div>
<script type="text/javascript">
/* * * CONFIGURATION VARIABLES: EDIT BEFORE PASTING INTO YOUR WEBPAGE * * */
var disqus_shortname = 'grimoire'; // required: replace example with your forum shortname
/* * * DON'T EDIT BELOW THIS LINE * * */
(function() {
var dsq = document.createElement('script'); dsq.type = 'text/javascript'; dsq.async = true;
dsq.src = 'http://' + disqus_shortname + '.disqus.com/embed.js';
(document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(dsq);
})();
</script>
<noscript>Please enable JavaScript to view the <a href="http://disqus.com/?ref_noscript">comments powered by Disqus.</a></noscript>
<a href="http://disqus.com" class="dsq-brlink">comments powered by <span class="logo-disqus">Disqus</span></a>
</div>
<div id="footer">
<p>
The Codex —
Powered by <a href="http://markdoc.org/">Markdoc</a>.
<a href="https://bitbucket.org/ojacobson/grimoire.ca/src/master/wiki/java/a-new-kind-of.md">See this page on Bitbucket</a> (<a href="https://bitbucket.org/ojacobson/grimoire.ca/history-node/master/wiki/java/a-new-kind-of.md">history</a>).
</p>
</div>
</div>
</body>
</html>
|