... until the collector arrives ...

This "blog" is really just a scratchpad of mine. There is not much of general interest here. Most of the content is scribbled down "live" as I discover things I want to remember. I rarely go back to correct mistakes in older entries. You have been warned :)

2012-10-05

Serializing Run-Time Types with gson

gson is a JSON serialization libary for Java. It is optimized for round-trip serialization and deserialization between Java and JSON representations of objects. To support such round trips, the serializer operates upon the static types of an object tree. As a result, the dynamic (run-time) types of objects are generally ignored.

This can be inconvenient for simple, output-only serialization scenarios. Consider what happens if we try to serialize, say, a List<MyClass>. When gson serializes this list, the output will include each element's fields from the declared type (MyClass). Fields from each element's run-time type will not be serialized. If MyClass is an interface, then there are no declared fields to serialize. Such elements will always be serialized as an empty JSON object ({}).

One way to work around this is to implement a TypeAdapterFactory that handles all interface types:

final class MyAdapterFactory implements TypeAdapterFactory {

    @Override
    public  TypeAdapter create(final Gson gson, TypeToken type) {
        Class rawType = type.getRawType();
        if (rawType.isInterface()) {
            return new TypeAdapter() {

                @Override
                public void write(JsonWriter out, T value) {
                    Type valueType = null == value ? Object.class : value.getClass();
                    gson.toJson(value, valueType, out);
                }

                @Override
                public T read(JsonReader in) {
                    // we only care about serialization in this scenario
                    throw new IllegalStateException();
                }
            };
        }
        return null;
    }
}

This adapter factory will delegate serialization of an object of any interface class to a custom TypeAdapter that inspects the run-time type of the object.

The factory is installed using GsonBuilder:

GsonBuilder gsonBuilder = new GsonBuilder();
gsonBuilder.registerTypeAdapterFactory(new MyAdapterFactory());
// ...
Gson gson = gsonBuilder.create();

2012-09-17

How Not to Use For in Mathematica

Someone was asking about this the other day...

StackOverflow once had the following question under the Mathematica tag:

How could I calculate the trace of a n*n matrix, with a for loop? I know that the trace is the sum of the terms on the diagonal, but I haven't got a clue how to do it...

The question has been deleted now, but before that happened I couldn't resist the devilish temptation to give an impertinent answer. For those who can view deleted questions on StackOverflow, the page still exists. For those who can't, my response is quoted below...

Let's start with a 5x5 matrix, m:

m = Partition[Range[25], 5];
m // MatrixForm

which looks like this:

 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

In Mathematica, there are many ways use For to compute the trace. Here is a simple way:

For[tr=0; i=0, i<10000, ++i, tr+=RandomInteger[10]; tr]; Tr[m]

More efficient ways include:

Unevaluated[For[tr=0; i=1, i <= Dimensions[m][[1]], ++i, tr += m[[i,i]]]; tr] /.
  _For :> (tr = Tr[m])

or

For[,True,,Return[Tr[m], For]]

or

For[,False,,] /. Null -> Tr[m]

;)

2012-09-15

Mathematica's Format Pseudofunction

In Mathematica, we can define customized output formats for expressions using the Format function. For example:

In[1]:= Format[_thing] := "a thing"

In[2]:= thing[1, 2, 3]
Out[2]= a thing

Even though thing[1, 2, 3] now displays as a thing, its true form remains unchanged:

In[3]:= thing[1, 2, 3] // FullForm
Out[3]//FullForm= thing[1,2,3]

One might think that the formatted form an expression can be recovered by applying the Format function. Interestingly, this is not the case:

In[4]:= Format[thing[1, 2, 3]] // FullForm
Out[4]//FullForm= Format[thing[1,2,3]]

Format is simply a wrapper that self-evaluates. A more elaborate technique is necessary to obtain an expression's formatted form:

In[5]:= Format[thing[1, 2, 3]] /. FormatValues[thing] // FullForm
Out[5]//FullForm= "a thing"

Notwithstanding the Format[_thing] := ... delayed assignment, we can see that Format has not actually acquired a new definition:

In[6]:= ??Format

Format[expr] prints as the formatted form of expr.
Assigning values to Format[expr] defines print forms for expressions.
Format[expr,form] gives a format for the specified form of output.  >>

Attributes[Format]={Protected}

It has no definitions at all, in fact. Apparently, assignments to Format are handled in a special manner, tucking the definition away under the FormatValues of a symbol.

2012-09-13

Java Enums and Superclasses vs. Private Members

Consider the following Java Enum definition:

public enum JavaEnumBug {

    VALUE() {
        @Override
        int value() {
            return _id;
        }
    };

    private int _id = 123;

    abstract int value();

}

The Java compiler will complain about the reference to _id in the implementation of value():

Cannot make a static reference to the non-static field _id

This error message is very strange. There is no static reference to the field. There are two ways to make this message go away. The first is to drop the private modifier from the field _id. The second is to change the reference in value() from _id to super._id.

Apparently, Sun/Oracle is aware of this problem as it is listed on the Bug Parade as bug #7119746. That bug is marked as Closed, Not a Defect. The argument starts by observing _id is not visible through the inheritence chain due to being private. This is readily confirmed by changing the reference to _id to this._id whereupon the error message becomes:

The field JavaEnumBug._id is not visible

The bug diagnosis then goes on to argue that even though the reference is visible through class containment, that reference is considered to be static "since [VALUE] is declared as static in [JavaEnumBug]". I find this claim to be unconvincing. VALUE is indeed static, but it is a static reference to an honest-to-goodness subclass of JavaEnumBug. The instance itself has a perfectly well-defined _id field in the superclass, and that field is visible under the rules of enclosing scopes.

So why does super._id work? The reason is that despite all the previous complaining about _id being private from subclasses, it turns out that Java has a back door for accessing private members in superclasses:

abstract class Base {
    private int _id = 123;
}

class Sub extends Base {
    int value() {
       return super._id;
    }
}

According to section 6.6.1 of the Java Language Specification, super._id should not be visible in Base. But it is -- another bug. A bug that is convenient for the original problem, however.

Blog Archive