Building Blocks

Building Software Better

SmallJava-97, The Language

Posted by Mark on August 27, 1997

This document is comparing Smalltalk and Java through an intermediary language, SmallJava. SmallJava will start as the common elements from both Smalltalk and Java. It will then be used to discuss how new properties brought into SmallJava from Smalltalk or Java impact the language. The first item on the agenda is to specify what the base version of SmallJava will look like in both semantics and syntax.

SmallJava Semantics

SmallJava semantics will be the intersection of the common semantic features of both Smalltalk and Java. This will enable SmallJava to easily grow with features in either direction and will allow developers familiar with either language to also be familiar with SmallJava. To accomplish this goal requires simplifying the properties of both languages until the remaining cores overlap sufficiently. Because of the similarities in the languages not very much has to be removed from either.

Smalltalk and Java Simplification

First I will simplify Smalltalk to get to its core. To do this SmallJava will:

  • (S1) Use class declaration instead of class construction
  • (S2) Drop all the Metaclass/Class capabilities
  • (S3) Ignore how blocks and control messages are different from control structures.
  • (S4) Only have a single root class “Object” that all classes must inherit from directly or indirectly.

This gives us a dialect of Smalltalk like “Little Smalltalk” [Budd 87]. We have dropped (or not mentioned) a lot of capabilities of professional Smalltalk dialects, but we still have a valid dialect of the Smalltalk language.

Next I will simplify Java to match up with the above simple Smalltalk. To do this SmallJava will:

  • (J1) Drop access control. All methods will be public and all instance variables will be protected which closely matches Smalltalk’s standard access controls.
  • (J2) Ignore the static side of Java classes.
  • (J3) Consider all primitive data types to inherit from Object. Viewed differently, you could say that all the Java control structures, operators, and other expressions work with the Wrapper versions of the primitive data types.
  • (J4) Make allowances and simplifications with certain packages and operators. For example the “Math” functions will be made available without needing the “Math” prefix.
  • (J5) Drop the use of static typing. All variables, parameters, and return types will be typed as “Object” and messages can be successfully sent to an object that has a method with the right signature. Since static typing is removed, interfaces are removed also and we simply have classes extending other classes.

The only dramatic change to Java is by J5. An interesting aspect of J5 is that if you take a working program it still works after applying J5 to it. This will be shown in the example below.

The change J3 is also sizable but I believe it is an “unquestionable” improvement so less interesting although this will also be discussed in later sections.

SmallJava Semantics Summary

Stated again, SmallJava’s semantics are the intersection Smalltalk and Java with each simplified as specified. A more formal description might be useful but is not in the scope of this document. It would also have to be many formal descriptions because SmallJava will be constantly changing as we add new properties to it. Beside the above informal description, examples of SmallJava will be provided as the document progresses. Next we have to specify SmallJava’s syntax.

SmallJava Syntax

SmallJava uses primarily Java syntax. This is to allow easier discussion of adding in Java properties (e.g. static typing and interfaces) since I can use Java syntax for those properties. It is also true that many programmers are more familiar with ‘C++’ like syntax than with Smalltalk syntax. Adding in Smalltalk properties to SmallJava generally does not require extra syntax (blocks “[ | ]” being the notable exception) but instead either requires objects to become “smarter” (control messages for Booleans and Collections) or requires developing new types of objects (Class objects).

If you are interested in a syntax level comparison between Smalltalk and Java, you might want to look at: http://www.chimu.com/publications/SmalltalkJavaSyntax.html. Also some of my naming conventions make Java look a bit more like Smalltalk so the syntax difference will not be quite as noticeable.

The SmallJava Language

This resulting SmallJava is a language you can view as either a simple Java without static typing or as a simple Smalltalk with Java syntax. I will show each of these views in different ways. First I will show the similarity to Java by applying the “J” transformations to a Java program and turn it into SmallJava. Second I will translate the example’s syntax between SmallJava and Smalltalk. This will result in a total of three versions of the same example code in each of Smalltalk, Java, and SmallJava.

From Java to SmallJava

My primary example will be a simple Point class. The following is the original, 100% pure Java.

    public class Point {

        public Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        public double x() {return x;}

        public double y() {return y;}

        public double r() {return Math.sqrt(Math.pow(x,2)+Math.pow(y,2));}

        public double theta() {return Math.atan2(y,x);}

        public Point vectorFrom(Point point) {
           return new Point(x - point.x(), y - point.y());
        }

        protected double x,y;

    }

Now I will start applying the SmallJava changes. J2 doesn’t apply because there are no static methods. After applying J1, J3, and J4 to the example we get:

    class Point {

        Point(Double x, Double y) {
            this.x = x;
            this.y = y;
        }

        Double x() {return x;}

        Double y() {return y;}

        Double r() {return sqrt(x^2+y^2);}

        Double theta() {return atan2(y,x);}

        Point vectorFrom(Point point) {
           return new Point(x - point.x(), y - point.y());
        }

        Double x,y;

    }

The major dramatic effect of these changes is that all our numbers can now be used like all other objects (e.g. directly placed in Vectors and Hashtables). Except for these numbers and the simplified Math calls, the above is completely legal Java.

Next we apply J5 part 1: make all the variables typed to Object.

    class Point {

        Point(Object x, Object y) {
            this.x = x;
            this.y = y;
        }

        Object x() {return x;}

        Object y() {return y;}

        Object r() {return sqrt(x^2+y^2);}

        Object theta() {return atan2(y,x);}

        Object vectorFrom(Object point) {
           return new Point(x - point.x(), y - point.y());
        }

        Object x,y;

    }

Strangely enough, this is almost legal Java also. Basically it is missing a lot of casting to make it work. For example the method #vectorFrom needs to have casts like this to be valid Java:

    Object vectorFrom(Object point) {
       return new Point(
                             (Double) x - (Double) ((Point) point).x(),
                             (Double) y - (Double) ((Point) point).y()
                        );

    }

Well, that is a whole lot of casting, so it is fortunate we are dropping it. We will allow a message to be sent to any Object and if it the actual object does not implement that method we will throw a “DoesNotUnderstandException” (this behavior will be discussed in depth in the next section).

Now we can finish the J5 transformation and drop all the superfluous “Object”s. This gives us:

    class Point {

        Point(x, y) {
            this.x = x;
            this.y = y;
        }

        x() {return x;}

        y() {return y;}

        r() {return sqrt(x^2+y^2);}

        theta() {return atan2(y,x);}

        vectorFrom(point) {
           return new Point(x - point.x(), y - point.y());
        }

        x,y;

    }

The first SmallJava example

The above is the first example of SmallJava. From these transformations you can see that SmallJava is just like Java but with a lot fewer words. An important observation is, returning to an earlier comment, if the original Java Point class executed correctly then the above class would execute correctly too. The use of the static typing does not impact the correct behavior of the code at all [1]; it only helps detect incorrect specifications that will result in incorrect behavior (as does having multiple types of access control).

SmallJava to Smalltalk

Next, to show how similar SmallJava is to Smalltalk, the following is the SmallJava program converted to Smalltalk-like (see [Budd 87]) syntax (the bar “|” separates method):

    class Point  | x y | [
        newX: newX y: newY
            x := newX.
            y := newY.

    |

        x
            ^x

    |

        y
            ^y

    |

        r
            ^((x^2) + (y^2)) sqrt

    |

        theta
            ^(y atan2: x)

    |

        vectorFrom: point
            ^Point newX: x - point x
                      y: y - point y

    ]

The point of defining the SmallJava language is so people familiar with either Smalltalk or Java will all have a single common language they also consider familiar. For Smalltalk developers the transition is mostly a change in syntax. For Java developers the transition is mostly relaxing over typing: the Point class will execute correctly whether the types are there or not.

Summary: SmallJava as a Vehicle

SmallJava is a vehicle to compare and contrast Smalltalk and Java. SmallJava’s existence is the first comparison: these languages are very similar which makes SmallJava possible. In the next sections I will start the contrasting by adding properties of Java into SmallJava. I will begin by getting “pessimistic”.

———————————————————————

[1] Static typing can also be used to choose among overloaded message names, but I would argue that these Type overloaded messages are a very bad thing. It should be obvious to the programmer reading or writing a message what will happen. Overloading excessively hinders this: you also have to read the Type declarations of all the message parameters and know all the possible overloaded methods to determine what the compiler determines (which better be the same thing). This is not an objection to multi-methods which are a very different thing. See the comments on method naming http://www.chimu.com/publications/javaStandards/ for a slightly longer discussion of this.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: