Monday, January 25, 2010

The Rosetta stone, what a paper

I am really enjoying this paper by John Baez (yes, that John Baez) and Mike Stay. My background is in physics (and music) and the crossing of physics, topology, logic and computation is too much to keep to myself. I hope you enjoy it, too.

Friday, January 15, 2010

Update on Google Phone saga

An update from Google on my continuing Google phone quest:

XXX YYY has posted an answer to the question "Ineligible to purchase phone: T-mobile contract changed too recently": Howdy binkley, We've listened very carefully to everyone's feedback and concerns regarding the upgrade issue and are working with our partners to improve the situation for existing customers. In all instances, Google's web store only passes your information along. The carrier then determines eligibility for a full or partial upgrade, as your service contract is with the carrier. You must be fully upgrade eligible in order to get this device at a discount. Stay tuned for more updates about upgrading! In the meantime, you can use the sticky post at the top of this forum to get the latest information and share any more thoughts you may have: http://www.google.com/support/forum/p/Google+Mobile/thread?tid=3c0fd3870ec370a8&#all Cheers, -XXX

UPDATE: I've received a variant of this text in a second message from another Google employee. It's good they are trying to deal with this mess. I should not be surprised at the form letter template employees work from.

Wednesday, January 13, 2010

Rusty Java: in-place updating a collection while iterating

Some areas of my Java grow rusty with time, as with all things. This code looks nice, but completely fails:

public static void main(final String... args) {
    final Set<Foo> foos = new HashSet<Foo>(asList(FOO));

    for (final Foo foo : foos)
        foos.addAll(foo.more);

    System.out.println("foos = " + new HashSet<Foo>(foos));
}

enum Foo {
    QUUX,
    BAZ(QUUX),
    BAR(BAZ),
    FOO(BAR, BAZ);

    private final Set<Foo> more;

    Foo(final Foo... more) {
        this.more = new HashSet<Foo>(asList(more));
    }
}

The goal is to collect all transitive dependencies. What is wrong?

The iterator is not a "current picture" of the collection; it is a snapshot. This code prints only foos = [FOO], updates vanish. Changing to ArrayList only worsens things with the dreaded ConcurrentModificationException.

Correct is to use a list iterator and be careful with cursor position:

public static void main(final String... args) {
    final List<Foo> foos = new ArrayList<Foo>(asList(FOO));
    final ListIterator<Foo> lit = foos.listIterator();

    while (lit.hasNext())
        for (final Foo foo : lit.next().more) {
            lit.add(foo);
            lit.previous();
        }

    System.out.println("foos = " + new HashSet<Foo>(foos));
}

This prints foos = [QUUX, BAZ, BAR, FOO] with the happy side effect of depth-first ordering.

Tuesday, January 12, 2010

Class token nuisance

Fabrizio Giudici posts a nice description of type-safe map keys, a clever way to simplify life for an API user.

It exposes one of the nuisances of class tokens:

@Nonnull
public <T> T get (final @Nonnull Key<T> key)
  throws NotFoundException
  {
    return NotFoundException.throwWhenNull(
        (T)itemMap.get(key), "Not found: " + key);
  }

(Kudos to him for using JSR-305 annotations.)

See the cast (T)? That generates a compile-time warning (link just one of many complaints around this). The correct way to get ride of this warning is to use a class token:

@Nonnull
public <T> T get (final @Nonnull Key<T> key)
  throws NotFoundException
  {
    return NotFoundException.throwWhenNull(
        key.cast(itemMap.get(key)), "Not found: " + key);
  }

Where the Key<T> type is redefined:

@Immutable
public final static class Key<T>
    implements Comparable<Key<T>>
  {
    @Nonnull
    private final String name;
    @Nonnull
    private final Class<T> type;

    protected Key (final @Nonnull String name, final @Nonnull Class<T> type)
      {
        this.name = name;
        this.type = type;
      }

    public T cast(final Object that)
      {
        return type.cast(that);
      }

    @Override
    public int compareTo (final @Nonnull Key<T> other) { ... }

    @Override
    public boolean equals (final @CheckForNull Object object) { ... }

    @Override
    public int hashCode() { ... }
  }

What a nuisance.

Saturday, January 09, 2010

ANI, not your usual language

This is interesting: anic, a compiler for the language ANI. It is really the language which is the interesting part, of course.

ANI is automatically parallelizing, and very non-inperative. In its own buzzwords: experimental, high-performance, statically-safe, fully implicitly parallel, object-oriented, general-purpose dataflow programming language.

Take a breath now.

Thursday, January 07, 2010

Bad fanboi - no gphone

Continuing my Nexus One story...

So far I cannot get a Google phone. At first the site did not like my T-mobile family plan. So I went from $60/mo. to $130/mo. to break up our plan into a his/hers data/voice plan.

Now Google still does not like my T-mobile plan:

You are not eligible for an upgrade at this time.
You are not eligible because your current contract was initiated too recently.

No love from Google.

IntelliJ and Scala

Thomas Jung writes about using IntelliJ and Scala and is very enthusiastic, as he should be: IntelliJ IDEA remains the best IDE.

I've long been pessimistic of IDEA retaining this position in the face of thousands of Eclipse code monkeys eventually typing the works of Knuth, but JetBrains has admirably kept up.

The struggle between the cathedral and the bazaar continues.

UPDATE: When it rains, it pours.

Wednesday, January 06, 2010

Those lucky web developers

Those lucky web developers have it so good. Automated functional testing for enterprise integration middleware is a complete pain. You try simulating a dozen distinct systems. Helps keep me warm at night just thinking about it.

Actor thinking from Kresten Krab Thorup

Kresten Krab Thorup posts a long think on objects and processes, full of great references, which I enjoy. Maybe you will, too.

Tuesday, January 05, 2010

isolate: a new tool for my toolbox

isolate is the newest tool in my toolbox. Paranoids are sometimes correct. (Found thanks to LWN.net.)

Nexus One URL almost there

What is the typical error page for a bad link into Google, say, http://www.google.com/bobsyerunkel? But for http://www.google.com/phone I get a prosaic default 404 page, perhaps in preparation for something more interesting later today.

UPDATE: Not happy! http://www.google.com/phone works now, but T-mobile is disabled as a choice. Only the unlocked phone is offered:

We're unable to sell T-Mobile service plans at this time, but you can still buy the unlocked phone.

This was my Christmas present from my wife!

UPDATE #2: I was premature. The T-mobile option now works, very nicely, too. However, it checked my existing T-mobile phone number and said family plans were not eligible. Time to confer with the wife.

UPDATE #3: Spent 20 minutes on line with T-mobile. She was courteous and did her best, but management left them unprepared for Nexus One release beyond a cursory memo. Several checks with different supervisors, still no answer on how to split family plan, add Nexus One plan for myself. There's always tomorrow.

Monday, January 04, 2010

Revisiting an old post: mixing OSGi, Scala, et al with pax

I overlooked the coolness of Brian Murphy's post the first time I ran across it: OSGi With Scala, Java, Groovy, Maven and PAX. As I am playing with OSGi, guice and peaberry, I ran across his instructions and was struck by how straight-forward pax makes everything.

My contribution to the conversation, bootstrapping a peaberry project:

$ pax-add-repository -i google-maven-repository \
    -u http://google-maven-repository.googlecode.com/svn/repository
$ pax-add-repository -i ops4j.releases \
    -u http://repository.ops4j.org/maven2
$ pax-import-bundle -g com.google.inject -a guice -v 2.0
$ pax-import-bundle -g org.ops4j -a peaberry -v 1.1.1
$ pax-create-module -a wrappers
$ cd wrappers
$ pax-wrap-jar -g aopalliance -a aopalliance -v 1.0
$ cd ..
$ pax-create-bundle -p $your_groupId -n $your_artifactId

This presumes a simple project with only one module ("$your_artifactId").

Top notch post on JDK 1.6 update 14 optimizations

A really good post on JDK 1.6 update 14 optimizations: lock coarsening, biased locking and escape analysis. Found via the Java Specialist newletter.

Wednesday, December 30, 2009

Nexus One: Buy from Google, not T-mobile

I just spoke with my friendly T-Mobile customer care specialist. She was direct and helpful. Point blank I asked to pre-order a Nexus One and sign up for the matching phone plan. As expected, she could not help me with that. But she did tell me some interesting tidbits:

  • T-mobile considers it an HTC phone, not a Google one
  • T-mobile has not yet given customer service details on the phone, but my specialist did know about it
  • T-mobile will not be selling the phone directly; she said I needed to order it from Google, not T-mobile

Anticipation is a great selling device.

Android load webby

My first Android project, AndroidLoad, is very simple. It reads /proc/loadavg every second and and updates a table with the data.

Achieving this much in a single day of browsing and code noodling, I hope to make something more interesting with it soon. So far, Android+IDEA has been a real pleasure to develop with, and I expect the IDE integration to continue improving.

Monday, December 28, 2009

Chocolate sausages: not programming

My 12-year old son sent me a delightful email:

Today, grandma and I made some chocolate sausages and they turned
out great. Here is the recipe so you and Rebecca can replicate it,
but do not attempt without me. Ingredients: 200 grams of good butter 3 tablespoons of sugar 3 tablespoons of water 2 tablespoons of cocoa 50 grams of 90% and up dark chocolate 300 grams tea biscuits 1 egg 5 tablespoons of walnuts chopped wax paper Instructions: Melt butter, cocoa, chocolate, butter, water, and sugar over low heat. Bring to a boil. Turn off heat. Let it sit for 2 minutes. Remove excess water. Mix in eggs, biscuits, and walnuts. Place 2-3 tablespoons on sheet of wax paper and roll up. Repeat until there is no more filling. Freeze for minimum of 2 hours. Enjoy!

This is my one non-serious post for the year. Follow my son's advice: enjoy!

Sunday, December 27, 2009

All I want for Christmas is a Google Phone

I made a simple Christmas wish list for my wife:

  1. A Google phone

Yep, that's it, if I can bear the delayed gratification. And then there are the naysayers, ye of little faith.

Would I be a Android developer with a Nexus One? In a heartbeat—time to get started! I've got faith.

UPDATE: Rumor has it, Nexus One by invitation only. Will code for invite!

Saturday, December 26, 2009

New Ioke release

Ola Bini announced a new release of Ioke. Why is Ioke interesting? From the home page:

 
Ioke = LanguageExperiment with(
  goal: :expressiveness, 
  data: as(code), 
  code: as(data), 
  features: [
    :dynamic, 
    :object_oriented, 
    :prototype_based, 
    :homoiconic, 
    :macros 
  ], 
  runtimes: (JVM, CLR), 
  inspirations: set(Io, Smalltalk, Ruby, Lisp)
)
 
hello = method(name, 
  "hello, #{name}!" println)
 
Ioke inspirations select(
  features include?(:object_oriented)
) each(x, hello(x name))

Saturday, December 19, 2009

Code repository

I used Google Code to setup a Subversion repository for this blog under binkley. So far there are only two items: Soapy and MagicBus. Feedback encouraged.

Thursday, December 17, 2009

Vacation: BlockingIterable

I love vacation: a chance to stretch my coding fingers free of work! Here is a code snack I thought of while daydreaming today—enjoy!

public final class BlockingIterable {
    public static <E> Until<E> over(final BlockingQueue<E> queue) {
        return new Until<E>(queue);
    }

    public static class Until<E> {
        private final BlockingQueue<E> queue;

        private Until(final BlockingQueue<E> queue) {
            this.queue = queue;
        }

        public Iterable<E> until(final E poison) {
            return new Iterable<E>() {
                @Override
                public Iterator<E> iterator() {
                    return new Iterator<E>() {
                        private E next = poison;

                        @Override
                        public boolean hasNext() {
                            try {
                                return poison != (next = queue.take());
                            } catch (final InterruptedException e) {
                                currentThread().interrupt();
                                next = poison;
                                return false;
                            }
                        }

                        @Override
                        public E next() {
                            if (poison == next)
                                throw new NoSuchElementException();
                            return next;
                        }

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

Monday, December 14, 2009

Gmail smarter than I am

I was typing a personal mail to family members and using Gmail's address completion feature to just type a few characters for each recipient when I got to filling in the message body. I looked up and saw a warning about the To: list. It asked if I really meant to mail PQT, perhaps I really meant PQR? And it was right.

Gmail recognized that I mispicked one of the recipients while using completion, and that I would prefer a relation rather than a friend for this mail. Gmail is smarter than I am.

Thursday, December 10, 2009

How to release software

The wrong way

  • Have no master plan
  • Practise nothing ahead of release day
  • Prepare only on release day
  • Build release packages on release day
  • Have dissimilar production and test environments
  • Hand edit configuration during release
  • Keep no backups of previously working configuration
  • Use trial-and-error to fix configuration

The right way

Do the opposite of everything done the wrong way. Wasn't that simple?

Some elaboration

As much as possible, clone the production environment to your test environment. Any number of weird, unexpected, troubling problems will crop up. Fix them all. Do not release if your test environment is not pristine.

Make complete release packages as early as you can, and release them to the test environment just as you would to production. Do not release if you cannot deploy smoothly.

Keep the entire test environment under release control: everything including binaries, symlinks, logs. Do not release if there are uncommitted changes; do not release if you do not understand the changes since last release.

Above all, have a plan! Discuss it with your team, assign roles and check that everyone understands what they do. Practice the release; practice rollback should something break. Obey the Scout motto: Be prepared.

Postscript

What is the penalty for the wrong way? Eight hours spent with your cell phone glued to your ear during vacation while you fix a slow-moving train wreck of a release. Your family will thank you for the right way.

UPDATE:

And in the comments:

  • Release very seldom with a big bang approach

This is very apropos. Management prefers a few large releases to smaller, more frequent releases. My opinion is that large releases look better to upper management (demonstrates you can deliver large widgets) even though it hurts in cost and quality.

Wednesday, December 02, 2009

Epic fail with agile, or winning the battle but losing the war

Dave Nicolette posts one of the most depressing but realistic outcomes of successful agile engagements: retrenchment by anti-agile forces.

I utterly hate the case studies, but I hate them precisely because they are real.