Bistro Frequently Asked Questions

Under Construction!


Q: Why is the syntax of Bistro different from Smalltalk?

A: The design of Bistro was driven by some very specific goals. Foremost among these are:

  1. Compile Bistro code to standard Java™ class files.
  2. Maintain the simplicity, expressiveness and readability of Smalltalk.
  3. Support the ANSI standard Smalltalk behaviors where possible.
  4. Support seamless integration with existing Java™ classes.
  5. Support primitive methods written in Java™.
  6. Optimize messages to untyped receivers as much as possible without modifications to the Java™ VM.
  7. Optimize messages to typed receivers, including typed variables, arguments, and casted receivers.
  8. Provide mechanisms for porting Smalltalk code to a Java™ runtime environment.

Goals 1 and 2 were the primary factors I had to keep in balance during language design. They provided a constant tension for many decisions. Goals 2 and 6 drove the design of the syntax for Bistro messages and methods. Goals 3 and 4 drove the development of the initial class library supplied with Bistro. Goals 5 and 7 provided support for improving performance. Goal 8 provided a bridge to the existing Smalltalk world, because the future of Smalltalk remains somewhat murky while Java™ continues to garner increasing market share in all industry sectors.


Q: Why run Smalltalk on the Java™ VM?

A: Smalltalk and Java™ both have their technical merits. Many of those found in Java™ trace their origins back to Smalltalk. Together, Smalltalk and the Java™ platform provide a powerful combination. From a certain point of view, their integration seems inevitable.

  1. Smalltalk is a better modeling language than Java™.

    Smalltalk is far more expressive and readable than Java™. As I indicated in Using Natural Language in Software Development, Smalltalk provides a natural way to model the elements of natural language problem descriptions by directly supporting the linguistic metaphors we use in object-oriented software design. Thus, Smalltalk can provide superior traceability from the code back to the original requirements.

  2. Smalltalk and Bistro have first-class metaclasses, while Java™ does not.

    Object-oriented designs often need metaprotocols for factory and registry methods. Object-oriented frameworks with metaprotocols often make polymorphic metaprotocols desirable. Java™ static methods support a kind of inheritance, but without full polymorphism. So, Java™ does not support full metadesign and metaprogramming. However, like Smalltalk, Bistro provides first-class metaclasses, which support both inheritance and full polymorphism. See the introductory paper for more details regarding how Bistro metaclasses are implemented using the underlying Java™ object model.

  3. Many of Smalltalk's classes and frameworks are more mature than those found in Java™.

    Smalltalk supports generic programming easily, partly because of its dynamic object typing. Many of the Java™ classes have only recently achieved a level of parity in convenience with that found in Smalltalk - e.g., the Java™ 2 collection class framework. However, some parts of the Java™ platform have exceeded those addressed by standard Smalltalk - e.g., network programming. Java™ is maturing at a rapid pace, with broad support from the computing and communications communities.

  4. Java™ provides namespaces (packages) and a standardized binary distribution mechanism (class files and archives).

    Smalltalk has no standardized namespace mechanism. This can produce class name conflicts and complicates the integration of class libraries from disparate software vendors. Smalltalk has no standardized binary distribution mechanism for its classes. While Smalltalk's image-based development model contributes to its agility and productivity, it complicates product deployment.

  5. The Java™ VM supports more hardware platforms than Smalltalk, and continues its growth toward ubiquity.

    Java™ has grown to cover a wide variety of hardware platforms and includes support for thin clients, web applications, distributed services, embedded devices, smart cards and rings. More and more hardware and software vendors are integrating Java™ into their solutions. The Java™ platform has finally matured to the point of significant adoption by Fortune 1000 companies.

  6. It is feasible to host Smalltalk on the Java™ VM.

    The implementation of Bistro demonstrates that Smalltalk can be hosted on the Java™ platform. Bistro maps the Smalltalk object model onto the Java™ VM, and the essential class libraries have been ported. Most of the ANSI standard Smalltalk behaviors have been implemented.

  7. It is desirable to reuse Smalltalk classes in a Java™ deployment.

    As more enterprises embrace Java™ and deploy mission critical applications on the Internet, the demand for mature objects and frameworks will increase, and more opportunities for the reuse of Smalltalk classes and applications that address those needs will arise. Given the foregoing factors, why would anyone want to limit their options for class reuse and deployment to a proprietary VM implementation?


Q: How fast is Bistro on the Java™ VM?

A: See the performance benchmarks. Bistro supports optional type annotations and both typed and untyped method resolution. Messages sent to untyped objects use dynamic method resolution at runtime. For untyped message receivers, the Java™ reflection facility is used to resolve the implementation of a method based on the class of the receiver. The dynamic dispatch facility caches the result of the method resolution so that future invocations are faster. Methods invoked through the dynamic dispatch facility execute about 20-40 times slower than primitive Java™ methods. However, continuing advances in Java™ VM design and computer hardware make this performance difference insignificant. Also, Bistro provides additional mechanisms for improving performance, including compiler optimizations of some control structures, type annotations, primitive Java™ methods, and access through the Java™ Native Interface (JNI) to native methods.

Unlike Smalltalk, Bistro supports the ability to define the type of a variable or argument. The Bistro compiler retains such type information when translating code into Java™. The Bistro compiler optimizes messages sent to objects whose types are known at compile time. So, messages sent to self and super are always optimized. Messages sent to variables and arguments that have type annotations are also optimized. Optimized messages perform with the same speed as primitive Java™ messages.

Message expressions can be cast to a specific type using a special idiom. The compiler recognizes the as: keyword message and optimizes a message sent to the expression result. For example, the message x will be optimized in the following expression:

(5 @ 6 as: Point) x

The message (5 @ 6) creates a Point, but the compiler does not know this until the Point instance is explicitly cast to the Point class.

Bistro classes may include primitive methods written in Java™. So, primitive Java™ methods have full and direct access to the classes included in the Java™ platform. Many of the classes in the Bistro library have been implemented using the underlying Java™ platform classes, e.g., some of the collection classes and some of the stream classes. Seamless integration with Java™ was one of the many design goals for Bistro, but primitive Java™ methods also provide a way to increase performance for the "hot spots" in a design.

Like Java™, Bistro also supports the ability declare native methods. Native methods provide direct support for the Java™ Native Interface (JNI). The Bistro compiler translates native method definitions directly into Java™ native method definitions. These native methods can then be implemented using standard JNI programming techniques. So, Bistro supports the same mechanism as Java™ for methods that require maximum performance, or direct access to OS services. However, such methods tie a system to a specific OS platform and the code is no longer 100% pure Java™.


Q: Will Bistro support the Smalltalk Interchange File (SIF) format?

A: Yes. Please see the notes regarding the plans for roundtrip SIF conversions.


Q: What are the similarities and differences between Bistro and Smalltalk?

A: There are many syntactic similarities between Bistro and Smalltalk, but there are also some differences.

  1. Bistro supports the Smalltalk message syntax, with some extensions.

    To retain the expressiveness and readability of Smalltalk, Bistro uses essentially the same syntax for unary, binary, and keyword messages. However, to support seamless integration with Java™, Bistro extends the keyword message syntax with anonymous argument lists. Thus, keyword messages can include arguments separated by colons, as in the following example.

    (Point basicNew: 0 asPrimitive : 0 asPrimitive)

    The Bistro compiler translates the above expression into the following Java™ code.

    (new Point( 0, 0 ))
  2. Bistro blocks and methods resemble Smalltalk blocks and methods.

    The syntax for Smalltalk blocks and methods have many similarities, but block signatures are contained within their delimiters while method signatures precede their bodies, which have no delimiters. So, while blocks have delimiters, Smalltalk method bodies do not. This was one of the factors that originally drove the design of the Smalltalk chunk file formats. When represented in a flat file, Smalltalk method definitions need some kind of delimiter - hence the use of a bang (!) to mark the end of a Smalltalk method.

    "Example Smalltalk method (chunk)"
    yourself
    ^self !

    However, Bistro methods have delimiters. I chose to use the same delimiter used for blocks - square brackets.

    "Example Bistro method"
    yourself
    [
    ^self
    ]

    In fact, square brackets are also used to delimit class scopes. The consistent use of square brackets as delimiters makes Bistro class definitions structurally similar to Java™ class definitions, at least with respect to scopes. It also eliminates the need for code chunks. Overall, Bistro increases the similarities between blocks and methods, while finally providing a truly declarative class and method definition syntax.

    Bistro local block variables do not need to be predefined in a separate section within a block as they are in Smalltalk. Instead, they can be defined and used in-line as they are in Java™.

    "Example Bistro block"
    [ :a :b |
    max := a < b ifTrue: [ b ] ifFalse: [ a ].
    max
    ]
  3. Bistro supports optional type annotations.

    Java™ is strongly typed at compile-time, while Smalltalk is not. Bistro variables may be typed, but type annotations are not required. When a message receiver has a type annotation, the Bistro compiler translates the message directly into a Java™ method invocation. When a message receiver has no explicit type information, the Bistro compiler translates the message into an appropriate perform: invocation. The perform: methods resolve the type of the message receiver at runtime and select the appropriate method based on the actual receiver type. All variable type annotations appear after a variable name in Bistro. The following code fragment provides an example.

    "Example typed Bistro variable."
    sampleVariable (SmallInteger) := 5.
  4. Bistro class and type definitions mix language ideas from Smalltalk and Java™.

    Bistro class and type definitions use keywords in a way that resembles Smalltalk code, but the overall structure of the definitions resembles Java™ code. The following table provides a summary of the class and type definition patterns supported by Bistro. Note that each occurrence of [ "..." ] indicates where variable and method definitions may appear, and each occurrence of Type "..." indicates a list of implemented types.

    Definition Templates
    Class Definitions Type Definitions Type Implementations
         
    nil
    subclass: RootClass
    metaclass: [ "..." ]
    class: [ "..." ]
    nil
    subtype: RootType
    metatype: [ "..." ]
    type: [ "..." ]
    nil
    subclass: RootClass
    implements: Type "..."
    metaclass: [ "..." ]
    class: [ "..." ]
         
    Superclass
    subclass: Subclass
    metaclass: [ "..." ]
    class: [ "..." ]
    Supertype
    subtype: Subtype
    metatype: [ "..." ]
    type: [ "..." ]
    Superclass
    subclass: Subclass
    implements: Type "..."
    metaclass: [ "..." ]
    class: [ "..." ]
         
    Superclass
    subclass: Subclass
    class: [ "..." ]
    Supertype
    subtype: Subtype
    type: [ "..." ]
    Superclass
    subclass: Subclass
    implements: Type "..."
    class: [ "..." ]

    Notice that Bistro supports first-class metaclasses like those found in Smalltalk. Both Smalltalk and Bistro metaclasses provide full polymorphism. However, because Bistro metaclasses are all singletons, you cannot declare metaclass methods to be abstract. See the Bistro introductory paper for a fuller discussion of metaclasses and metatypes.

  5. Bistro reuses the Java™ class packaging mechanism for namespaces.

    Smalltalk has no standardized namespace mechanism. This can produce class name conflicts and complicates the integration of class libraries from disparate software vendors, or even different development teams within an enterprise. However, Java™ includes a mechanism for separating classes into packages. The Java™ class library makes extensive use of the package mechanism to organize the standard Java™ classes.

    Bistro reuses the underlying Java™ package mechanism by supporting package and import statements prior to a class definition. The following code fragment includes examples of both a package declaration and a list of imported packages and classes.

    package: third.person.util; "Identifies the current package."
    import: smalltalk.collection.*; "Imports all the collection classes."
    import: smalltalk.stream.*; "Imports all the stream classes."
    import: smalltalk.geometry.Point; "Imports the Point class."

    The Bistro compiler imports certain classes automatically, so you need not include them explicitly. This resembles how the Java™ compiler automatically includes the classes from the package named java.lang. These implicit imports include all the following Bistro classes.

    "All the behavior classes, especially the literals."
    smalltalk.behavior.*
    smalltalk.behavior.Object
    smalltalk.behavior.Boolean
    smalltalk.behavior.False
    smalltalk.behavior.True
    smalltalk.behavior.UndefinedObject

    "All the magnitudes, especially the literals."
    smalltalk.magnitude.*
    smalltalk.magnitude.Character
    smalltalk.magnitude.Double
    smalltalk.magnitude.Fixed
    smalltalk.magnitude.Float
    smalltalk.magnitude.Integer
    smalltalk.magnitude.Number
    smalltalk.magnitude.SmallInteger

    "The literal collection classes"
    smalltalk.collection.String
    smalltalk.collection.Symbol
    smalltalk.collection.Array

Oracle and Java™ are registered trademarks of Oracle and/or its affiliates.
SourceForge™ is a trademark of Geeknet, Inc.

Permission is granted to copy this document provided this copyright statement is retained in all copies.
Copyright 1999-2001 Nikolas S. Boyd.