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, -Paul
On May 20, 2013, at 4:43 PM, Paul Davidowitz <pdavidow@fastmail.fm> 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).
First the idea is that when you browse and navigate code we now use AST to support the text analysis so we can really know where we are. For example for senders and implementors perform: #foo: with: when the caret in on perform: then we are on the node and get the selector: perform:with: We do not parse the string to try to guess and get confused with foo:. Reflectivity is the work of marcus on a reflection model. We want to rethink the absence of design of the Smalltalk MOP. Stef
Can someone in a nutshell please describe these developments? Thanks, -Paul
On May 20, 2013, at 4:44 PM, Paul Davidowitz <pdavidow@fastmail.fm> 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
This is _very_ interesting stuff, looking forward to it. On 20 May 2013, at 17:57, Marcus Denker <marcus.denker@inria.fr> wrote:
On May 20, 2013, at 4:44 PM, Paul Davidowitz <pdavidow@fastmail.fm> 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
On 20 May 2013 16:57, Marcus Denker <marcus.denker@inria.fr> wrote:
On May 20, 2013, at 4:44 PM, Paul Davidowitz <pdavidow@fastmail.fm> 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 )
I keep forgetting to ask - does the Refactoring AST have an equivalent of Squeak's FutureNode? (It's not semantically necessary to have one to support futures; it's a performance enhancer.) frank
On May 20, 2013, at 6:16 PM, Frank Shearar <frank.shearar@gmail.com> wrote:
On 20 May 2013 16:57, Marcus Denker <marcus.denker@inria.fr> wrote:
On May 20, 2013, at 4:44 PM, Paul Davidowitz <pdavidow@fastmail.fm> 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 )
I keep forgetting to ask - does the Refactoring AST have an equivalent of Squeak's FutureNode?
No.
(It's not semantically necessary to have one to support futures; it's a performance enhancer.)
Now that sound *very* odd. An AST Node is by definition something that is a grammatical element of the language. If you write down the grammar of Smalltalk, there is no "Future" there, so in the AST there is none modeled, either. No, I know nothing about the Future implementation in Squeak⦠but a Future node in the AST sounds extremely strange. Marcus
On 20 May 2013 17:26, Marcus Denker <marcus.denker@inria.fr> wrote:
On May 20, 2013, at 6:16 PM, Frank Shearar <frank.shearar@gmail.com> wrote:
On 20 May 2013 16:57, Marcus Denker <marcus.denker@inria.fr> wrote:
On May 20, 2013, at 4:44 PM, Paul Davidowitz <pdavidow@fastmail.fm> 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 )
I keep forgetting to ask - does the Refactoring AST have an equivalent of Squeak's FutureNode?
No.
(It's not semantically necessary to have one to support futures; it's a performance enhancer.)
Now that sound *very* odd. An AST Node is by definition something that is a grammatical element of the language. If you write down the grammar of Smalltalk, there is no "Future" there, so in the AST there is none modeled, either.
No, I know nothing about the Future implementation in Squeak⦠but a Future node in the AST sounds extremely strange.
It's a compile-time transformation of #future and #future: messages. Depending on whether or not the result is used (through some basic semantic analysis) the messages are transformed into #futureDo:at:args or #futureSend:at:args. FutureNode to performs the necessary transformation through the usual emitCodeForFoo:value: messages. (Warning: I have limited knowledge of the inner workings of the Compiler, and so anything I say here might be nonsensical.) frank
Marcus
On May 20, 2013, at 6:43 PM, Frank Shearar <frank.shearar@gmail.com> wrote:
It's a compile-time transformation of #future and #future: messages. Depending on whether or not the result is used (through some basic semantic analysis) the messages are transformed into #futureDo:at:args or #futureSend:at:args. FutureNode to performs the necessary transformation through the usual emitCodeForFoo:value: messages. (Warning: I have limited knowledge of the inner workings of the Compiler, and so anything I say here might be nonsensical.)
Wow⦠I would have never implemented it like this. I even would argue that it is conceptually wrong. The AST has a one-to-one mapping to the grammar. What is a message send is a MessageNode, this is even true for ifTrue:, so why would one not keep it like that? Optimizations have to be done on another level. Destroying the AST while generating code is not a good idea! Marcus
On Mon, May 20, 2013 at 06:26:04PM +0200, Marcus Denker wrote:
No, I know nothing about the Future implementation in Squeak? but a Future node in the AST sounds extremely strange.
I think that the background may be found in this thread: http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-December/142111.... Dave
Why Future required compiler changes? What problem to implement #future message as any other method? If it is about performance can you explain why basic implementation should have bad speed? And what benchmarks was used to verify it? 2013/5/22 David T. Lewis <lewis@mail.msen.com>
On Mon, May 20, 2013 at 06:26:04PM +0200, Marcus Denker wrote:
No, I know nothing about the Future implementation in Squeak? but a Future node in the AST sounds extremely strange.
I think that the background may be found in this thread:
http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-December/142111....
Dave
Why does ifTrue: use a compile-time transformation? There are LOTS of places where the Compiler (I can't speak for Opal, but it's almost certainly true of Pharo's Compiler unless you've already rewritten the whole thing before Opal) does all manner of code transformations. As for why, and what benchmarks, drop Josh Gargus or Ron Teitelbaum a mail. This stuff landed in Squeak via Croquet. frank On 22 May 2013 06:35, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Why Future required compiler changes? What problem to implement #future message as any other method? If it is about performance can you explain why basic implementation should have bad speed? And what benchmarks was used to verify it?
2013/5/22 David T. Lewis <lewis@mail.msen.com>
On Mon, May 20, 2013 at 06:26:04PM +0200, Marcus Denker wrote:
No, I know nothing about the Future implementation in Squeak? but a Future node in the AST sounds extremely strange.
I think that the background may be found in this thread:
http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-December/142111....
Dave
On 2013-05-22, at 09:53, Frank Shearar <frank.shearar@gmail.com> wrote:
Why does ifTrue: use a compile-time transformation? There are LOTS of places where the Compiler (I can't speak for Opal, but it's almost certainly true of Pharo's Compiler unless you've already rewritten the whole thing before Opal) does all manner of code transformations.
Futures in the compiler do only make sense in two cases: a) the VM has special bytecode support for futures b) there is a special new syntax for it AFAIK neither of it is the case.
2013/5/22 Frank Shearar <frank.shearar@gmail.com>
Why does ifTrue: use a compile-time transformation?
But what makes #future be similar to "ifTrue" case? What makes it so special?
There are LOTS of places where the Compiler (I can't speak for Opal, but it's almost certainly true of Pharo's Compiler unless you've already rewritten the whole thing before Opal) does all manner of code transformations.
As for why, and what benchmarks, drop Josh Gargus or Ron Teitelbaum a mail. This stuff landed in Squeak via Croquet.
frank
On 22 May 2013 06:35, Denis Kudriashov <dionisiydk@gmail.com> wrote:
Why Future required compiler changes? What problem to implement #future message as any other method? If it is about performance can you explain why basic implementation should have bad speed? And what benchmarks was used to verify it?
2013/5/22 David T. Lewis <lewis@mail.msen.com>
On Mon, May 20, 2013 at 06:26:04PM +0200, Marcus Denker wrote:
No, I know nothing about the Future implementation in Squeak? but a Future node in the AST sounds extremely strange.
I think that the background may be found in this thread:
http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-December/142111....
Dave
On May 22, 2013, at 11:23 AM, Denis Kudriashov <dionisiydk@gmail.com> wrote:
2013/5/22 Frank Shearar <frank.shearar@gmail.com> Why does ifTrue: use a compile-time transformation?
But what makes #future be similar to "ifTrue" case? What makes it so special?
And why do we discuss this on this Mailinglist? There are no Futures on Pharo⦠Marcus
2013/5/22 Marcus Denker <marcus.denker@inria.fr>
On May 22, 2013, at 11:23 AM, Denis Kudriashov <dionisiydk@gmail.com> wrote:
2013/5/22 Frank Shearar <frank.shearar@gmail.com>
Why does ifTrue: use a compile-time transformation?
But what makes #future be similar to "ifTrue" case? What makes it so special?
And why do we discuss this on this Mailinglist? There are no Futures on Pharoâ¦
Sorry for that.
Marcus
On Wed, May 22, 2013 at 09:35:47AM +0400, Denis Kudriashov wrote:
Why Future required compiler changes? What problem to implement #future message as any other method? If it is about performance can you explain why basic implementation should have bad speed? And what benchmarks was used to verify it?
Sorry, I cannot really help because I have no background in this, I only know what I read on the mailing list. There is also a class comment for FutureBuilder in Squeak: "Uses #doesNotUnderstand: to transform messages into future messages. In practice, this class is never used; for efficiency, the Compiler has been modified to use FutureNode to transform code at compile-time to directly send #futureSend:at:args:. However, this is simply an optimization... the semantics are unchanged." Based on this, I would assume that the compiler support is provided only for performance reasons. But I do not have any other information to offer. Dave
2013/5/22 David T. Lewis <lewis@mail.msen.com>
On Mon, May 20, 2013 at 06:26:04PM +0200, Marcus Denker wrote:
No, I know nothing about the Future implementation in Squeak? but a Future node in the AST sounds extremely strange.
I think that the background may be found in this thread:
http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-December/142111....
Dave
On May 20, 2013, at 6:15 PM, Frank Shearar <frank.shearar@gmail.com> wrote:
On 20 May 2013 16:57, Marcus Denker <marcus.denker@inria.fr> wrote:
On May 20, 2013, at 4:44 PM, Paul Davidowitz <pdavidow@fastmail.fm> 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 )
I keep forgetting to ask - does the Refactoring AST have an equivalent of Squeak's FutureNode? (It's not semantically necessary to have one to support futures; it's a performance enhancer.)
what do you mean by performance enhancer?
frank
On 20 May 2013 18:35, stephane ducasse <stephane.ducasse@free.fr> wrote:
On May 20, 2013, at 6:15 PM, Frank Shearar <frank.shearar@gmail.com> wrote:
On 20 May 2013 16:57, Marcus Denker <marcus.denker@inria.fr> wrote:
On May 20, 2013, at 4:44 PM, Paul Davidowitz <pdavidow@fastmail.fm> 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 )
I keep forgetting to ask - does the Refactoring AST have an equivalent of Squeak's FutureNode? (It's not semantically necessary to have one to support futures; it's a performance enhancer.)
what do you mean by performance enhancer?
Like with ifTrue:, whileTrue: and friends: you can still use futures in Squeak if you don't have FutureNode in your image, but things will just run slower. frank
frank
On May 20, 2013, at 8:13 PM, Frank Shearar <frank.shearar@gmail.com> wrote:
Like with ifTrue:, whileTrue: and friends: you can still use futures in Squeak if you don't have FutureNode in your image, but things will just run slower.
But there is no IfTrueNode, either. The AST models the grammar of the language, that's why it is called Syntax treeâ¦. Marcus
On 20 May 2013 19:17, Marcus Denker <marcus.denker@inria.fr> wrote:
On May 20, 2013, at 8:13 PM, Frank Shearar <frank.shearar@gmail.com> wrote:
Like with ifTrue:, whileTrue: and friends: you can still use futures in Squeak if you don't have FutureNode in your image, but things will just run slower.
But there is no IfTrueNode, either.
The AST models the grammar of the language, that's why it is called Syntax treeâ¦.
Sure. I have no idea why it's implemented that way. Perhaps it was easier or desirable to keep the transformation out of the base image or something. Josh Gargus might know. I would imagine that in Opal you wouldn't need to do that :) You'd hook in custom emitters somewhere, and be done. frank
Marcus
Hacking inside the compiler instead of extending it to support a good static way of declaring transformations is way to: - make the system more complex, less modular - hamper tools to use a good infrastructure - push hacks and hidden knowledge in all the layers. Definitively not a good idea. This is why opal has a open architecture for plugins. Stef
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 )
I keep forgetting to ask - does the Refactoring AST have an equivalent of Squeak's FutureNode? (It's not semantically necessary to have one to support futures; it's a performance enhancer.)
what do you mean by performance enhancer?
Like with ifTrue:, whileTrue: and friends: you can still use futures in Squeak if you don't have FutureNode in your image, but things will just run slower.
frank
frank
Wow, thanks for the detailed explanation. That is really interesting! Norbert Am 20.05.2013 um 17:57 schrieb Marcus Denker <marcus.denker@inria.fr>:
On May 20, 2013, at 4:44 PM, Paul Davidowitz <pdavidow@fastmail.fm> 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
participants (9)
-
Camillo Bruni -
David T. Lewis -
Denis Kudriashov -
Frank Shearar -
Marcus Denker -
Norbert Hartl -
Paul Davidowitz -
stephane ducasse -
Sven Van Caekenberghe