Reflection and Context



        Marcus Denker
        marcus.denker@inria.fr
        http://rmod.lille.inria.fr




© Marcus Denker
Roadmap




> I. Sub-Method Structural Reflection
> II. Partial Behavioral Reflection
> III. Meta Context




© Marcus Denker
Smalltalk



>    Smalltalk has support for reflection

>    Structural reflection
     — Classes / methods are objects
     — Can be changed at runtime

>    Behavioral reflection
     — Current execution reified (thisContext)
     — #doesNotUnderstand / MethodWrappers



© Marcus Denker
Can we do better?


>    Structural Reflection stops at method level
     — Bytecode in the CompiledMethod: Numbers
     — Text: Just a String, needs to be compiled

>    Behavior hard coded in the Virtual Machine
     — Message Sending
     — Variable Access

>    Both structural and behavioral reflection is limited
     — We should do better!



© Marcus Denker
Structural Reflection



>    Structure modeled as objects

     — e.g. Classes, methods
     — Causally connected

>    Uses:
     — Development environments
     — Language extensions and experiments




© Marcus Denker
Methods and Reflection



>    Method are Objects
     — e.g in Smalltalk


>    No high-level model for sub-method elements
     — Message sends
     — Assignments
     — Variable access


>    Structural reflection stops at the granularity of methods


© Marcus Denker
Sub-Method Reflection




>    Many tools work on sub method level
     — Profiler, Refactoring Tool, Debugger, Type Checker

>    Communication between tools needed
     — Example: Code coverage

>    All tools use different representations
     — Tools are harder to build
     — Communication not possible



© Marcus Denker
Existing Method Representations




>    Existing representations for Methods

     — Text

     — Bytecode

     — AST




© Marcus Denker
Requirements


>    Causal Connection

>    Abstraction Level

>    Extensibility

>    Persistency

>    Size and Performance


© Marcus Denker
Text




>    Low level abstraction
     — String of characters


>    Not causally connected
     — Need to call compiler




© Marcus Denker
Bytecode



>    Low level abstraction
     — Array of Integers


>    Missing extensibility
     — e.g. for tools

>    Mix of base- and meta-level code
     — Problems with synthesized code when changing code
     — Examples: AOP point-cut residues, reflection hooks



© Marcus Denker
Abstract Syntax Tree



>    Not causally connected
     — Need to call compiler


>    Not extensible
     — Fixed set of codes, no way to store meta data

>    Not persistent
     — Generated by compiler from text, never stored




© Marcus Denker
Solution: Reflective Methods


> Annotated, persistent AST
> Bytecode generated on demand and cached


    :ReflectiveMethod                                           :CompiledMethod
                     annotation               compiledMethod

                                                               #(12 13 45 38 98 128
                     annotation
                                  reflectiveMethod              84 72 42 77 22 28 59
                                                                 32 7 49 51 87 64)




             Tools                                                     VM



© Marcus Denker
Persephone



>    Implementation of Reflective Methods for Squeak 3.9

>    Smalltalk compiler generates Reflective Methods
     — Translated to bytecode on demand

>    Open Compiler: Plugins
     — Called before code generation
     — Transform a copy of the AST




© Marcus Denker
Requirements revisited


>    Abstraction Level OK

>    Causal Connection OK

>    Extensibility OK

>    Persistency OK

>    Size and Performance OK


© Marcus Denker
Annotations


>    Source visible annotations
     — extended Smalltalk syntax

                  (9 raisedTo: 10000) <:evaluateAtCompiletime:>

>    Source invisible annotations
     — Reflective API
     — Can reference any object

> Every node can be annotated
> Semantics: Compiler Plugins


© Marcus Denker
Example: Pluggable Type-System


>    Example for textual annotations


      bitFromBoolean: aBoolean <:type: Boolean :>
      ^ (aBoolean ifTrue: [1] ifFalse: [0]) <:type: Integer :>




> Optional, pluggable type-system
> Types stored as annotations in the Reflective Methods



© Marcus Denker
Memory


                    number of classes   memory


Squeak 3.9          2040                15.7 MB

Persephone          2224                20 MB
no reflective
methods

Persephone          2224                123 MB
reflective methods

© Marcus Denker
Roadmap




> I. Sub-Method Structural Reflection
> II. Partial Behavioral Reflection
> III. Meta Context




© Marcus Denker
Behavioral Reflection


>    Reflect on the execution
     — method execution
     — message sending, variable access

>    In Smalltalk
     — No model of execution below method body
     — message sending / variable access hard coded by VM
     — #doesNotUnderstand / MethodWrappers

>    Reflective capabilities of Smalltalk should be improved!


© Marcus Denker
MetaclassTalk


>    Extends the Smalltalk metaclass model
     — Similar to CLOS MOP


>    Metaclass defines
     — message lookup
     — access to instance variables

>    Problems:
     — Reflection only controllable at class boundaries
     — No fine-grained selection (e.g. single operations)
     — Protocol between base and meta level is fixed


© Marcus Denker
Reflex: Partial Behavioral Reflection



> Hooksets: collection of operation occurrences
> Links
     — Bind hooksets to meta-objects
     — Define protocol between base and meta
                                                            metaobject
>    Goals
     — Highly selective reification     links                activation
                                                            condition
     — Flexible meta-level engineering
           –      Protocol specification
                                                             hookset
           –      Cross-cutting hooksets


                                               Tanter, OOPSLA03
© Marcus Denker
Example: Profiler



>    Operation:
     — Method execution (around)


>    Hookset:
     — All execution operations in a package

                                               metaobject
>    Meta-object:
     — A profiling tool              links      activation
                                               condition

                                                hookset

© Marcus Denker
Reflex for Squeak




>    Partial Behavioral Reflection pioneered in Java
     — Code transformation at load time
     — Not unanticipated (it’s Java...)



>    Geppetto: Partial Behavioral Reflection for Smalltalk
     — For Squeak 3.9 with Bytecode transformation




© Marcus Denker
Problems


>    Annotation performance
     — Decompile bytecode


>    Execution performance
     — Preambles for stack manipulation

>    Low-level representation
     — ifTrue:ifFalse:
     — Blocks
     — Global variables



© Marcus Denker
Links as Annotations


>    Links can be annotations on the AST

            Method
                                           Meta
                          Link




© Marcus Denker
Behavioral Reflection: Flexible


                                      meta-object


        links
                                      activation
                                      condition
                                      source code
                                         (AST)


                  >   Very Flexible

© Marcus Denker
Behavioral Reflection: CLOS


                                              meta-object


        links
                                              activation
                                              condition
                                              source code
                                                 (AST)


                  >   Meta-class MOP (CLOS)

© Marcus Denker
Behavioral Reflection: AOP


                                meta-object


        links
                                activation
                                condition
                                source code
                                   (AST)


                  >   Aspects


© Marcus Denker
Behavioral Reflection: Tracer


                               tracer metaobject


       link


                                  source code
                                     (AST)



                  >   Tracer

© Marcus Denker
Properties



>    Very fast annotations
     — No decompile!

>    On-the-fly code generation
     — Only code executed gets generated

>    Generated code is fast
     — Better then working on bytecode level




© Marcus Denker
Demo




>    Show Bounce Demo




© Marcus Denker
Reflectivity




>    Prototype implementation in Squeak

     — Sub-Method Structure
     — Partial Behavioral Reflection

>    Download:

    http:/scg.unibe.ch/Research/Reflectivity



© Marcus Denker
Reflectivity: Pharo




>    Not yet.... but soon.

     — Slowly revisiting all research stuff
     — Now we can do it for real!
           –      Engineering vs. Research...




© Marcus Denker
Roadmap




> I. Sub-Method Structural Reflection
> II. Partial Behavioral Reflection
> III. Meta Context




© Marcus Denker
Behavioral Reflection: Flexible


                                      meta-object


        links
                                      activation
                                      condition
                                      source code
                                         (AST)


                  >   Letʼs use it!

© Marcus Denker
Problem: Recursion




>    Behavioral reflection cannot be applied to the whole system

     — System classes
     — Meta-objects




© Marcus Denker
Example: Beeper



 >    Call the Beeper from OrderedCollection>>#add

beepLink := Link new metaObject: Beeper.
beepLink selector: #beep.




(OrderedCollection>>#add:) methodNode link: beepLink.




© Marcus Denker
Meta-object Call Recursion


       Base Level       Meta Object   Meta Object


                  #add: send
                               #beep send
                                 #add: send
                                              #beep send
                                                #add: send

                                                Infinite recursion




© Marcus Denker
Ad-hoc Solutions




>    Code duplication



>    Adding special tests




© Marcus Denker
Tower of Interpreters




>    Smith, 1982




© Marcus Denker
The Real Problem




                  Representing Meta-Level Execution




© Marcus Denker
The Meta-Context



                    Base Level   Meta Level


                                        MetaContext activation



>    Link enables
     MetaContext


                                        MetaContext deactivation




© Marcus Denker
Context-aware Links



                         Base Level   Meta Level




                                              Stop meta-level call

>    Disable call when
     already on the
     meta-level




© Marcus Denker
MetaContext




>   Recursion problem solved                      meta-object
                                           meta
                                links
                               level 0

                                                    operation
                                         base




© Marcus Denker
MetaContext



                                                  metameta-
                                                   object
                                              meta-2
                               link
                             level 1

>    Meta-level analysis:                         meta-object
                                         meta
     — Trace the tracer      links
                            level 0

                                                       operation
                                       base




© Marcus Denker
MetaContext




>    Recursion problem

>    Missing representation of meta-level execution

>    Meta-context
     — Solves the recursion problem
     — Enables meta-level analysis




© Marcus Denker
transaction
                        set-slot
                      insert-slot
                     remove-slot
                    define-method
                   remove-method
                  declare-delegation

                      system
                        set-slot
                      insert-slot
                     remove-slot
                    define-method
                   remove-method
                  declare-delegation

© Marcus Denker
non-destructive operations also need to see the
               objects belonging to the current transaction


            (empty? inventory )                  (empty? inventory’ )


                                       alter-object


      (with-context @transaction
        (defmethod send (selector arguments)
           (let ((log (log (host-context))))
              (do-slots (arguments argument index)
                  (setf ($slot-value arguments index) (gethash argument log argument))))
                  (resend)))
                                            case study is not implemented
                                          purely on top of the object model
- System must make sure that any method invoked in transaction context sees the
     © Marcus Denker
transactional versions of modified objects, rather than the original versions.
Rethinking Reflection




>    Meta change “shows through”
     — Introspection shows implementation
     — Recursion and confusion of meta levels

>    Reflective change is always global
     — Any change is visible to the whole system
     — No way to batch multiple changes into one atomic operation




© Marcus Denker
Next steps




>    Generalize context model:
     — Beyond context as control flow.


>    Virtual machine support... to make it practical

>    What is the next reflective language kernel?



© Marcus Denker
A lot of open questions...




     thats why it is
                  Research...

                      ?????
© Marcus Denker
Questions

                  ?
© Marcus Denker
License

>    http://creativecommons.org/licenses/by-sa/2.5/



                                           Attribution-ShareAlike 2.5
     You are free:
     • to copy, distribute, display, and perform the work
     • to make derivative works
     • to make commercial use of the work

     Under the following conditions:

              Attribution. You must attribute the work in the manner specified by the author or licensor.

     "
              Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting
              work only under a license identical to this one.

     • For any reuse or distribution, you must make clear to others the license terms of this work.
     • Any of these conditions can be waived if you get permission from the copyright holder.

                     Your fair use and other rights are in no way affected by the above.
© Marcus Denker

Reflection and Context

  • 1.
    Reflection and Context Marcus Denker marcus.denker@inria.fr http://rmod.lille.inria.fr © Marcus Denker
  • 2.
    Roadmap > I. Sub-MethodStructural Reflection > II. Partial Behavioral Reflection > III. Meta Context © Marcus Denker
  • 3.
    Smalltalk > Smalltalk has support for reflection > Structural reflection — Classes / methods are objects — Can be changed at runtime > Behavioral reflection — Current execution reified (thisContext) — #doesNotUnderstand / MethodWrappers © Marcus Denker
  • 4.
    Can we dobetter? > Structural Reflection stops at method level — Bytecode in the CompiledMethod: Numbers — Text: Just a String, needs to be compiled > Behavior hard coded in the Virtual Machine — Message Sending — Variable Access > Both structural and behavioral reflection is limited — We should do better! © Marcus Denker
  • 5.
    Structural Reflection > Structure modeled as objects — e.g. Classes, methods — Causally connected > Uses: — Development environments — Language extensions and experiments © Marcus Denker
  • 6.
    Methods and Reflection > Method are Objects — e.g in Smalltalk > No high-level model for sub-method elements — Message sends — Assignments — Variable access > Structural reflection stops at the granularity of methods © Marcus Denker
  • 7.
    Sub-Method Reflection > Many tools work on sub method level — Profiler, Refactoring Tool, Debugger, Type Checker > Communication between tools needed — Example: Code coverage > All tools use different representations — Tools are harder to build — Communication not possible © Marcus Denker
  • 8.
    Existing Method Representations > Existing representations for Methods — Text — Bytecode — AST © Marcus Denker
  • 9.
    Requirements > Causal Connection > Abstraction Level > Extensibility > Persistency > Size and Performance © Marcus Denker
  • 10.
    Text > Low level abstraction — String of characters > Not causally connected — Need to call compiler © Marcus Denker
  • 11.
    Bytecode > Low level abstraction — Array of Integers > Missing extensibility — e.g. for tools > Mix of base- and meta-level code — Problems with synthesized code when changing code — Examples: AOP point-cut residues, reflection hooks © Marcus Denker
  • 12.
    Abstract Syntax Tree > Not causally connected — Need to call compiler > Not extensible — Fixed set of codes, no way to store meta data > Not persistent — Generated by compiler from text, never stored © Marcus Denker
  • 13.
    Solution: Reflective Methods >Annotated, persistent AST > Bytecode generated on demand and cached :ReflectiveMethod :CompiledMethod annotation compiledMethod #(12 13 45 38 98 128 annotation reflectiveMethod 84 72 42 77 22 28 59 32 7 49 51 87 64) Tools VM © Marcus Denker
  • 14.
    Persephone > Implementation of Reflective Methods for Squeak 3.9 > Smalltalk compiler generates Reflective Methods — Translated to bytecode on demand > Open Compiler: Plugins — Called before code generation — Transform a copy of the AST © Marcus Denker
  • 15.
    Requirements revisited > Abstraction Level OK > Causal Connection OK > Extensibility OK > Persistency OK > Size and Performance OK © Marcus Denker
  • 16.
    Annotations > Source visible annotations — extended Smalltalk syntax (9 raisedTo: 10000) <:evaluateAtCompiletime:> > Source invisible annotations — Reflective API — Can reference any object > Every node can be annotated > Semantics: Compiler Plugins © Marcus Denker
  • 17.
    Example: Pluggable Type-System > Example for textual annotations bitFromBoolean: aBoolean <:type: Boolean :> ^ (aBoolean ifTrue: [1] ifFalse: [0]) <:type: Integer :> > Optional, pluggable type-system > Types stored as annotations in the Reflective Methods © Marcus Denker
  • 18.
    Memory number of classes memory Squeak 3.9 2040 15.7 MB Persephone 2224 20 MB no reflective methods Persephone 2224 123 MB reflective methods © Marcus Denker
  • 19.
    Roadmap > I. Sub-MethodStructural Reflection > II. Partial Behavioral Reflection > III. Meta Context © Marcus Denker
  • 20.
    Behavioral Reflection > Reflect on the execution — method execution — message sending, variable access > In Smalltalk — No model of execution below method body — message sending / variable access hard coded by VM — #doesNotUnderstand / MethodWrappers > Reflective capabilities of Smalltalk should be improved! © Marcus Denker
  • 21.
    MetaclassTalk > Extends the Smalltalk metaclass model — Similar to CLOS MOP > Metaclass defines — message lookup — access to instance variables > Problems: — Reflection only controllable at class boundaries — No fine-grained selection (e.g. single operations) — Protocol between base and meta level is fixed © Marcus Denker
  • 22.
    Reflex: Partial BehavioralReflection > Hooksets: collection of operation occurrences > Links — Bind hooksets to meta-objects — Define protocol between base and meta metaobject > Goals — Highly selective reification links activation condition — Flexible meta-level engineering – Protocol specification hookset – Cross-cutting hooksets Tanter, OOPSLA03 © Marcus Denker
  • 23.
    Example: Profiler > Operation: — Method execution (around) > Hookset: — All execution operations in a package metaobject > Meta-object: — A profiling tool links activation condition hookset © Marcus Denker
  • 24.
    Reflex for Squeak > Partial Behavioral Reflection pioneered in Java — Code transformation at load time — Not unanticipated (it’s Java...) > Geppetto: Partial Behavioral Reflection for Smalltalk — For Squeak 3.9 with Bytecode transformation © Marcus Denker
  • 25.
    Problems > Annotation performance — Decompile bytecode > Execution performance — Preambles for stack manipulation > Low-level representation — ifTrue:ifFalse: — Blocks — Global variables © Marcus Denker
  • 26.
    Links as Annotations > Links can be annotations on the AST Method Meta Link © Marcus Denker
  • 27.
    Behavioral Reflection: Flexible meta-object links activation condition source code (AST) > Very Flexible © Marcus Denker
  • 28.
    Behavioral Reflection: CLOS meta-object links activation condition source code (AST) > Meta-class MOP (CLOS) © Marcus Denker
  • 29.
    Behavioral Reflection: AOP meta-object links activation condition source code (AST) > Aspects © Marcus Denker
  • 30.
    Behavioral Reflection: Tracer tracer metaobject link source code (AST) > Tracer © Marcus Denker
  • 31.
    Properties > Very fast annotations — No decompile! > On-the-fly code generation — Only code executed gets generated > Generated code is fast — Better then working on bytecode level © Marcus Denker
  • 32.
    Demo > Show Bounce Demo © Marcus Denker
  • 33.
    Reflectivity > Prototype implementation in Squeak — Sub-Method Structure — Partial Behavioral Reflection > Download: http:/scg.unibe.ch/Research/Reflectivity © Marcus Denker
  • 34.
    Reflectivity: Pharo > Not yet.... but soon. — Slowly revisiting all research stuff — Now we can do it for real! – Engineering vs. Research... © Marcus Denker
  • 35.
    Roadmap > I. Sub-MethodStructural Reflection > II. Partial Behavioral Reflection > III. Meta Context © Marcus Denker
  • 36.
    Behavioral Reflection: Flexible meta-object links activation condition source code (AST) > Letʼs use it! © Marcus Denker
  • 37.
    Problem: Recursion > Behavioral reflection cannot be applied to the whole system — System classes — Meta-objects © Marcus Denker
  • 38.
    Example: Beeper > Call the Beeper from OrderedCollection>>#add beepLink := Link new metaObject: Beeper. beepLink selector: #beep. (OrderedCollection>>#add:) methodNode link: beepLink. © Marcus Denker
  • 39.
    Meta-object Call Recursion Base Level Meta Object Meta Object #add: send #beep send #add: send #beep send #add: send Infinite recursion © Marcus Denker
  • 40.
    Ad-hoc Solutions > Code duplication > Adding special tests © Marcus Denker
  • 41.
    Tower of Interpreters > Smith, 1982 © Marcus Denker
  • 42.
    The Real Problem Representing Meta-Level Execution © Marcus Denker
  • 43.
    The Meta-Context Base Level Meta Level MetaContext activation > Link enables MetaContext MetaContext deactivation © Marcus Denker
  • 44.
    Context-aware Links Base Level Meta Level Stop meta-level call > Disable call when already on the meta-level © Marcus Denker
  • 45.
    MetaContext > Recursion problem solved meta-object meta links level 0 operation base © Marcus Denker
  • 46.
    MetaContext metameta- object meta-2 link level 1 > Meta-level analysis: meta-object meta — Trace the tracer links level 0 operation base © Marcus Denker
  • 47.
    MetaContext > Recursion problem > Missing representation of meta-level execution > Meta-context — Solves the recursion problem — Enables meta-level analysis © Marcus Denker
  • 48.
    transaction set-slot insert-slot remove-slot define-method remove-method declare-delegation system set-slot insert-slot remove-slot define-method remove-method declare-delegation © Marcus Denker
  • 49.
    non-destructive operations alsoneed to see the objects belonging to the current transaction (empty? inventory ) (empty? inventory’ ) alter-object (with-context @transaction (defmethod send (selector arguments) (let ((log (log (host-context)))) (do-slots (arguments argument index) (setf ($slot-value arguments index) (gethash argument log argument)))) (resend))) case study is not implemented purely on top of the object model - System must make sure that any method invoked in transaction context sees the © Marcus Denker transactional versions of modified objects, rather than the original versions.
  • 50.
    Rethinking Reflection > Meta change “shows through” — Introspection shows implementation — Recursion and confusion of meta levels > Reflective change is always global — Any change is visible to the whole system — No way to batch multiple changes into one atomic operation © Marcus Denker
  • 51.
    Next steps > Generalize context model: — Beyond context as control flow. > Virtual machine support... to make it practical > What is the next reflective language kernel? © Marcus Denker
  • 52.
    A lot ofopen questions... thats why it is Research... ????? © Marcus Denker
  • 53.
    Questions ? © Marcus Denker
  • 54.
    License > http://creativecommons.org/licenses/by-sa/2.5/ Attribution-ShareAlike 2.5 You are free: • to copy, distribute, display, and perform the work • to make derivative works • to make commercial use of the work Under the following conditions: Attribution. You must attribute the work in the manner specified by the author or licensor. " Share Alike. If you alter, transform, or build upon this work, you may distribute the resulting work only under a license identical to this one. • For any reuse or distribution, you must make clear to others the license terms of this work. • Any of these conditions can be waived if you get permission from the copyright holder. Your fair use and other rights are in no way affected by the above. © Marcus Denker