If You Don't Want Users to Use a Class, Give it an Ugly Name!

I spent the better part of a day trying to figure out why a clearly documented API call didn't work as advertised. It turns out that the library uses the same class name, but in a different package, for an implementation class with different methods, and Eclipse auto-completed to that package. That's reprehensible. Don't entrap your fellow programmers like that!

Several of my graduate students are working on a rather mundane problem, to get code grading results into the learning management systems that exist on many college campuses. Those systems work fine with multiple choice and fill-in-the-blank questions, but they don't have great extension points for scenarios such as “fill in this code and have the autograder run it”.

The principal extension point that they do provide is called “Learning Tools Interoperability” or LTI, and it's your typical heavyweight design-by-committee thing. And nobody ever thought of a homework assignment where students were asked to complete multiple coding problems.

So, we are developing plumbing, using the generally admirable Play framework. I had to do something with JSON-P, so that a run-of-the-mill educational app that didn't want to buy into the byzantine complexity of LTI could still be useful.

Play has a perfectly nice helper class to do the JSON-P thing. So I called it. And got a bizarre error message.

I tried adding the Scala library to the project. I tried compiling with the activator tool that Play provides for those people who prefer to work with vim instead of Eclipse. That gave me a different (and, as it turned out, more accurate) error message, that there was no jsonp method with a string and a JsonNode.

It took me the better part of a day to figure it out.

I shouldn't have imported play.api.libs.Jsonp but play.libs.Jsonp.

The play.api.libs.Jsonp class is an undocumented internal implementation class that doesn't have a jsonp method, but only methods with ugly names such as writeableOf_Jsonp.

Of course, I didn't consciously import play.api.libs.Jsonp. I just typed Jsonp and accepted the first suggestion that Eclipse gave me. I had no idea that there was more than one Jsonp class. The API docs list just one.

This particular programmer was familiar with the use of the underscore to uglify Java method names (writeableOf_Jsonp). So why not put it to work with class names as well? I would have never accepted autocompletion to Jsonp_Impl.

Ugly package names aren't the answer. I've seen lots of source files with bizarre imports such as

import com.sun.xml.internal.bind.v2.schemagen.xmlschema.List;

where someone hit Ctrl+Space to autocomplete List.

Providing pretty names in implementation packages is a terrible, terrible thing to do to your fellow programmers. DO NOT do this! If you have an implementation class that you don't expect users to use, give it an ugly name, such as Jsonp_Impl. DO NOT rely on package names to separate user-level classes from implementation classes. Not everyone programs in vim, and when one uses an IDE, autocompletion of package names is a deeply ingrained habit.