ChiMu  
 
Menu Edge About   Products   Services   Projects   Publications  
  Publications                 

Compiler as mediator in Smalltalk and Java

Overview

This is a discussion of the benefits to Java static typing and the ability of the Java compiler to find bugs at coding time.

The following is a reference to the main thread-point that this short paper is on:

Original Posting: Compiler as mediator in Smalltalk and Java

Peter Kwangjun Suk wrote:
[SNIPPED CONTEXT]
> IMHO, no one who has looked honestly into both Java and Smalltalk
> could say that Java mediates better between people.  Type safety just
> doesn't seem to buy that much in the context of Smalltalk.  The fact
> that you have to go through this edit-compile-debug cycle, and that
> you don't have *everything* in your image conveniently available
> causes a shift in perspective.

To be fair to Java, you really need to compare VisualAge/Java against the standard Smalltalk IDEs. For this comparison, the edit-compile cycle is exactly the same granularity as Smalltalk (i.e. by method and class declaration) and you do have *everything* in your image that you want to have in it (as well as everything else available in the repository). You also have a decent debugger and other similar capabilities. Some things are missing but they are not that important or could be added with time (e.g. the Refactory browser would be even more useful in Java)

In this comparison context, the "mediation" capability of Java interfaces can be witnessed to its best advantage [however good that is]: VisualAge simply places an 'X' on any method/class that has a static-typing problem. Is this useful in comparison to Smalltalk behavior? I would say yes with heavy qualifications (because of all the other implications of static-typing). The type-checking certainly makes the client immediately aware of any "typing" problems in their code without being too intrusive: if the method is not necessary for execution, you can still "run" your program. Note though, that this is behavior beyond Java-compliant capabilities [and see far below]. In the best (rose-tinted) light, this "mediation" simply shows DoesNotUnderstand exceptions at the earliest possible moment[1]. And although I agree with previous threads that "typing" problems are not the most serious/common problems in good OO software it is kind of nice to be reminded of them as soon as possible and to have a continuous status of how many of them are remaining[2]. I do think this helps beginning programmers significantly and others moderately.

Qualifications

Now some of the qualifications. First note that I use a lot of "semi-unusual" standards in Java to ameliorate the failings/pains of static typing and Java-specific problems. These failings include:

  1. Typing to Classes [implementation]. This horribly impedes reuse, limits generalization, and makes a system intollerant of growth/changes.
  2. Poor granularity of Types. Frequently a Type will be specified that has too many operations (is too specific) to be useful in multiple contexts even though subsets of those operations (a more general concept) is widely useful. Since it costs effort to name and create each Type, there is an impetus of reduction that again impedes reuse and generalization. Save now, pay later.
  3. Loss of precise type information when objects are fed through more generic structures.
  4. Using types as a "poor-man's" documentation of an operation's responsibility 'do(Buffer,int)'
  5. The horrible 'static' keyword used with methods: Static methods aren't really methods at all (there is no object for them), do not support inheritence, are not compatible with interfaces, and are completely bound at compile-time [OK, that is the true problem, the others are just symptoms].
So again, I use a bunch of standards to avoid these problems in Java. Some of these are documented in [3] and I will mention the most relevant here:
  1. Interface with interfaces: Interfaces own the normal "namespace"[4] and almost all variables should be typed to an interface. This makes clients able to specify the capabilities they require without coupling them to a specific implementation and the implementer is able to choose/enhance/change the implementation as needs dictate.
  2. Almost no static methods other than 'main's: Instead, conceptually static methods are moved to singletons, factories, pack objects (see [3]), and similar objects.
  3. Potentially multiple interfaces for different types of clients (General, Extended, Factory, various Friends, etc.)
  4. Woven parameters: Parameters are woven into operation names with an underscore ('_') as a placeholder (fooX:y: -> fooX_y) so the caller has a good idea of parameter order just from reading the operation's name.
  5. No overloading methods on parameter types: toString(Object) and toString(String) are not acceptable.
  6. Casting/typechecking '(Foo)' is perfectly acceptable, especially with collections and similar type-losing structures.
  7. It is acceptable to throw a "ShouldNotImplement" exception if a class only mostly conforms to a 'Type'/Interface. This is the same behavior as the JDK started with the new Collection classes and somewhat works around the granularity problems.
  8. Only public and protected visibility usage in 99% of the code. Also, a bit of a tendency to promote visibility to 'public' and control access through the interfaces in (1) and (3).

The above and similar standards make some of the failings of static-typing and Java go away or at least live in a much smaller island within a better behaved world of objects.

The need to have strong standards to avoid these problems is itself a heavy qualification. Most of the above are work arounds for static problems: it isn't that I wouldn't like the compiler to check and mediate between developers, third party libraries, or even myself with myself, but the compiler is just not doing a good job. Its mediation is even discouraging good designs that cause static-typing difficulties[5]. So the compiler is relegated to having more constrained responsibilities and we also need to have bad constructs "linted" out. Also, the whole concept of Envy extensions, intelligent proxies, true meta-classes, etc. is pretty much impossible in the Java/static environment.

VisualAge capabilities and universal VMs

Anyway, on to a slightly different topic to counterpoint some of the comments above. Note that VisualAge is able to execute Java in ways that are beyond the standard Java specifications. The ability of VisualAge to run Java classes when there are errors in it is the most striking example of this, but there are lots of other unusual capabilities. Well, we all know it can do this because it is actually running Java on top of a more universal/Smalltalk-supporting VM. So in some ways VisualAge/Java is a bad argument for Java because it is really acting with a core of Smalltalk behavior that simply emulates some of the restrictions and "metadata" that are available to Java. And the point is: this augmented behavior is *extremely* useful, especially during development.

So, maybe we should just think of Java as both a (somewhat poor) semi-OO training language and a (reasonable) open VM for a sandboxed simplified Smalltalk with Types. The second of these suggest Java is better considered a *target* language and only a poor-man's development language. Smalltalk, Dylan, Eiffel, etc. enhanced with Java understanding are actually the real development languages. And this is exactly the case with VisualAge except the Smalltalk portion has been hidden away.

Yes, it would be better if the Java VM was a bit more universal. Yes, it would be better if the Java language got rid of its messes and supported DBC as well as Eiffel. Which takes us back to the "How to get SUN to augment the JVM with broader language/OO-concept support" thread...

--Mark
mark.fussell@chimu.com

[1] The reality with less tinting is that nil/null DNU/pointer-exceptions still happen and that the object being sent the message may truly understand the message even though its compile-time type does not declare it to.

[2] Smalltalk can tell you whether "fooX:y:" has every been "declared" before, but as soon as you save/accept the method you lose the information about the possible problem. On the other hand, the refactory browser can prevent going through some of these intermediate bad-states by doing an intelligent global search&replace.

[3] http://www.chimu.com/publications/javaStandards/index.html

[4] Classes are suffixed with 'C'/'Class' and 'AbsC' if abstract.

[5] Java's core libraries are so much weaker than Smalltalk's (in terms of functionality, quality, and reusability) in good part because of static-typing problems.

 
Publications