Bistro mixes some of the language features from Smalltalk and Java. The design of Bistro attempts to achieve a balance between the features and limitations of both languages. The declaration of variables is an area that presents a set of design trade-offs. Smalltalk has a special syntax for declaring all variables before the statements of a method or a block scope. Java allows variables to be declared and initialized in-line in the body of a scope. The later feature is preferable because it makes code maintenance easier. Java requires that every variable declaration includes a type specification, while Smalltalk has no type specifications. Both of these options are important. Some of these choices have implications for other design choices, such as whether a variable from an outer scope can be overridden by an inner scope. Table 3 compares these features and limitations with respect to variable declarations, and indicates what Bistro supports.
Bistro variable and argument type specifications are optional. Making types optional imposes the need to forbid variable redeclaration. To simplify the language, Bistro eliminates the need to declare local variables in a separate section at the beginning of each block. As with Java, variables can be declared anywhere in a scope, so long as they are declared before they are used, typically with an initial value. The Bistro compiler optimizes messages sent to typed variables, including sends to self and super. For untyped variables and expression results, the compiler automatically generates dynamic message sends using an appropriate perform: message.
The absence of explicit type information in Smalltalk contributes to its simplicity and its agility during software development. Software prototyping is much easier without type information. Specifying type information pervasively throughout a software system during development requires much more time. Also, the type information simply makes the resolution of method implementations safer and more efficient.
The Java reflection facility provides information about object types at runtime. So, Bistro uses the Java reflection facility to determine the type of an object and to resolve method invocations at runtime (late binding). The Bistro compiler takes advantage of the standard Smalltalk perform: messages to implement dynamic method resolution when needed. An unimplemented method discovered at runtime produces a AbsentMethodException.
Of course, the most significant issue associated with dynamic method resolution is performance. Experimental measurements indicate that raw reflective method invocations are about 100 times slower than normal method invocations. This is significant, but not necessarily prohibitive.
All of these contributions make the exploration of dynamic method resolution worthwhile. Also, given that Sun has made the Java VM available through a community source license, it may even be possible to customize the VM to accelerate method lookup for dynamically typed languages like Bistro and Smalltalk.
Bistro provides a spectrum of optimization options. Smalltalk developers will feel at home with the ability to write code with familiar idioms and classes. Then, as application interfaces harden and classes mature, type annotations may be added to classes in order to improve the performance of method resolution when and where needed. Performance critical methods may even be recoded directly in primitive Java methods. Finally, if 100% purity of the Java code can be sacrificed, a Java Native Interface (JNI) can be used to create platform specific optimizations written in C or C++.
Java is a trademark of Sun Microsystems, Inc.
Permission is granted to copy this document provided this
copyright statement is retained in all copies.
Copyright 1999-2001 Nikolas
S. Boyd.