Channels ▼

Bil Lewis

Dr. Dobb's Bloggers

How much would you pay for a closure?

June 13, 2009

I know there's been discussion about this in the Java world, but I
don't see the cost/value benefit. Perhaps you can enlighten me!

Today we build closures in Java the hard way. We build objects that
encapsulate the computation and give 'em an execute() method that does
the work. It's not hard to do and we have a whole variety of places
where we use this. Most of the time we don't even think in terms of a
"closure" per-se, just an object that will produce the desire result
when called on.

On rare occasions we use inner classes so that we can close over some
local variables. It's a bit awkward, but it is rare. 

Most of our code we write in the "old fashioned"
way--call/return. 'Cause it works really well and it's easy to
understand and it mirrors the real world.

Everything you add to a language costs something. It makes the
language more complex and harder to use. It often has non-obvious
computational expenses. The question is "Does the feature make writing
programs easier?" And if so, how much?

For example, "auto boxing", which seems so clever at first glance,
harbors some ugly little secrets. 

Auto boxing is where the compiler "fixes up" your code by adding a
method call that you didn't write. The issue is that primitives are
not of type Object, like everything else. If this was a wise thing to
do is an open question. But it was done. So normally, this would be

void doStuff(List list, int i) {

because add is expecting an Object. If you really wanted to add an int
to this list, you'd have to do the boxing yourself:

void doStuff(List list, int i) {
  list.add(new Integer(i));

By allowing the compiler to do this for you, it's easy to miss the
fact that this is going to be a very expensive call. And if what you
really wanted was a list of ints, you'd be unhappy.

So is auto boxing a good thing because it saves some typing. It's bad
because it can fool you. It's also a very rare thing to ever
do. Normal programmers will never see a situation where they want to
pass an int as type Object. 

(Write a ListInt class!) 

Only us reflective guys do this much. And we avoid auto boxing,
because we always want more control over what our program is doing in
these situations.

In Lisp languages (I'm gonna futz a bit with Scheme style, just
details), a function is (mostly) a first class object. Meaning that
you get closures practically for free. You could write this:

(setq plus1 (lambda(a) (+ a 1)))
(plus1 2) => 3

and more generally you can "close over" variable bindings:

(setq plus3 ((lambda(inc) (lambda(a) (+ a inc))) 3))
(plus3 4) => 7

It works great and the compilers can produce excellent binary from

By contrast, to do the same in Java, you must construct an object and
call a named method:

plus4 = new Plus(4);
plus4.add(5) => 9

class Plus {
  int inc;

  Plus(int inc) { = inc;

  int add(int i) {
    return i + inc;

Clearly the Java code is much more verbose than the Lisp code and it compiles
better then the Lisp code only because it has type declarations.

One could imagine a syntax in Java:

int inc = 6;
Closure plus6 = Closure(int i) {return i + inc;};
plus6(7) => 31

This would save the poor programmer from 10 additional lines of
code. Clearly, that's good. But is it worth it? Now the language is
more complex and there are lots of complications in the implementation
of efficient closures. And details for the programmer to understand.

I don't like learning weird little details.

The question for me is "Will I use this feature enough and is it
obvious enough in its usage to be worth including in the language?"

Macros, for example, are one of the banes of C/C++. They are so clever
and do such wonderful things, and have a bad habit of not being quite
as straight-forward as one would like. At the last count,
1,234,656,993 hours have been wasted due to subtle bugs in macros.

When I was writing a lot of Lisp, back in the 70s and 80s, I used
closures once in a blue moon. And I liked using them. I actually read
Church's thesis!

Without closures, I would have to rewrite 0.0194% of my code.

Is it worth the complication to save 0.0194% of my code?



Generics in Java: good!
Autoboxing:       bad
Delegates in C#:  bad
Closures in Java: bad
Macros anywhere:  bad

Waddya think?




Related Reading

More Insights

Currently we allow the following HTML tags in comments:

Single tags

These tags can be used alone and don't need an ending tag.

<br> Defines a single line break

<hr> Defines a horizontal line

Matching tags

These require an ending tag - e.g. <i>italic text</i>

<a> Defines an anchor

<b> Defines bold text

<big> Defines big text

<blockquote> Defines a long quotation

<caption> Defines a table caption

<cite> Defines a citation

<code> Defines computer code text

<em> Defines emphasized text

<fieldset> Defines a border around elements in a form

<h1> This is heading 1

<h2> This is heading 2

<h3> This is heading 3

<h4> This is heading 4

<h5> This is heading 5

<h6> This is heading 6

<i> Defines italic text

<p> Defines a paragraph

<pre> Defines preformatted text

<q> Defines a short quotation

<samp> Defines sample computer code text

<small> Defines small text

<span> Defines a section in a document

<s> Defines strikethrough text

<strike> Defines strikethrough text

<strong> Defines strong text

<sub> Defines subscripted text

<sup> Defines superscripted text

<u> Defines underlined text

Dr. Dobb's encourages readers to engage in spirited, healthy debate, including taking us to task. However, Dr. Dobb's moderates all comments posted to our site, and reserves the right to modify or remove any content that it determines to be derogatory, offensive, inflammatory, vulgar, irrelevant/off-topic, racist or obvious marketing or spam. Dr. Dobb's further reserves the right to disable the profile of any commenter participating in said activities.

Disqus Tips To upload an avatar photo, first complete your Disqus profile. | View the list of supported HTML tags you can use to style comments. | Please read our commenting policy.