Cryptic and Coffee Time


Reflection. When it was introduced in Java 1.1 I loved it. It made Java almost as flexible as real dynamic languages like Smalltalk, Python or Ruby. I used reflection to reduce boilerplate code and write functions to manipulate objects in generic ways. However, over time I backed off from my love of reflection. I found that it went against the "grain" of the language and mostly made life more difficult.

While travelling to my current client by train, I've started doing the cryptic crossword in the Metro, a newspaper that's given away free to London commuters. This got me thinking again about reflection and meta-level abstractions and how cryptic crosswords, oddly enough, can tell us something about programming.

Let's take a look at a couple of recent clues:

  1. Come in with article in container to amuse (9).
  2. Sad soldier in overturned vehicle (6).

Cryptic crossword clues are difficult because they mix concrete and meta levels and do not clearly distinguish the two. Part of the clue is a synonym of the answer, describing the concrete concept and the rest of the clue describes the word that is the answer, the meta level. Once you have identified which part of the clue is describing the concrete concept of the answer and which is describing the meta-level of the answer the clue is easy to solve but until then it is a puzzle.

The same applies to software. Mixing concrete and meta levels in the same code gets makes it hard to understand and therefore hard to maintain.

Reflection is a meta-level construct that is easy to abuse. Code navigation tools cannot statically analyse reflective code, which makes it difficult to determine the system's behaviour without running the system in a debugger and following each path of execution, a tedious process. However, transitions between concrete and meta levels do not require reflection. In an object oriented design, some objects are meta-level representations of other objects and meta-level transitions can be performed simply by calling a method or instantiating a class.

For example, persistence is a meta-level concept. Some object-relational mapping tools (no names, no pack drill) require that persistent objects expose state to the persistence mechanism through public getter and setter methods. These getter and setter methods are meta level concepts: they don't express domain concepts but expose how the domain concepts are implemented as Java objects. The danger is that programmers then think of these getters and setters as part of the object's domain-level API and invoke them in domain logic in other objects instead of implementing that logic in the class that actually owns the data. Domain logic then becomes separated from the data that it acts upon, increasing coupling between different parts of the code and making it harder to understand the intent of the logic. The benefits of an OO language are lost and the design regresses to a convoluted, procedural style.

A clear boundary between concrete and meta levels is key to guide understanding. In crossword puzzles, finding that boundary is what makes the answer obvious. In code, clear boundaries make it easier to understand what the code does, and therefore maintain the system.

In code, meta-level transitions fit naturally at tier or layer boundaries, for example, between the business logic and persistence mechanism, between the business workflow and user-interface or between an application and the transport protocol used for communication.

Let's look at those clues again, with the meta-level highlighted. Below, one side of the equals sign is a synonym of the answer, while the other side, in brackets, describes the words that make up the answer.

  1. [Come in with article in container] = to amuse
  2. Sad = [soldier in overturned vehicle]

Now it's much easier to work out the answers:

  1. "Come in" is a synonym for "enter", article is used in its grammatical meaning and in this case refers to "a", and a "tin" is a kind of container. So the clue tells us that the answer is a synonym for "to amuse", spelled out by "enter" followed by "a" inserted into the word "tin": Entertain.
  2. A "GI" is a soldier. "Overturned" means in reverse and indicates that a word for a vehicle will be spelled backwards. In this case the vehicle is a cart giving the letters "trac". So the answer is a synonym of "sad" spelled out by inserting "gi" into "trac": tragic.

Copyright © 2004 Nat Pryce. Posted 2004-09-22. Share it.