On this page:
7.3.3.1 Statics
7.3.3.2 Inheritance
7.3.3.3 Inheritance with Statics
7.3.3.4 Assignment Ordering
7.3.3.5 A Note on Naming
7.3.3.6 Stencil Code
7.3.3.7 Submission
7.3.3 B: SMoLTalk

    7.3.3.1 Statics

    7.3.3.2 Inheritance

    7.3.3.3 Inheritance with Statics

    7.3.3.4 Assignment Ordering

    7.3.3.5 A Note on Naming

    7.3.3.6 Stencil Code

    7.3.3.7 Submission

This assignment builds on your previous work in C: OMac.

7.3.3.1 Statics

Classes created objects that are isolated from one other. Sometimes, however, we don’t want them to be entirely isolated. In Java and other object-oriented languages, statics introduce the distinction between fields common to all instances of a class and those that are specific to each instance.

We will now change the syntax of the class macro to also admit statics:
(class cn
  (statics [sn is] ...)
  (fields [fn iv] ...)
  (methods [mn imp] ...))
but leave the rest of the syntax unchanged. Here, sn are names of static fields (represented as symbols), and is (“initial value of a static”) are expressions.

Assume that the statics have different names from the fields, so we don’t have to worry about which ones takes priority over the others.

The following example illustrates the expected behavior:
(class Cowboy
  (statics [cowboy-count 0])
  (fields)
  (methods
   [mosey-into-town
    (lambda (self)
      (set! cowboy-count (+ 1 cowboy-count)))]
   [town-aint-big-enough
    (lambda (self)
      (string-append
       "This town ain't big enough for the "
       (number->string cowboy-count)
       " of us"))]))
 
(define c1 (new Cowboy))
(define c2 (new Cowboy))
 
(call c1 mosey-into-town)
(call c2 mosey-into-town)
 
(test (call c1 town-aint-big-enough)
      "This town ain't big enough for the 2 of us")
(test (call c2 town-aint-big-enough)
      "This town ain't big enough for the 2 of us")

7.3.3.2 Inheritance

First, we will extend the classes from Classes with inheritance. For this portion we will not have statics. The class syntax changes to
(class cn extends sn
  (fields [fn iv] ...)
  (methods [mn imp] ...))
where sn is a symbol representing another class (“super’s name”).

You will also need to provide a pre-defined class called RootThis corresponds to Java’s Object, which is poorly named: Object is a class, not an object! that can serve as the root class for classes that have no real parent. Root itself has no fields or methods. It also has no parent; therefore, you need to define Root “internally” rather than using the class macro. This choice is intentional: it shows that some definitions may use powers that the language’s creator has but the language’s user does not.

Fields of the parent class are not visible in the child class. Each class can only see its own fields. This means the same field name can be present at each level, and each of these fields is different.If this seems confusing, what happens in Java—where all this is type-based—might confuse you even more.

Method invocation (call) looks up the method in the given object. If it is not found there, invocation chains to the parent. This repeats until the method is found or the chain reaches Root, at which point it raises an error.

Hint: Observe that method invocation happens on objects, but classes extend classes. That means an instantiated object also needs to instantiate its own private parent object, and so on. Again, there’s a relatively easy way to do this that will work most of the time, but may fail (i.e., produce undesirable results) in rare cases. Think about features interacting!

7.3.3.3 Inheritance with Statics

Finally, we will have both inheritance and statics! Our final syntax is
(class cn extends sn
  (statics [stn is] ...)
  (fields [fn iv] ...)
  (methods [mn imp] ...))
Assume that the statics of a parent aren’t visible in the child.

When you’re done with this, you’ll have a pretty good approximation of (untyped) Java classes!

7.3.3.4 Assignment Ordering

We have staged Inheritance with Statics by creating an intermediate deliverable in Inheritance. Other than statics, the two portions have exactly the same behavior. Some of you may find it easier to work in that order. Others may want to do it in one leap and then “subtract” out the statics portion to create a solution for Inheritance. If you feel that would be easier, you’re welcome to do it: we don’t counsel against it.

7.3.3.5 A Note on Naming

The name of this assignment is a riff on our SMoL languages and meant as a tribute to the great object-oriented language, Smalltalk. However, the language we have built up here is (unfortunately) not really Smalltalk: it’s much closer to an untyped version of Java. In Smalltalk, classes are objects too, enabling various operations on classes (known as reflection). Also, if every class is itself an object, and every object is an instance of a class, there can be classes whose instances are other classes; such classes are called metaclasses. This combination of ideas leads to a beautiful, almost mystical, class hierarchy that gives programmers enormous expressive power.

If you want to play with Smalltalk, check out Squeak, which is a modern implementation, or Pharo, a closely related language with lots of great features.

7.3.3.6 Stencil Code
7.3.3.7 Submission

Form