Bistro supports four kinds of methods: natural, primitive, abstract, and native. All four kinds of methods are declared with method signatures that resemble Smalltalk. However, Bistro method signatures may include modifiers from Java and may also include result and argument types. Bistro natural method bodies resemble Smalltalk. Bistro primitive method bodies are Java code. Bistro abstract methods and native methods have empty bodies. Abstract and native methods merely define method signatures without implementations, and they are translated into the equivalent Java abstract and native methods. Listing Three illustrates these method variations using keyword method signatures.
Listing Three
"A sample natural method" doItNaturally: argument [ "... Bistro statements ..." ] "A sample primitive method" doItPrimitively: argument { /* ... Java statements ... */ } "A sample abstract method" abstract doItAbstractly: argument [] "A sample native method" native doItNatively: argument []
Blocks are used for control flow and collection processing, as well as other features. Bistro supports the same block usage idioms offered by Smalltalk. Listing Four provides templates that illustrate how blocks are used for both flow-control and collection processing.
Listing Four
"Control Flow Alternatives" booleanExpression ifTrue: [ "..." ] ifFalse: [ "..." ]. "Loops and Iteration" start to: end do: [ :index | "..." ]. [ booleanExpression ] whileTrue: [ "..." ]. "Collection Processing" aCollection do: [ :element | "..." ]. result := aCollection collect: [ :element | "..." ]. result := aCollection select: [ :element | "..." ]. result := aCollection reject: [ :element | "..." ]. result := aCollection detect: [ :element | "..." ].
Namespaces
Originally, Smalltalk provided a single, flat namespace for classesand Smalltalk developers suffered. Smalltalk needed a mechanism for defining distinct namespaces to separate and group classes. The absence of namespaces permits class naming conflicts, especially when integrating large class libraries from third-party vendors. While some namespace models have been proposed for Smalltalk (see my article "Class Naming and Privacy in Smalltalk" The Smalltalk Report, November 1996 and "Name Space in Smalltalk/V for Win32," by Wayne Beaton, The Smalltalk Report, September 1994) and several proprietary mechanisms are available in the commercial Smalltalk environments, none has yet been widely adopted by Smalltalk vendors. Nor has the ANSI X3J20 committee included any namespace model in the Smalltalk standard (X3J20 Workgroup. ANSI Smalltalk. ANSI/NCITS 319-1998. ANSI, May 1998).
Luckily, the Java language model supports the namespace concept with packages. Packages organize Java classes into logical partitions that serve as namespaces for classes. This helps system designers prevent potential class naming conflicts. Java class files are physically organized into package directories in a filesystem. There is a direct correspondence between these logical and physical organizations.
Because Bistro code is translated into Java class files, Bistro reuses the Java package mechanism and the advantages it provides for separating, organizing, and grouping classes. All classes defined in a package are immediately visible to each other. The public classes from other packages can be made visible by importing them. As in Java, an import establishes visibility to an individual class or all the public classes contained in a package. Listing One includes examples of both a package declaration and import
statement. As with Java, any class outside the scope of the current package may be imported, or a class may be qualified by the name of the package in which it was defined. So, while the import
in Listing One makes OrderedCollection
visible, it may also be referred to by its fully qualified name smalltalk.collection.OrderedCollection
.
Classes and Metaclasses
The Bistro compiler translates Bistro classes into Java classes. Bistro class member variables and methods become Java class variables and methods. However, Smalltalk has full metaclasses, while Java does not. So Bistro implements its metaclasses by splitting each class definition into two partsone Java class for the Bistro class, and one for the Bistro metaclass. Putting the Bistro metaclass methods and variables into another Java class allows the metaclass hierarchy to parallel the class hierarchy as it does in Smalltalk. This provides inheritance and polymorphism for metaclasses such as those found in Smalltalk.