On May 20, 2013, at 4:44 PM, Paul Davidowitz <[email protected]> wrote:

> I just started following this Dev mailing list, and I saw that 'AST
> Everywhere' and 'Reflectivity' were mentioned as very promising (I
> already know about Slots).
> Can someone in a nutshell please describe these developments? Thanks,


Right now, the compiler uses it's own AST, Syntax highlighting uses a very 
minimal
token stream (and it's own parser), the refactoring engine has one, too.
And then there is Bytecode which is used by the Debugger, for example.

As a first step we plan to use the Refactoring AST for everything
(Compiler, Refactoring, Syntax highlighting )

There is a AST Interpreter useful for experimenting, maybe in the future the
debugger can use this instead of relying on byte code. (but this is for far 
later).

Now with the AST already there, all the tools can rely on it  (Gisela Decuzzi 
is working on this:)

 Navigation. When selecting code or navigating expressions, the editor can do 
better then just using word boundaries:

        http://www.youtube.com/watch?feature=player_embedded&v=pFLyzEI0jmE

Suggestions. When we want to do an actions on a selection, why not just show 
those that make sense? 
Why do I need to carefully highlight a  selector to browser implementors? The 
AST model can do much better!

        http://www.youtube.com/watch?feature=player_embedded&v=WmNKbewOXkE

Reflectivity
=========

Behavioral Reflection is quite interesting.. but there is not that much in 
Smalltalk by default to deeply hook
into how code is executed.

There are MethodWrappers (to be loaded as an additional tool). There is an 
in-image Bytecode Interpreter
(hidden in ContextPart).

People started to want more. "In this class, all Ivar accesses should be 
treated differently". Things like that.

So people tried to improve Smalltalk in the past. E.g. adding a CLOS Style MOP 
(Noury did that with MetaClassTalk).
But it is difficult to do it in a way that it does not get very slow (not 
introduce an overhead for every operation).

And in the end, the MetaClass style MOP is quite limiting: All change of 
semantic is done *per Class*. Already
quite nice, but limiting...

So in 2003 Eric Tanter finished his PhD and he invented this:

Eric Tanter , Jacques Noye , Denis Caromel , Pierre Cointe:
Partial Behavioral Reflection: Spatial and Temporal Selection of Reification 
        http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.58.8141

And as fate wanted, he was visiting in Bern the week before Christmas 2004, 
which gave me enough
time to implement a Bytecode Transformation thing in the style of  Javassist  
that this stuff was using.
But it was cumbersome… so at some point I thought "Bytecode Sucks", and took 
the Reflex model but
transported it on the AST Level.
        http://scg.unibe.ch/archive/phd/denker-phd.pdf

So… what this means is that the AST can be annotated with so-called "meta 
links". When you set a link,
the system behind the scene makes sure that new code is generated on the next 
call. 

One way to think about this is that these links are just extremely generalized 
break-points. So you can 
set a link that says "before this node, send #halt to Halt". 
But they are much more powerful:
        -> selector
        -> metaObject
        -> what to pass as parameters
        -> a condition
        -> is it #before, #after, #around?

can be set as wanted.

So after some thinking one realizes that this subsumes
        -> BreakPoints
        -> MethodWrappers
        -> CLOS style MOP where the class is the meta object
        -> AOP style crosscutting. (Aspects is just a pattern on top)
        -> ….

e.g. Code Coverage:
------------------------------

-  add a #markExecuted to RBProgramNode.
- install this link an all the nodes that you are interested in:

link := GPLink new metaObject: #node; selector: #markExecuted.
(markExecuted can even deinstall the link)

CLOS style MOP
----------------------
(for sends:)

link := GPLink new 
        metaObject: #class; 
        selector: #send:to:with:;
        arguments: #(selector receiver arguments)
        control: #instead.

Add this link to all send nodes in your class after the compiler compiles 
something, and
your class hierarchy has a CLOS style where every send is indirected through a 
method
in the class side.

 Javassist  (or Bytesurgeon) style "execute this code before this operation"
------------------------

link := GPLink new
        metaObject: [:object | object color = Color red ifTrue: [Beeper beep]]; 
        selector: #value:;
     arguments: #(object).

The nice thing is that these links are highly dynamic: they can be installed 
quickly, remove
themselves, propagate themselves over the AST at runtime even.

        Marcus

Reply via email to