[Types-sig] namespaces (was: Changing existing class instances)

Greg Stein gstein@lyra.org
Fri, 21 Jan 2000 03:08:19 -0800 (PST)

On Fri, 21 Jan 2000, Tim Peters wrote:
> [Greg Stein]
> > ...
> > In other words, I definitely would support a new class
> > object behavior that allows us to update a class' set of
> > bases and dictionary on the fly.  This could then be used
> > to support my solution for the recursive type scenario (which,
> > in turn, means that we don't have to introduce Yet Another
> > Namespace into Python to hold type names).
> Parenthetically, I never grasped the appeal of the parenthetical comment.
> Yet Another Namespace for Yet Another Entirely New Purpose seems highly
> *desirable* to me!  Trying to overload the current namespace set makes it so
> much harder to see that these are compile-time gimmicks, and users need to
> be acutely aware of that if they're to use it effectively.  Note that I
> understand (& wholly agree with) the need for runtime introspection.

And that is the crux of the issue: I think the names that are assigned to
these classes, interfaces, typedefs, or whatever, can follow the standard
Python semantics and be plopped into the appropriate namespace. There is
no overloading.

The compile-time behavior certainly understands what names have what
types; in this case, if a name is a "typedecl", then it can remember the
*value*, too. When the name is used later, it knows the corresponding
value to use. For instance:

  IntOrString = typedef int|str
  def foo(x: IntOrString):

In this example, the type-checker knows that IntOrString is a typedecl.
It also knows the *value* of "int|str" so the name IntOrString now has two
items associated with it at type-check time:

   # not "real" syntax, but you get the idea...

   namespace["IntOrString"] = (TypeDeclarator, int|str)

With the above information in hand, the type-checker knows what
IntOrString means in the declaration for foo().

The cool benefit is that the runtime semantics are exactly as you would
expect: a typedecl object is created and assigned to IntOrString. That
object is also associated with the "x" argument in the function object
referred to by the name "foo".

There is no "overloading" of namespaces. We are using Python namespaces
just like they should be, and the type-checker doesn't even have to be all
the smart to track this stuff.

To get back to the recursive class problem, consider the following code:

   decl incomplete class Foo
   decl incomplete class Bar

   class Foo:
     decl a: Bar

   class Bar:
     decl b: Foo

The "decl" statements would create an empty class object and store that
into the "current" namespace. There is no need to shove that off into
another namespace. When the "class Foo" comes along, the class object is
updated with the class definition for Foo.

It is conceivable to remove the need for "decl" if you allow "class" and
"def" to omit the ": suite" portion of their grammar:

  class Foo
  class Bar

  class Foo:
    decl a: Bar

  def some_function(x: some_type, y: another_type) -> third_type

  ... lots o' code ...

  def some_function(x, y):

Guido suggested that it may be possible to omit "decl" altogether.
Certainly, it can work for member declarations such as:

  class Foo:
    a: Bar

Anyhow... my point is that a new namespace is not needed. Assuming we want
objects for reflection at runtime, then the above proposal states *how*
those objects are realized at runtime. Further, the type-checker can
easily follow that information and perform the appropriate compile-time

No New Namespaces!  (lather, rinse, repeat)


Greg Stein, http://www.lyra.org/