Friday, November 27, 2009

Extension methods: the case for language-level delegates in Java

Extension methods

In There's not a moment to lose!, Mark Reinhold announces something completely different: Java 7 will have closures after all. Huzzah! And in that announcement, he lists enabling language changes for them:

  • Literal syntax
  • Function types
  • Closure conversion
  • Extension methods

I want to look at extension methods closely. Alex Miller does an admirable task of summarizing JDK7 changes; that's a good place to start. And some code:

public final class Filtering {
    public static <T, C extends Collection<T>> C filterInto(
            Collection<T> input, C output, Filter<T> filter) {
        for (T item : input)
            if (filter.keep(item))
                output.add(item);

        return output;
    }

    interface Filter<T> {
        boolean keep(T element);
    }
}

Given extension methods, a coder can write:

// static imports
Collection<String> names = asList("Bob", "Nancy", "Ted");
List<String> bobNames = names.filterInto(
        new ArrayList<>(), // new diamond syntax
        #(String name) "Bob".equals(name)); // new closure syntax

And some magic means will find Filtering#filterInto(Collection, Collection, Filtering.Filter) and transform the instance method call on Collection into a static method call on Filtering. Rules for finding Filterable vary. (Did you read Alex Miller's link?)

Here is an alternative.

Delegation

I am a fan of delegates and have writen about them often: I'd like them in Java. With delegates, the magic for finding #filterInto is less magical, and more under the control of the coder, but just as clean to use:

public final class FilteringCollection<T>
        implements Collection<T>, Filtering {
    // Some literate programming sugar for the static importers
    public static <T> FilteringCollection<T> filtering(
            Collection<T> input) {
        return new FilteringCollection(input);
    }

    public FilteringCollection(final Collection<T> input) {
        this = input; // the delegation proposal
    }

    public <C extends Collection<T>> C filterInto(
            C output, Filter<T> filter) {
        for (T item : this)
            if (filter.keep(item))
                output.add(item);

        return output;
    }
}

Usage now looks like:

// static imports
FilteringCollection<String> names = filtering(asList("Bob", "Nancy", "Ted"));
List<String> bobNames = names.filterInto(
        new ArrayList<>(), // new diamond syntax
        #(String name) "Bob".equals(name)); // new closure syntax

What's the difference?

Key here is that for the coder the only difference is delegation uses a static factory method to wrap input. This is not a drawback: it is an advantage. Less magic makes Java programs easier to maintain. There is no loss here in power.

Why bother with the delegation proposal?

Would you like to write the boilerplate forwarding methods of Collection? I wouldn't! It gets even worse as you move down the inheritance tree for Collection.

Postscript

How would you move down Collection's inheritance tree any how?

Beyond any current proposals, some javac author could implement type erasure for base classes (very carefully) in context of delegation:

public final class FilteringCollection<T, D extends Collection<T>>
        implements D, Filtering {
    // Only factory/constructor changes
    public static <T, D extends Collection<T>> FilteringCollection<T>
            filtering(D input) {
        return new FilteringCollection(input);
    }

    public FilteringCollection(D input) {
        this = input;
    }
}

Because the coder need not implement the dozens of forwarding methods, neither does he need to know what they are! The compiler sets the type of D to the precise collection used in the factory/constructor, and the resulting object provides all public methods.

But this is well beyond the scope of delegation. Go code Scala, or something.

UPDATE: Food for thought on extension methods from Rémi Forax.

UPDATE #2: This just gets more interesting: in Extension methods vs. method currying, Stefan Schulz discusses the alternative of currying.

Wednesday, November 18, 2009

A future for Java after all?

One of my favorite bloggers, Alex Miller, opens today with Apparently Mark Reinhold announced that closures would be added to JDK 7 at Devoxx today.

When I realized JDK7 would have no closures, I mentally wrote Java off as a language destined to be COBOL or FORTRAN or C: important in a practical way, but not to be where my heart was. (I'm looking around; Scala is likely my next language of choice.)

And, lo! Closure—in Java! Java may remain after all the language I prefer most. What a surprising turn.

UPDATE: Stephen Colebourne posts more details.

Thursday, November 12, 2009

Frankie says, don't do it (but does anyway)

Aleksander Kmetec explains Acme::Dont implemented in Scala.

Is it scarier that I can follow along, or that I recognize the Perl don't pragma? (Naturally Damian Conway is to blame.) Funny I ran across this post while reading Bytecodes meet Combinator: invokedynamic on the JVM.

Wednesday, November 11, 2009

How are your algorithms?

A fabulous post by Peteris Krumins summarizing MIT's Introduction to Algorithms lectures. It's like having a little Knuth in your browser.

A new programming language: Go

Time to brush up my resume and add a new programming language: Go, say 3 years experience?

I chuckle as I type this, but I have interviewed candidates for my present employer with an equally tenuous grasp on Java at variance with their resumes.

Thursday, October 15, 2009

More mana from the Czech lands: IntelliJ IDEA open-sourced

Take THAT, Eclipse!

UPDATE: This announcement is so popular, the JetBrains site is down. Never seen that before.

Tuesday, October 06, 2009

Surprisingly, there really is more to life than programming

Since I started this blog I have stuck consistently to programming topics. But I feel like posting a touch more broadly. Here are some of my favorite links:

And when I'm not browsing the Internet, I write classical music, cook freestyle, and thoroughly enjoy Rebecca, Greg and Ben.

Friday, September 25, 2009

Keeping a current timestamp in a Java concurrent map

Tricker than I like: In Java, how do you keep a map with the values being the "most recent timestamp" for the key? How do you do this for a concurrent map with multiple threads updating?

boolean isLatest(final K key, final long newTimestamp,
        final ConcurrentMap<K, Long> map) {
    Long oldTimestamp = map.putIfAbsent(key, newTimestamp);

    // If we are first, there is no previous to compare
    // with
    if (null == oldTimestamp)
        return true;

    // Make sure we are still the most recent
    while (newTimestamp > oldTimestamp) {
        if (map.replace(key, oldTimestamp, newTimestamp))
            // No other thread has updated, we are most
            // recent
            return true;

        // Another thread got here first, recheck
        oldTimestamp = map.get(key);
    }

    // Another thread put in a newer update, we are not
    // most recent
    return false;
}

As with all multi-threaded coding, bugs are easy to make and hard to spot. If I have made one, please let me know!

UPDATE: Fixed a typo. Thanks, David!

Friday, September 11, 2009

Sunday, September 06, 2009

Fast reflection, a cool post

"Coding Masters" (sorry, I didn't find his name) posts an interesting dissection of reflection and tunes until it is as quick as normal code. This is one for my toolbox.

Thursday, September 03, 2009

More on favorite idioms

lambdaj does a much better job than I did:

List<Integer> biggerThan3 = filter(greaterThan(3), asList(1, 2, 3, 4, 5));

Qi4j 1.0-RC1

Qi4j realizes much of the promise of annotations. Mixins and aspects without code or bytecode generation, what's not to love?

Monday, August 31, 2009

Design, Don't do it

Are you designing a thread-safe front to a single-threaded resource? Relax.

The wrong way

Write layers and layers of complexly interacting abstraction over an object pool, letting the object pool (hopefully) protect you from threading concerns.

The right way

Use the JDK:

public class FooService {
    private final UnsafeResource resource;
    private final ExecutorService service;

    public FooService(final UnsafeResource resource) {
        this.resource = resource;
        service = createPoolFor(resource);
    }

    public <T, E extends Exception> Future<T> submit(
            final Work<T, E> work) {
        return service.submit(new Callable<T>() {
            T call() throws E {
                return work.use(resource);
            }
        });
    }

    public interface Work<T, E extends Exception> {
        T use(final UnsafeResource resource) throws E;
    }

    // Good place for an extension point depending on your needs
    private static ExecutorService createPoolFor(final UnsafeResource resource) {
        return newSingleThreadExecutor(new ThreadFactory() {
            public Thread newThread(final Runnable r) {
                return new Thread(r,
                        FooService.class.getSimpleName() + ": " + resource);
            }
        });
    }
}

Wednesday, August 26, 2009

Comments on Hipp's A Lesson In Low-Defect Software

Thanks to Alecco Locco for useful comments on Hipp's A Lesson In Low-Defect Software. the full title:

A Lesson In Low-Defect Software
-or-
A Journey From A Quick Hack
To A High-Reliability Database Engine

and how you can use the same techniques to reduce
the number of bugs in your own software projects

Those comments got me to read the paper.

Tuesday, August 25, 2009

A favorite functional idiom in Java

Ok, two favorite functional idioms in Java:

public abstract class Option<T>
        extends Cursorable<T> {
    public static <T> Option<T> some(final T value) {
        return new Option<T>() {
            @Override
            public int size() {
                return 1;
            }

            @Override
            public T get() {
                return value;
            }
        };
    }

    public static <T> Option<T> none() {
        return new Option<T>() {
            @Override
            public int size() {
                return 0;
            }

            @Override
            public T get() {
                throw new IllegalStateException();
            }
        };
    }

    public abstract int size();

    public abstract T get();

    public final boolean isEmpty() {
        return 0 == size();
    }

    @Override
    public final Iterator<T> iterator() {
        return new Iterator<T>() {
            private boolean empty = isEmpty();

            @Override
            public boolean hasNext() {
                return !empty;
            }

            @Override
            public T next() {
                if (empty)
                    throw new NoSuchElementException();
                empty = true;
                return get();
            }

            @Override
            public void remove() {
                throw new UnsupportedOperationException();
            }
        };
    }
}

public abstract class Cursorable<T>
        implements Iterable<T> {
    public static <T> Cursorable<T> over(
            final Iterable<T> it) {
        return new Cursorable<T>() {
            @Override
            public Iterator<T> iterator() {
                return it.iterator();
            }
        };
    }

    public final Cursorable<T> select(
            final Select<T> select) {
        return new Cursorable<T>() {
            @Override
            public Iterator<T> iterator() {
                return new Iterator<T>() {
                    private final Iterator<T> it
                            = Cursorable.this.iterator();

                    private Option<T> current = none();

                    @Override
                    public boolean hasNext() {
                        while (it.hasNext()) {
                            final T next = it.next();
                            if (!select.accept(next))
                                continue;
                            current = some(next);
                            return true;
                        }
                        current = none();
                        return false;
                    }

                    @Override
                    public T next() {
                        if (current.isEmpty())
                            throw new NoSuchElementException();
                        return current.get();
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }

    public final <U> Cursorable<U> project(
            final Project<T, U> project) {
        return new Cursorable<U>() {
            @Override
            public Iterator<U> iterator() {
                return new Iterator<U>() {
                    private final Iterator<T> it
                            = Cursorable.this.iterator();

                    @Override
                    public boolean hasNext() {
                        return it.hasNext();
                    }

                    @Override
                    public U next() {
                        return project.on(it.next());
                    }

                    @Override
                    public void remove() {
                        throw new UnsupportedOperationException();
                    }
                };
            }
        };
    }

    public interface Select<T> {
        boolean accept(final T input);
    }

    public interface Project<T, U> {
        U on(final T input);
    }
}

And a demo:

public class SelectAndProjectMain {
    public static void main(final String... args) {
        for (final Integer number : over(asList(1, 2, 3, 4))
                .select(new Cursorable.Select() {
                    @Override
                    public boolean accept(final Integer input) {
                        return 0 == input % 2;
                    }
                })) {
            System.out.println("Even: " + number);
        }

        for (final String number : over(asList(1, 2, 3, 4))
                .project(new Cursorable.Project() {
                    @Override
                    public String on(final Integer input) {
                        return Integer.toBinaryString(input);
                    }
                })) {
            System.out.println("Binary: " + number);
        }
    }
}

Produces:

Even: 2
Even: 4
Binary: 1
Binary: 10
Binary: 11
Binary: 100

Although I am afraid to add this to my project at work. I worry for the maintainer after me.

UPDATE: A coworker called me to the mat for extreme terseness. Demonstrating a more fluent style, I refactored the demo code:

public class SelectAndProjectMain {
    public static void main(final String... args) {
        final List<Integer> numbers = asList(1, 2, 3, 4);

        for (final Integer number : over(numbers).select(evens()))
            System.out.println("Even: " + number);

        for (final String number : over(numbers).project(binaries()))
            System.out.println("Binary: " + number);
    }

    static class Evens
            implements Cursorable.Select<Integer> {
        static Evens evens() {
            return new Evens();
        }

        @Override
        public boolean accept(final Integer input) {
            return 0 == input % 2;
        }
    }

    static class Binaries
            implements Cursorable.Project<Integer, String> {
        static Binaries binaries() {
            return new Binaries();
        }

        @Override
        public String on(final Integer input) {
            return Integer.toBinaryString(input);
        }
    }
}

UPDATE: And lastly, more on Option from the land of Scala.

Monday, July 27, 2009

Where is a tool for parsing date ranges in Java?

I'd like to turn this 20090701,20090703-20090710 into a list of dates in Java. It's not hard to do, but I hate writing code like this when I am just certain there's already a library for this.

Except I can't find one.

Any pointers for an open-source library to parse date ranges in Java would be much appreciated. I'm embarrassed to reinvent this whell.

Monday, July 20, 2009

Shell gotcha: when comments execute

The problem: a colleague has a script which dies early, something like this (with the -x flag):

+ [ 2 -eq 2 ]
+ break
+ exit

The corresponding shell (KSH, but same results in BASH):

if [ $cond1 -eq $cond2 ]
then
   break
fi

# Lots of commented out code

more commands ...

The curiosity: why the early exit? The logic does not have an exit anywhere nearby; the commands following do not call exit.

Follow Sherlock Holmes' dictum, How often have I said to you that when you have eliminated the impossible, whatever remains, however improbable, must be the truth? (The Sign of the Four) The only thing left is the commented out code.

Sure enough:

# Blah, blah
# Something with $(hidden command) buried inside
# More blahbage

I had completely forgotten that the shell expands variables even inside comments! In this case, the expanded $(hidden command) blew up and caused the shell to exit prematurely. Caveat plicator.

Tuesday, June 23, 2009

A pleasant read: call/cc

Here's a pretty good explanation of call/cc.

Dataflow concurrency for Java

I ran across this interesting Scala class by Vaclav Pech which makes the data concurrent rather than the code (if I understood the author correctly). The ~ (extraction) and << (insertion) operators looked nifty.

Looking to do the same in Java, I see four key requirements:

  1. Insertion can happen only once.
  2. Extraction is idempotent (infinitely repeatable, non-modifying).
  3. Extraction blocks until insertion has completed.
  4. Insertion and extraction are both atomic.

With these in mind, I write this:

public class DataFlowReference<T> {
    private final ReentrantLock lock = new ReentrantLock();
    private final Condition condition = lock.newCondition();
    private volatile T item;
    private volatile boolean set = false;
    private volatile boolean called = false;

    public T get()
            throws InterruptedException {
        lock.lockInterruptibly();
        try {
            while (true) {
                if (set)
                    return item;

                if (!called) {
                    called = true;
                    onFirstGet();
                    continue;
                }

                condition.await();
            }
        } finally {
            lock.unlock();
        }
    }

    public void setOnce(final T value) {
        lock.lock();
        try {
            if (set)
                return;

            set = true;
            item = value;

            condition.signalAll();
        } finally {
            lock.unlock();
        }
    }

    protected void onFirstGet() {
    }

    // Object

    @Override
    public boolean equals(final Object o) {
        if (this == o)
            return true;
        if (o == null || getClass() != o.getClass())
            return false;

        final DataFlowReference that = (DataFlowReference) o;

        return set && item.equals(that.item);
    }

    @Override
    public int hashCode() {
        return set ? item.hashCode() : super.hashCode();
    }

    @Override
    public String toString() {
        return "(" + set + ':' + item + ')';
    }
}

Use of DataFlowReference follows the examples from Vaclav's page: declare dataflow references, create threads whose runables use setOnce() and get(), invoke them all together.

onFirstGet() supports "just in time" supply of item and would call setOnce(T) with a fresh value.

UPDATE: The original version of this class had a horrible, obvious race condition. Caveat plicator.

Thursday, June 11, 2009

Deep understanding of the JVM

Gary Benson posts a deep understanding of the JVM from the team at RedHat porting it to non-x86 architectures.

HTTPS, blow by blow

Jeff Moser presents a blow-by-blow account of HTTPS. I knew most of this stuff in a hand-waving chalkboard way. Now I feel less ignorant about what actually happens when I connect to a secure web site.