[Grace-core] Super-Outer-Objects: What does your language (gBeta/Newspeak/Scala/Java…) do with this? What should Grace do?

Lex Spoon lex at lexspoon.org
Mon Nov 19 06:33:49 PST 2012


On Mon, Nov 19, 2012 at 5:26 AM, James Noble <kjx at ecs.vuw.ac.nz> wrote:
> If this were Self, and nesting was just multiple inheritance,
> both calls to "C" would resolve to "C-pathological".

Somehow I never realized that aspect of Self.

To put the punch line at the beginning, I believe questions about
identifier lookup can be answered by considering the requirement of
having at least optional static typing for Grace. For static checking
to be sound, all lookups must be performed at compile time, and the
results of those lookups must be compatible with what the associated
code will do at run time. The dynamic lookup doesn't need to have the
same result as the static lookup, but it needs to resolve to something
compatible to the static lookup.

Let me now give the rules that Scala and Java use, and then show how
that plays out in the devious example code that you posted, James.

In Scala and Java, there are two different lookup mechanisms:
selection of object members, and lookup of an identifier in a scope.

Selection is used for evaluating expressions like C.foo. The
identifier "foo" is looked up in the members table of the object
referred to by "C". The member table of "C" was established at the
point C was created, at which point inheritance was considered.

Scope is used to look up bare identifiers, e.g. the identifier
"pathological" in method A.B.foo. For each place that code can occur,
a scope is built up. This scope includes mappings from nested and
inherited scopes, according to some precedence rules in case the same
identifier is in more than one of the scopes.

In Scala and Java, if the result of a scope lookup is an object
member, then a "this" expression is automatically inserted, thus
turning it into a selection.


Those are the rules. For the examples given:

A.pathological: Prints A-pathological.

A.B.foo: Prints A-pathalogical. The "pathalogical" in A.B.foo is
replaced by "A.this.pathological".

C.pathological: Prints C-pathological.

C.foo: Prints A-pathalogical. The direct call is to B.foo, which has
been automatically rewritten to "A.this.pathalogical". The call to
A.this.pathological does not involve any inheritance.


// Scala version. Note that "def" means function
// and "val" means read-only variable.

object A {
  def pathological { println("A-pathological") }
  class B {
    def foo { pathological }
  }
  val B = new B  // Allowed due to separate namespaces for types and values
}
object C extends A.B {
  def pathological { println("C-pathological") }
}


A.pathological
A.B.foo
C.pathological
C.foo


Lex Spoon


More information about the Grace-core mailing list