Started playing with Go this weekend, and I'm already sure that this language is going to become a keystone in my work. What I like: strong typing with type inference, built-in concurrency, garbage-collection, native compilation across lots of machines, and it's fast. And most of all, it's a very straight-forward, practical language. Oh, and the ability to return multiple values from a function is great. And switch statements that don't automatically fall through. Things I'll enjoy playing with: slices over arrays, defer/panic/recover, channels/select, and the type switch construction (which I'm really enjoying in XQuery/MarkLogic). While I'm looking forward to it, it will be a bit odd for me to get serious with a non-object-oriented language again. It's been years since I've done anything significant with C. But the interface mechanism should help ease the transition.

Now for my first project. Maybe I'll run through the Matasano Crypto Challenges. That's something I've been meaning to do but never seem to make the time.

I had code that I wanted to treat as a library and import it into my Swift Playground. It took several hours of searching and experimenting until I came up with a recipe that worked. There may be easier, better ways to do this, but this is what worked for me on Xcode 6.1:

Create a workspace.

Add a new Cocoa Framework project to the workspace.

Add a Swift file to the framework project.

Remove Foundation.h file from the framework.

Build the framework.

Add a playground to the project (not the workspace).

In the playground, add code to import the framework.

Now you can use your imported framework/library in the playground. Just add the library code to the framework (using the file in step 3 and adding other files as needed) and build the project. You can then access the public members in the framework.

This example worked as described with jdk1.8.0_05. With jdk1.8.0_45, however, the compiler gives the "reference to go is ambiguous" error for a.go(3,i). I'll have to do some research to see why the behavior changed.

Most Java programmers run afoul of the complex invocation and overloading
rules fairly early in their careers. Example 6 (GitHub) illustrates
the often surprising behaviors that emerge from overloading--especially when
combined with implicit conversions and autoboxing.

It might not be apparent from the code, but both versions of the method go
in class A are applicable to both method calls. That is, if either of the
go methods did not exist--go was not overloaded--both method calls would
still execute without error.

To see this for yourself, change the name of the go method that returns A1
to something like noGo. Recompile and run. Both a.go(3, i) and a.go(i, 3)
will return A2. Do the same to the go that returns A2, and you'll see that
both calls will return A1.

Since both methods defined in A are applicable to to both method invocations,
why does overloading cause different behavior? Why is
go(Integer i1, Integer i2) more applicable to a.go(3, i) while
go(Number i1, double i2) is more applicable to a.go(i, 3)? All it takes is
boxing 3 in both cases to return A1.

One reason for the observed behavior is that Java's algorithm for matching
method invocations to method definitions proceeds in three phases. If matches
are found in an early phase, the search concludes with that phase and does not
continue on to the later phases. See Section 15.12.2 in JLS8 for
the details.

In this case, only the first two phases are relevant (the third phase applies
to varagrs). The first phase uses what Java calls strict invocation. During
strict invocation, Java will widen a reference but it will not autobox
primitive types. The second phase uses loose invocation and allows boxing
conversions. JLS8 5.3 discusses these rules.

With that background in mind, let's look at the results of the program.

Item 1

The method invocation a.go(3, i) will not match either method definition in
A under strict invocation. The 3 must be converted to a reference type in
order for it to match either definition and such conversions are not permitted
in phase 1.

When Java moves on to phase 2, it notes that it can easily box 3 to an
Integer. This makes go(Integer i1, Integer i2) a match. Voila!

Wait, not so fast: go(Number i1, double i2) is also a match in phase 2.
The first argument in the method invocation, 3, needs to be boxed and widened
to become a Number, and the second argument needs to be unboxed and widened to
become a double. These operations are all allowed in phase 2.

Both methods are applicable to the invocation. What is Java to do?

Once Java has determined which methods are applicable, it then selects the
most specific of those methods. The rules for this selection are a bit hairy.
Read JLS8 15.12.2.5 for the specifics (I couldn't resist). This is
an area of the JLS on which I need to spend a bit more time, but here's my
understanding of what is going on.

To determine the most specific method, Java compares the types of each
method's parameters. When comparing two methods the most specific method is
the method in which each parameter is a subtype of the corresponding parameter
of the other method. The rules defining a subtype are covered in JLS8
4.10.

To be a little formal: If m1 is a method with parameters
T1, T2, T3,..., Tn and m2 is a method with parameters
S1, S2, S3,..., Sn, then we say m2 is more specific than m1 if
each Si is a subtype of Ti. (Note that a type is a subtype of itself.

So far, this is pretty straightforward. Things get interesting when we mix
primitive types with reference types. Because Java allows autoboxing,
primitive types can "match" reference types. This occurred in our example
above. However, boxing and unboxing are only applied during the phases to
determine which methods are applicable. Once Java has determined the set of
applicable methods, it no longer considers boxing or unboxing. It only looks
at the parameter types.

This means that when selecting the most specific method, Java will on occasion
need to determine if a primitive type parameter is more specific than a
reference type parameter. To resolve this question, Java considers the
arguments in the actual method invocation. The more specific parameter is the
one which is a supertype of the argument used in the invocation.

So when comparing two methods the most specific method is the method in which
each parameter is either a subtype of the corresponding parameter of the other
method or, failing that, is a supertype of of the corresponding argument.

Rule for Selecting the Most Specific Method

If M is a method invocation with arguments
A1, A2, A3,..., An and m1 a method with parameters
T1, T2, T3,..., Tn and m2 is a method with parameters
S1, S2, S3,..., Tn, then we say m2 is more specific than m1 if
for each Si one of the following conditions is true:

If Si and Ti are both reference types or both primitive types,
then Si is a subtype of Ti

If Si or Ti is a reference type and the other is a primitive
type, then Ai is a subtype of Si

The rules that identify applicable methods guarantee that one of these
conditions will be true. This doesn't cover all of the rules in the JLS8
for determining specificity, just the parts that are relevant to this example.

The first parameters in our example case are Integer in the first method and
Number in the second method. Since Integer is more specific than Number,
the first method is considered more specific for the first parameter per the
first condition of the Rule stated above.

The second parameters are Integer in the first method and double in the
second method. Since one is primitive and the other a reference type, the
second condition of the Rule applies. Since the second argument is an
Integer, and an Integer is a subtype of itself, the first method is
considered more specific for the second parameter.

Since the first method is considered more specific than the second method for
each parameter, the first method is considered the most specific. Hence, the
first result is A1.

Item 2

This case is much easier. During the first phase of determining applicable
methods, boxing is not permitted, but widening is. Both parameters of the
invocation a.go(i, 3) can be widened to match the parameters of the second
method go(Number, double). Matching the first method would require a boxing
operation which isn't permitted in the first phase.

So in this case, Java never moves on to the second phase. Since only one
method was identified as applicable, there's also no need to determine the
specificity of methods. So the second result is A2.

See, I said it was easier.

Item 3

If we had included

System.out.println(" 3: " + a.go(3, 3));

as a 3rd invocation, the compiler would have complained that the "reference to
go is ambiguous." Hopefully this makes sense given the above discussion. The
invocation requires boxing to match, and both methods will match with some
widening thrown in.

The determination on which is more specific starts okay. The first parameter
of the first method is more specific according the first condition of the Rule.
However, the second parameter of the second method is more specific according
to the second condition of the Rule. We don't have a most specific method so the
compiler throws the "ambiguous" error.

Summary

This was a long post. Longer than I thought it would be. And I might have the
exact rule by which the compiler determines the most specific method wrong. It
is certainly incomplete. Chapter 15 of the JLS8 should come with a "here be
dragons" warning. I certainly feel that the language spec is a bit ambiguous
about this topic, but I'm probably just misreading some obvious point.
Eventually someone will point it out to me and I'll have a "Doh!" moment.

The important take-away from this example is that overloading is tricky. If
you're programming an API, avoid overloading or at least minimize it.
Effective Java recommends that you never have more than one overloaded
method with the same number of parameters. Seems like good advice to me. It
will certainly eliminate uncertainty about which method will actually be
executed.

This example explores what happens when you override overloaded methods. The interesting behavior in the program below (GitHub) comes into play when the example introduces differences between declared and actual types.

Shows that Java will select the overloaded method that exactly matches the parameter list. Not very surprising.

Item 2

As discussed in Example 1, the actual type of a reference is used when methods are overridden. Since x is a reference to a B object, only the B implementations are available in selecting which overloaded method to invoke. Of those, Java again selects the overloaded method that exactly matches the parameter. If you understand how overriding works this should not be very surprising.

Item 3

This one may be a little tricky as the dual use of x is misleading. The method invocation x.go(...) uses the same logic as in Item 2 above: since x is a reference to a B, the methods in B are the available candidates. At this point it is easy to just continue on with the idea that x is a B which could lead to the mistaken conclusion that the output should be B2.

The key to understanding the behavior that produces B1, is to understand that Java uses the declared types of the parameters to determine the signature of the method to invoke. Then it uses the actual type of the reference to invoke the method that best matches the signature. The details of this entire process are many and complex, but Section 8.4.9 of JLS8 gives an overview and points to the labyrinth of rules that govern overloading and method invocation.

Applying that knowledge to the example above, you can see that since the declared type of parameter x is A, the method that best matches the signature is one that accepts A as its only parameter. There are two of these methods: one in A and one in the subclass B. Since these methods are overridden, the actual type of the invoking reference is used (and will be determined dynamically at runtime). In this case, the actual type of reference x is B. So the conclusion is that the go(A a) method in class B is the method that will be invoked.

In most cases, the declared type is the relevant type in Java. When overriding comes into play, though, the actual type is used to determine invocation dynamically. So in the expression x.go(x), the first x is treated like a B (because of overriding) and the second is treated as usual like an A.

Once a method has been overridden in a subclass, that method's behavior is no longer directly available to the user of the subclass. See Item 3 in Example 1 for an example. Sure, the subclass can use super to invoke the overridden method, but that mechanism isn't available through a reference to the subclass. Overriding is irreversible.

Hiding is a different story. Java allows you to hide fields, nested classes, and static methods. Hiding static methods was discouraged in Example 2, Hiding Static Methods in Java, so let's use instance fields here.

The program (also on GitHub) below contains a simple hierarchy of three classes. Each contains an instance field s.

Output 1 clearly shows that the s in C hides the s in its superclasses. Outputs 2 and 3 show that to access the hidden fields in the superclasses, you simply cast the reference to the appropriate type.

This is a key difference between hiding and overriding. Overriding is forever. Hidden items can be uncovered. All it takes is a cast.

Will this code even run? The reference a is null and we invoke a method on it: a.go(). Won't it throw a NullPointerException?

It does run, no exceptions are thrown, and the output is:

Example 3
1: A1

This behavior is described in section 15.12.4 of JLS8,
and it cements the idea that you should always think of static methods as belonging to the class even when they are invoked through a reference. When you're reading code that invokes static methods on reference, follow the complier's lead: ignore the reference. Pay attention only to the reference's type.

Also, as mentioned in Example02, where possible, invoke static methods through the class itself. That is, do this: A.go(); not this: a.go(). This practice will reduce confusion and produce programs that are more easily understood.

In Java, you can't override static methods. However, a parent class and its subclasses can have static methods with identical signatures. In that case, the static method in the subclass is said to hide the identical method in the parent class. Overriding and hiding are both examples of what Java Puzzlers refers to as name reuse.

Static methods are also called class methods because they don't depend on an actual instance of the class. You invoke a static method directly on the class: A.myStaticMethod(). You don't need an instance of A to access myStaticMethod().

However, Java also allows static methods to be invoked through an instance. While this is discouraged by the language specification (see JLS8 8.5 on page 70), it is still common, and it causes confusion because static methods invoked through an instance look like instance methods--which are invoked dynamically.

The code in Example02 (on GitHub)
is identical to the code in Example01 except the go() methods are now static. In this example I am invoking the static methods through instances, contrary to the recommendations in the language spec. This is to better illustrate the difference in behavior when compared to Example01.

The output of A1 is not too surprising since we invoked the static method on an instance of an A class.

Item 2

This result is also not very surprising. You can see that invoking the static go() on an instance of a B class executes the method defined in the B class. This is called method hiding; the implementation of go() in B hides the implementation in A.

Item 3

Here we see the difference between instance methods and static methods. In Example01, the output of item 3 was B1. When go() is static, the output is A1. This difference is because static methods invoked through a reference are resolved based on the declared type of the reference. Since x is declared as a reference to an A, the implementation of go() in A is used.

If you refrain from invoking static methods on instances, this complexity is reduced. Invocations such as A.go() or B.go() are fairly unambiguous. In fact, the Java compiler pretty much ignores instance references when invoking static methods, and only pays attention to the declared type of the reference. Example03 shows this explicitly. If the compiler can resolve references to their types, then you should be able to do it in most cases when writing the code.

Check out Puzzle 48 in Java Puzzlers for more information on this behavior. In particular, the authors take it one step further than I do. Their advice: "Do not hide static methods."

I'm re-reading Joshua Block (Effective Java and Java Puzzlers) and thought
I'd engrave some of my thoughts and notes here and on GitHub for future
reference. If you haven't read Effective Java or Java Puzzlers, you should
stop reading for a moment and order them right away. These books shine a
bright light into some rather dark corners of Java and provide insight into
Java programming that's worth more than a dozen certifications.

This post is inspired by Item 41 in Effective Java and Chapter 8 of Java
Puzzlers. I say inspired by because I'm not reproducing the code examples or
sticking to exactly the same topics as the book. These notes simply record
some of my thoughts while reading.

The program in Example01 (available on
GitHub),
consists of two classes, A and B. B is a sublcass of A. B overrides several
methods inherited from A. Here's the code:

This output is terribly interesting, but let's walk through it quickly to
make sure sure it's clear.

Item 1

This is basic method invocation on an object.

Item 2

Here we see that Java does support overriding. The method go() is
implemented in A and then it is re-implemented in B. Invoking go() on a B
objects executes the implementation in B. Which isn't too surprising.

Item 3

Finally something a little more interesting. Take a moment to think about this
situation. The variable x is of type A, but it actually references a B
object. The complier allows this because B is a subclass of A. These sorts of
discrepancies between declared and actual types often produce interesting or
unexpected behavior in Java.

Logically, x.go() could execute the implementation defined in A or B. Since
x is of type A, then it is easy to imagine that A1 would be the output,
such as we saw with Item 1. But the output is B1. This is because Java determines
the actual type of the object dynamically, during runtime, and selects the
method with the appropriate signature defined in that class. If that class
does not define an appropriate method, Java climbs up the class hierarchy
looking for the right method (see the invokevirtual instruction in the
Java Virtual Machine Specification).

This is an example of polymorphism. Instance methods are invoked dynamically.
As we'll see in Example02, static methods are not.

Ars Technica reports on Julia, an interesting language that is aspiring for pole position in the world of technical and numeric computing. The benchmarks are revealing. I'm most surprised though by the performance of FORTRAN. It still kicks ass after 60 years!

Dedication

My grandfather had a wonderful shop in his basement. To me, it was a place of mystery and fascination, and I would spend hours wandering through it, looking at all the tools and projects in various states of completion. Not being much of a wood worker, I've never had the need for such a shop (not to mention that I lack a basement), but recently it occurs to me that my gear, computers, and software are my shop. This site is for my late grandfather and everyone else who takes personal pride in carefully executed work.