An Object-Oriented Framework

for

Reflective Metalevel Architectures

 

Brian Foote

University of Illinois at Urbana-Champaign

 

17 November 1994

Thursday

 

A Dissertation Proposal


Presentation Overview

 

An Object-Oriented Framework

for

Reflective Metalevel Architectures

 

What problems could we solve?

Why build languages out of objects?

What do these terms mean?

What have I done?

What do I want to do?

How do I plan to do it?

 

Additional Questions at your discretion


Constraint Support

 

Declare constraints between variables that

are enforced automatically

 

Constraints change the meaning of

variable access

and

variable assignment

 

First-class variables can permit

dynamic constraint attachment


Automatic Future Generation

 

Built into ABCL/1 (not ABCL/R)

 

Reflective Facilities in Smalltalk-80

 

Implicit dynamic per-method future generation

 

Superego send$ and send objects would support this

 

Every send from a given method creates a future

 

Accessing a future causes synchronization


Distributed Object Support

 

Distributed marshalling is an area

where dynamic languages have an advantage

 

Similar issues arise with with request brokers

and persistence

 

The importance of client/server database applications

underscores this need

 

Requires first-class

dispatching and state handling mechanisms


Exception Support

 

Runtime access to control or continuation objects

allows runtime exception handling

 

Backtracking

Error Handling

 

Access to runtime contexts

can support this


Dispatching Mechanisms

 

No single language subsumes

Smalltalk-80

CLOS

(ABCL/R)

 

Smalltalk’s venerable doesNotUnderstand:

   is proven, but second-class

 

CLOS uses discriminating functions associated with

   each generic function

   to make multimethods and method-combination easy

 

ABCL/R allows blocking and non-blocking sends.

 

A unified scheme will use all arguments, including selectors,

as well as the context and machine objects


Sharing Mechanisms

 

Static Inheritance

is the only sharing mechanism

supported by CLOS and Smalltalk

 

Smalltalk supports single inheritance

CLOS supports multiple inheritance

 

Forwarding, delegation and composition

must be constructed in an ad-hoc fashion

 

Inheritance is static/per-class

Many interesting relationships are dynamic/per-instance

 

Container/Component Aggregate/Element

Dynamic Coalitions

Multiple Views/Subjectivity

Signature or Protocol objects will help

 

Replace elaborate preprocessors

by building and reusing such mechanisms directly


Why is this interesting?

 

Existing languages are too rigid to evolve gracefully

 

Hence,

New requirements require new languages

 

Just as objects are good for building programs

objects are good for building  languages

 

 

 

An object-oriented language with a reflective

metalevel architecture is easy to extend.

Existing metaobjects may be selectively specialized

and dynamically reintroduced into a running system

New features are added by building a set of objects

to support them

Changes can be localized, or pervasize


What do these terms mean?

 

A programming language with

an object-oriented metalevel architecture

is one in which programs are

constructed out of first-class objects

 

Metalevel objects, or metaobjects are objects that

define, implement, or otherwise support the

execution of application, or base level programs

 

A reflective object-oriented language

allows a running program to look at or change

the (meta-)objects out of which it is built

 

An object-oriented framework is a set of abstract classes

and components that together embody an abstract design

or generic solution for a range of potential application

requirements


What have we done?

 

Frameworks

 

Reflective Facilities in Smalltalk-80

 

Ports for PCL/CLOS and ABCL/R

 

Id

Ego

Superego

 

<The Babel Framework>


Reflective Facilities in Smalltalk-80

 

Strengths

 

Cataloged ST80 Reflective Facilities

Enumerated missing facilities

More natural dispatching model

Future

Delegation to Components

Views, Dynamic Fields

Protection, Prioritized Forwarding, Protocol Adaptor

Addressed Efficiency

Speculated about new sharing mechanisms

Possible implementations

Clever virtual machine modifications

 

Flaws

 

Depends on inefficient doesNotUnderstand: hack

Inadequate descriptions of delegation mechanisms

Tardy follow through

Clever virtual machine modifications


Id and Ego

 

Id

A simple subset of Self in CLOS (PCL)

 

Ego

Had a metalevel architecture

Was built in Common Lisp

 


Superego

 

Strengths

 

Simple, based on Self

Scripts, Ensembles, Performers

Scenes, Performances

Policy independent dispatch

Dared to aspire to uniformity

Reflective blocks

It worked

 

Flaws

 

Awkward syntax

Too SELF-centered

Incompletely reflective

Incompletely metacircular

Obsessed with uniformity

Lacked symbiosis

Hashed Instances with Indexable parts

Grotesquely Slow


Superego Ensembles

 

On one hand, we can change the interpreter incrementally

 

On the other hand, we can make many changes

atomically


What do I Want to do?

 

Find a set of metaobjects that provide:

 

Unified Dispatching Mechanisms

Flexible Sharing Mechanisms

Automatic Future Generation

Constraint Support

Distributed Object Support

Exception Support


How do I Plan to do this?

 

Construct an Object-Oriented Framework

 

Seed the Framework using Superego

 

Let the requirements we’ve

discussed drive the evolution of the framework

 

<-> Prototype <-> Explore <-> Consolidate <->

 

Babel Framework

 

Will be built atop or into VisualWorks 2.0

 


Metalevel Concerns:  A Comparision

 


 Contributions

 

Cataloged the Reflective Facilities in Smalltalk

Identified missing facilities

Added additional facilities, including class: and dispatch

Demonstrated Futures and Delegation support

 

Superego explored novel program and activation structures

including Ensembles

 

More universal dispatching mechanisms

More dynamic, powerful, and customizable sharing

More flexible runtime control architectures

More natural integration of contraints and distributed objects

 

Nature of and relationships among

languages, frameworks, reflection, and evolution

 

Demonstration of the power and flexibility

of dynamic, first-class objects

and open object-oriented architectures


Thesis

 

Just as objects are good for building programs

they are good for building languages

 

Reflection can be thought of simply as an

aggressively open school of object-oriented architecture

 

If we had a good object-oriented framework for languages

we wouldn’t need so many new languages

 

Such a framework should strive to cast

significant linguistic elements as first-class dynamic objects

 

The evolution of such a framework

be driven by real requirements

 

The challenge is finding the

right architecture

 


Ways of Dealing with Regress

 

Circularity

Smalltalk class/metaclass relationship

 

Lazy Reification

3-KRS Metaobjects, Smalltalk Contexts

 

Induction

Base case differs from others

 


What is SELF?

 

Classless Prototype-based

Dynamically Typed

Construction via Cloning

Smalltalk Inspired

Pure

Simple

Efficient

 

Reflection done using mirrors


What Objects is Smalltalk Built Of?

 

Object

Behavior

ClassDescription

Class

Metaclass

 

Method

MethodDictionary

CompiledMethod

ByteArray

 

Context

MethodContext/BlockContext

Message

 

Process

ProcessScheduler

Semaphore

SharedQueue

Compiler


What Objects is CLOS Built Of?

 

T

| STANDARD-OBJECT

| | METHOD-COMBINATION

| | | STANDARD-METHOD-COMBINATION

| | | | LONG-METHOD-COMBINATION

| | | | SHORT-METHOD-COMBINATION

| | METAOBJECT

| | | GENERIC-FUNCTION

| | | | STANDARD-GENERIC-FUNCTION

| | | METHOD

| | | | TRACED-METHOD

| | | | STANDARD-METHOD

| | | | | STANDARD-ACCESSOR-METHOD

| | | | | | STANDARD-WRITER-METHOD

| | | | | | STANDARD-READER-METHOD

| | | SLOT-DEFINITION

| | | | STANDARD-SLOT-DEFINITION

| | | | | STANDARD-EFFECTIVE-SLOT-DEFINITION

| | | | | STANDARD-DIRECT-SLOT-DEFINITION

| | | | EFFECTIVE-SLOT-DEFINITION

| | | | | STANDARD-EFFECTIVE-SLOT-DEFINITION

| | | | DIRECT-SLOT-DEFINITION

| | | | | STANDARD-DIRECT-SLOT-DEFINITION

| | | SPECIALIZER

| | | | EQL-SPECIALIZER

| | | | CLASS

| | | | | PCL-CLASS

| | | | | | BUILT-IN-CLASS

| | | | | | FORWARD-REFERENCED-CLASS

| | | | | | STD-CLASS

| | | | | | | FUNCALLABLE-STANDARD-CLASS

| | | | | | | STANDARD-CLASS

May Day PCL Hierarchy


What Does Superego Code look like?

 

Integer       0, 1, ,2, -99, etc.

Selector      dog, cat, +

Symbol        :dog, :cat

Boolean       (true, false)

 

(collection$ 1 2 3 4 5)

 

(send$ + 2 2) ;Send + 2 to 2...

 

(sequence$

     (send$ + 2 2)

     (send$ * 4 4)

     99)  ;Returns 99

 

((+ 2 2)(* 4 4) 99) ;Short form

 

(send$ a)      ;Send to current scene

(a)           ;Short form

 

;;; Send <- to set slot a in object x to 4...

(<- (x) a (+ 2 2))


More Superego Code

 

(while$       ;While a<b, increment b...

     (> (a) (b))

     (<~ b (+ (b) 1))) ;<~ is assign in current scene

 

(method$ ;Create a method to double n...

     (collection$ n)

     (collection$)

     (* 2 (n)))

 

(<-       ;Enter double in integer proto’s double slot

     (integer)

     double

     (method$ (n) () (* 2 (n))))

 

(double 3)

 

(block$ (n) () (print (n)))


Superego Primitives

 

 

(<-       ;End plus-primitive in integer’s + slot

     (integer)

     +

     (primitive$ (self addend) ()

          #'plus-primitive)

 

;;;

;;; plus-primitive --

;;;               Add two Superego-integers...

;;;

(defun plus-primitive (chi self addend)

  (provide-superego-integer

            (+

                  (value self)

                  (value addend))))


What Objects is Superego Built Of?

 

Kernel Objects

 

instance*

method, primitive

block,send

 

scene, performance

environment

 

Atoms

 

Integer, Symbol

Selector, Boolean

 

Scripts

 

Send, Sequence, Collection, While

Method, Primitive

Block, Return

Reflect


What about efficiency?

 

Don’t ask was the answer with Superego

 

RFS80 discussed dispatch caching

 

Self customization and inlining

 

Intelligent objects can retain compilation assumptions

 

Dynamic optimization

 

No play-No Pay is desirable


Architectural Roles

 

Structural

Store

Instance

State

Templates

Sharing

Scripts

 

Computational

Semantics

Dispatching

Variables

Primitives

Closures

Context

Control

Namespace

Animus


Issues

 

Commitment

Mutability

Extensibility

Uniformity

Regress

Openness

Efficiency

Symbiosis

Concurrency

Pervasiveness

Insularity

Selectivity

Incrementality

Separation/Decoupling/Factoring/Layering

Transience

Metamorphosis


Thank You Very Much

for your time and interest