A Smalltalk/Java Hybrid
During the 1970s, Smalltalk pioneered several advanced computing technologiesthe mouse, high-resolution bitmapped graphics displays, graphical user interfaces with overlapping windows, object-oriented programming, and virtual machines with automatic garbage collectionthat have become prevalent in the computing industry. Smalltalk also influenced the development of platforms such as Java. For instance, the Java class libraries have grown to embrace several features offered by commercial Smalltalk libraries, including mature
Collection classes and the introduction of the Swing libraries. Java has grown massive, providing a vast selection of reusable classes and frameworks.
Over the past decade, Java has been adopted throughout the computer, communications, and consumer-electronics industries. Some vendors have even gone so far as to integrate Java into their operating systems. The pervasive availability of Javaespecially the Java VMhas motivated many software developers to port their favorite programming languages to the Java platform; see, for instance, Robert Tolksdorf's "Programming Languages for the Java Virtual Machine."
Of course, every programming language attempts to give easy expression to both conceptual and computational models. But as with all engineered artifacts, trade-offs balance various forces and emphasize some over others. Consequently, each programming language has its strengths and weaknesses, and a fitness for solving certain kinds of problems. But while some programming languages may ultimately be computationally equivalent, they often exhibit differencessometimes vast differencesin the ease with which they express concepts and computations. Such differences then also impact the reusability of models and solutions developed with those languages.
There are several motivations for model reuse, the primary one being economicit's often cheaper to reuse existing solutions. However, solutions developed in one programming language may not translate well into another programming language, or the investments needed to accomplish such translation may be prohibitive. Sometimes, the differences in expressiveness are so vast that the costs of solution conversion and maintenance may exceed the expenses incurred during their original development. So the differences between programming languages are often warranted.
While there are many similarities in the overall design approach to Smalltalk and Java, it remains that language expressiveness, readability, and agility are Smalltalk's greatest advantages. While these advantages may be lost on programmers responsible for lower level system and infrastructure facilities, it fulfills many needs of business application programmers, especially those responsible for modeling business enterprises.
Java's syntax was largely derived from C++, which was itself derived from C, and it retains many of the expressive limitations and biases of C/C++. This kind of language syntax lends itself to expressing mathematical formulas and long procedural methods. While it's still possible to use Java to write C-style code, it's much harder to do that with Smalltalk. You really have to work at it, and in contrast, it becomes much more obvious that so much procedural code detracts from the overall quality of an otherwise object-oriented design.
Smalltalk fosters a particular design mindset. It offers a set of language usage and design idioms, conventions, and metaphors that have material consequences on software designs. Well-crafted object-oriented designs are easier to express, evolve, and maintain in Smalltalk. While it is possible to create mathematically oriented designs with it, Smalltalk also supports method signature designs that resemble natural language expressions. This feature remains one of Smalltalk's primary strengths, and offers many advantages over most other algorithmic programming languages. Objects developed with Smalltalk generally adhere to a common style of simplicity. Methods are generally smaller and more readable. Less internal documentation is usually required. Long procedural methods, like those often found in C code, are seldom found in Smalltalk. Classes are also generally smaller. Responsibilities are generally more evenly distributed throughout a set of collaborating classes.
Some of the common design patterns discussed in the software patterns literature were motivated by the capabilities and idioms of Smalltalk, for example, the Iterator pattern, which resembles Smalltalk Collection processing idioms; Factory Method and Abstract Factory patterns, which resemble the responsibilities of Smalltalk Metaclasses; Observer and Model-View-Controller patterns, pioneered in the Smalltalk human interface classes; and Flyweight pattern, of which Smalltalk Characters and Symbols are examples. (See Design Patterns: Elements of Reusable Object-Oriented Software, by Erich Gamma et al., Addison-Wesley, 1995.)
Other commonly used software development techniques and technologies were also pioneered with Smalltalk. For example, the JUnit test library was derived from the earlier SUnit library, and the tenets and practices of Extreme Programming were originally pioneered in the context of software development with Smalltalk, especially because of the agility offered by the Smalltalk language and integrated development tools.
Bistro: Smalltalk Over Java
These issues of reuse and expressiveness led me to develop the Bistro programming language. The method syntax for Smalltalk supports designs that resemble natural language expressions. So Bistro provides a natural method syntax that closely resembles that of Smalltalk. However, the Bistro compiler translates all methods into Java and generates Java class files. So, Bistro provides close interoperability with Java, thereby supporting reuse of all the existing Java class libraries. The primary goals influencing the design of Bistro were:
- Retain the simplicity, expressiveness, and readability of Smalltalk.
- Provide a class library compatible with the ANSI Smalltalk standard.
- Compile Bistro code to standard Java class files.
- Support seamless integration with existing Java classes.
- Support primitive methods in Java.
While Smalltalk has a superior method syntax for modeling concepts, Java offers several features that Smalltalk lacks. Bistro integrates the best features from both languages, especially taking strength from the one where the other is weak. Table 1 lists the features found in Bistro and where the feature originated, whether from Smalltalk or Java.
Table 1: Bistro includes the best features from both Smalltalk and Java.
Traditionally, Smalltalk systems were built in the context of an object memory image. Smalltalk class definitions were loaded from source files in the context of the image. While an image-based development environment contributes significantly to the agility of Smalltalk's integrated suite of tools, it introduces some difficulties for code, component, and system configuration management in large development projects.
A declarative, file-based programming model makes it much easier to use existing commercial version control and configuration management tools. Java is file based, both for its source code (.java) and executable binaries (.class). Java also supports the deployment of class libraries as files in archival form (as .zip, .jar, and so on). To leverage these Java features, Bistro utilizes a declarative language model for its source code files (.bist). The current Bistro compiler performs source-to-source translation from Bistro to Java. Then, the Bistro compiler uses a standard Java compiler to compile the intermediate Java source code into class files.
Smalltalk methods and blocks are similar. Each method and block contains a series of statements. The primary difference is that blocks are delimited with square brackets [ ], while methods are not. To support a declarative language model and normalize the syntax, Bistro uses square brackets as scope delimiters throughout. Thus, the declaration of Bistro classes, types, methods, and blocks are delimited with square brackets (except for primitive methods).
The overall source-code structure of each Bistro class resembles that in Java, including the location of classes with respect to their packages. However, the specific syntax used to declare a Bistro class resembles that found in Smalltalk. Listing One provides a general template for Bistro class definitions, while Listing Two provides more specific templates for several kinds of class and type definitions supported by Bistro.
"Identify the package for the class." package: smalltalk.example; "Make all the Collections visible." import: smalltalk.collection.*; "Define a new class and metaclass." Superclass subclass: Subclass metaclass: [ "... class methods ..." ] class: [ "... instance variables ..." "... instance methods ..." ]
"A root class definition" nil subclass: RootClass metaclass: [ "..." ] class: [ "..." ] "A derived (sub)class definition" Superclass subclass: Subclass metaclass: [ "..." ] class: [ "..." ] "A root type definition" nil subtype: RootType metatype: [ "..." ] type: [ "..." ] "A derived (sub)type definition" Supertype subtype: Subtype metatype: [ "..." ] type: [ "..." ] "A derived (sub)class that implements a type" Superclass subclass: Subclass implements: Type "..." metaclass: [ "..." ] class: [ "..." ]
Root classes and types are derived from
nil. Root types have no equivalent Java supertype, but root classes are derived from
java.lang.Object and root metaclasses are derived from
smalltalk.behavior.Class. Thus, the
smalltalk.behavior.Object class is derived from
java.lang.Object and its metaclass is derived from
Method and Blocks
There are two Smalltalk featuresblocks and keyword method signaturesthat tend to distinguish it from most other programming languages. Smalltalk blocks provide a unifying mechanism for statement execution. Both blocks and methods use the same underlying statement execution mechanism. Smalltalk keyword messages support method signature designs that resemble and model natural language expressions. Because these features are central to the expressiveness of Smalltalk, Bistro also offers these features. Bistro blocks and natural methods closely resemble Smalltalk, as do Bistro keyword method signatures. However, Bistro also provides some method signature extensions and decorations that let it integrate relatively seamlessly with Java.