> urticator.net

  About This Site
> Domains

> Computers

  Concepts for Persistent Objects
> Language Design Principles

> Nameless Code

Nameless Code

It took a bit of thinking to find a good statement of this principle. My first thought was to say that code should be nameless, be able to exist and run with no names at all … but I soon realized that could just as well be a description of compiled code. My second thought was that code should also be able to be edited without names, but that wasn't right either. Names are too useful for referring to things to get rid of entirely.

My third thought was in pictures. The names in existing languages are all tangled up with the code, so that the code can't exist without them, like this.

What I want is for the names to be separate from the code, for them to be part of the means by which the code is manipulated, like this.

With all the above in mind, I finally came up with the following statement.

Names should be external to code.

Unfortunately, although I can state the principle, I can't really justify it. I have some weak arguments for it, but in the end the principle is just an idea that I find very attractive.

The strongest of the weak arguments, I think, has to do with the idea that words are not reality. We use words, or names, to refer to things that are part of reality, but the things in themselves don't have names. Wouldn't it be interesting to have a language that modeled this aspect of reality? I imagine such a language would have almost magical properties.

I got the rest of my weak arguments by trying to think of specific problems caused by names.

  • Some things don't need names; inventing names for them is a waste of time. (This is one of the problems Hungarian notation was designed to solve.)
  • Names get used up, and can conflict with one another. (But namespaces, particularly hierarchical namespaces, are helpful.)
  • If name resolution occurs at runtime, it can be inefficient.

So much for justification.

What I'd like to do next is look at some examples. I don't have any examples of the complete namelessness I'm looking for, of course, but I do have some examples of specific parts of code being nameless. (Are parts of code like parts of speech?)

In Java, it's possible to create nameless classes. Here's an example from The Java Tutorial.

someObject.addMouseListener(new MouseAdapter() {
    public void mouseClicked(MouseEvent e) {
        ...//Event handler implementation goes here...

I have to admit I find the syntax terribly confusing. The call new MouseAdapter() creates not a new MouseAdapter, but rather a new object belonging to a nameless subclass of MouseAdapter with its mouseClicked method overridden.

It's well known that the lambda expressions that appear in functional languages such as Lisp and Scheme produce nameless functions. For example, the result of evaluating the following expression is a nameless function of one argument that returns the argument plus three.

(lambda (x) (+ x 3))

In statically scoped languages, it's possible to make the local variables nameless as well, like so.

(lambda 1 (+ (var 0 0) 3))

Here, the expression (var 0 0) looks up the first variable in the first enclosing frame. (Remember, index numbers start with zero.)

We can even get rid of the expression and function names, by, say, creating objects (in memory) to represent each expression and function, then replacing all the names with pointers to the objects. And guess what? The result looks a lot like a compiler's intermediate representation of code … a representation that is very convenient for analysis and transformation.

So, that's another good way to think of nameless code. If I could take the intermediate code produced by a compiler and refer to the different parts of it via the compiler's symbol tables, that would be almost exactly what I want.

Q: What's the point of replacing names with pointers to objects? Aren't pointers just another kind of name?

A: It's true that pointers are very similar to names. Both are used to refer to other things, and both are context-dependent, the context for pointers being the local machine. The difference, I think, is that pointers don't need to be resolved—if you have a pointer, you don't need to look it up to know what it refers to, you just know.

Now that I've given some examples of parts of code being nameless, let me finish by mentioning a case in which code seems particularly nameful. Consider the following function (in C++).

template<class TYPE>
TYPE max(TYPE t1, TYPE t2)
   if (t1 > t2) return t1;
   else         return t2;

As a template, or generic, function, it operates on objects of an unspecified type TYPE, and can be used to find the numerical maximum of integers, the alphabetical maximum of strings, or whatever. The part that's nameful is the less-than operator. Since the argument type isn't known in advance, there's no way to resolve the name “>” to any particular function.


  See Also

  Hierarchical Namespaces
  Words Are Not Reality

@ January (2001)