Objects + Reflection = Open Languages
Brian Foote
University of Illinois at Urbana-Champaign
7 November 1992
Saturday
IMSA '92 Workshop on
Reflection and Metalevel Architectures
Tokyo, Japan
Open Object-Oriented Object-Oriented
Languages
The marriage of
object-oriented programming and design techniques
with reflection promises to dramatically change the way that we
think about, organize, implement, and use
programming languages and systems
Building object-oriented languages out of
first-class objects allows the full power of
object-oriented tools and techniques to be brought to
bear on th language level itself...
A system built of objects can serve as the basis
for an object-oriented framework
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.
Rodriguez/Anibus Reactions
These are extensions.
Is callling them pragma's too timid?
However, were these annotations added
to runtime data structures automatically,
would we consider them extenstions?
Static vs. Dynamic translation?
How incremental could this process be?
How much would a uniform object-oriented
substrate have helped here?
Are explicit annotations a realisitic option in general
for converting sequential programs to concurrent programs?
What is the role of program transformation at the
abstract syntax tree level as a means of opening
up languages?
Possible Metalevel Components
(Potential Metaobjects)
(Things one might reify)
A Metaobject Palette
In no particular order...
Variables/Slots
Selectors/Generic Functions/Keys/Operators
Messages
Evaluators/Processors/Interpreters
Method Dictionaries/Script/Scripts Sets/Role//Containers/Behaviors
Records/Repetoire/Relation/Table/Index
A-List/Association/Pair/Tuple/Entry
Handles/Pointers/Names/Addresses/Locations/References/OOPs
Environments
Continuations
Contexts (Method, Block)
Mailboxes/Message Queues
State Memory/Stores/Storage
Blocks/Closures
Classes
Types
Prototypes/Traits
Signatures/Protocols
Methods (Primitive and otherwise)
Code/Expressions/Parse Trees/Byte Codes/Forms
(Denotations?)
Processes/Threads/Engines
...and last but not least:
Objects
Integers/Floats/Reals/Strings
Arrays/Aggregates/Structures/Collections/Lists
(other primitive objects)
Design Principles
Message Passing at the Bottom
all computation shall be conducted via message passing
Object-Oriented Uniformity and Openness
everything shall be a first class object
(including variables, "code", contexts, oops)
Malleable Self-Representation
computations shall be represented by first class objects
at a semantically interesting level
Extensionality
behavior only shall determine an object's identity
Inheritance is signature composition
at least from an extensional standpoint
State and Behavior
shall be externally indistinguishable
Active Dispatching vs. Passive Lookup
shall be externally indistinguishable
Dynamic vs. Static Scope
That is, name binding, particularly for closures, will be handled by explicit runtime objects.
Imperative Declarations
Declarations are executable imperatives that have a temporal scope. A declaration is a dynamic invocation of a mechanism that enforces the declarations intended consequences.
Stratification
The architecture should be cleanly layered.
The distinction between application dependent and independent
layers will often be one of degree
Factoring
Significant elements of the system (including the interpreter itself)
will be distribubuted across a constellation of objects
Stratification and Factoring can be thought of
a suggesting a distributed vertical and horizontal organization
Necessity is...
A good sign that a programming language
feature is necessary is when a lot of people go to
a good deal of trouble to reinvent it in cumbersome ways
in existing languages
Smalltalk programmers have shown
remarkable ingenuity in getting around the VM barrier...
Encapsulators (Pascoe)
Messick and Beck (Active Variables, Advised Methods.)
Borning (ThingLab)
Randy Smith (ARK)
ACTRA (Thomas)
ACTalk (Briot)
That method dictionary hack from '90 or '91... (Boecker)
C++
Object-orientation in the first place...
...let alone dynamic object-orientation (Cox, Burkhardt)
Tiemann (Wrappers)
Various persistent object schemes (BKS's Poet, Borland's OWL)
Various resource management schemes
The MIP
Choices
Lisp
God knows how many people (re-)invented various
object-oriented and reflective features
Store Models
Could there be more than one?
Why not?
Store polymorphism could be interesting...
Smalltalk calls this level the Object Memory
The OM is responsible for garbage collection
and is the basis for image snapshots...
Instance Models
Smalltalk
Two parts:
An Object Pointer (OOP)
The instance
class pointer
fixed part
indexable part
ABCL/R
state
behavior
evaluation
message queue
Super-Ego
store
repetoire
ensemble
<queue>
Changing the Show
Change the Script
Source transformation
Program generation
Change the Performers
Polymorphic interpreters
Polymorphic scripts
Kabuki MacBeth
Dispatching Models
A number of system elements play a role
Instance
Class
Operator
Other Specializers
Context
Current Evaluator
In Super-Ego, these are part of Ensemble Objects
Ensemble entries
atom$, return$, block$, method$, primitive$
sequence$, collection$
while$, top$, send$, get$, set$
reflect$
atom, method, primitive, block, send
Primitive operators are thought of as cached
Hence, idempotence is exploited to short circuit the tower
Architectural Issues
Structural
Store
Instance
State
Templates
Sharing
Scripts
Computational
Semantics
Dispatching
Variables
Primitives
Closures
Context
Control
Namespace
Animus
Implementation
Is it visible?
Do we embrace it as a white box?
Or pretend its beneath us, Laputan-style?
Or do we subscribe to a layered, translucent architecture?
Frameworks may make it possible to embrace,
rather than ignore, implementation differences...
Consider, for instance, polymorphic code generators...
There is an interesting tension between
object-oriented uniformity and low level visibility
Do you chose one, the other, or both?
A point: Tables beat (even) frameworks.
If you can push all the details into the data
that is good...
The O**2 experience is a drive towards pushing
more complexity (control?) into the data structures...
The Camps
Lisp: Unemcumbered linguistic licensiousness
The linguistic imperialists
C: The pragmatists
laisse faire ... Languages grow unzoned, like Houston
Pascal: the ministry of computing
Linguistic totalitarians...
Ways of Dealing with Regress
Circularity
Smalltalk class/metaclass relationship
Lazy Reification
3-KRS Metaobjects
Induction
Base case differs from other
Some language designs are Laputan,
and don't ground out at all
Some are built on rigid, immovable foundations
Some are like the surface of Jupiter...
...with language and implementation objects coexisting...
Conclusion:
Reflection is a School of Architecture
Objects
make it possible to treat languages themselvesas dynamic, first-class, evolving parts of a system,
that benefit themselvles from the power of object-oriented techniques
like framework construction
Building languages out of dynamic, first-class objects encourages
a highly reflective approach to architecture
Objects can serve as the basis for a more flexible underlying
computational model
A well chosen set of objects
can permit a language to encompass a variety
of different programming models and features
Object-oriented metalevel architectures can provide
a structural redoubt as existing system organizations
are rethought...
Domo Arigato