- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
Dynamic object composition
Wed, 2009-06-17, 22:55
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Thu, 2009-06-18, 01:27
#2
Re: Dynamic object composition
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Thu, 2009-06-18, 08:47
#3
Re: Dynamic object composition
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers,adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
cheers,adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
Thu, 2009-06-18, 09:17
#4
Re: Dynamic object composition
Roles! This has brought some memories. Back in 1998 I did (my MSc thesis) a compiler for an extension of Java that had first-class roles. The objective was to model context-dependent dynamic behavioural evolution. I even had some basic algebra that described things...
This stuff are always at the back of my head. Context-dependent behaviour will raise sometime to a discipline. At least it has great potential.
BRChristos
On Jun 18, 2009, at 10:46 AM, Adriaan Moors wrote:
--
__~O
-\ <, Christos KK Loverdos
(*)/ (*) http://ckkloverdos.com
This stuff are always at the back of my head. Context-dependent behaviour will raise sometime to a discipline. At least it has great potential.
BRChristos
On Jun 18, 2009, at 10:46 AM, Adriaan Moors wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers,adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
__~O
-\ <, Christos KK Loverdos
(*)/ (*) http://ckkloverdos.com
Thu, 2009-06-18, 09:37
#5
Re: Dynamic object composition
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers,adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
Thu, 2009-06-18, 09:57
#6
Re: Dynamic object composition
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers,adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
Thu, 2009-06-18, 15:17
#7
Re: Dynamic object composition
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers,adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
Thu, 2009-06-18, 15:37
#8
Re: Dynamic object composition
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Thu, 2009-06-18, 16:17
#9
Re: Dynamic object composition
If I can't add a pure keyword, then I can certainly add an annotation!
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Thu, 2009-06-18, 16:27
#10
Re: Dynamic object composition
trait Base {
def methodFromBase = ...do something
def otherMethodFromBase = ...something else
def yetAnotherBaseMethod = ...show working here
}
@proxyfor[classOf[Base]] class Decorator(base: Base) {
def methodFromBase = ...enhanced version of base.methodFromBase
def brandNewMethod = ...
}
should give me:
class Decorator(base: Base) {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def base2decorator(base: Base) = new Decorator(base)
}
Where the code in red has been transformed to the code in blue
The syntax is a little cluttered, and it's a shame that we lose the override keyword, but the concept still looks good :)
On Thu, Jun 18, 2009 at 4:09 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
def methodFromBase = ...do something
def otherMethodFromBase = ...something else
def yetAnotherBaseMethod = ...show working here
}
@proxyfor[classOf[Base]] class Decorator(base: Base) {
def methodFromBase = ...enhanced version of base.methodFromBase
def brandNewMethod = ...
}
should give me:
class Decorator(base: Base) {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def base2decorator(base: Base) = new Decorator(base)
}
Where the code in red has been transformed to the code in blue
The syntax is a little cluttered, and it's a shame that we lose the override keyword, but the concept still looks good :)
On Thu, Jun 18, 2009 at 4:09 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
If I can't add a pure keyword, then I can certainly add an annotation!
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Thu, 2009-06-18, 16:47
#11
Re: Dynamic object composition
You won't get the implicit conversion on calls defined for Base. I wonder, then, if you couldn't accomplish this with two way implicits?
On Thu, Jun 18, 2009 at 12:21 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
On Thu, Jun 18, 2009 at 12:21 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
trait Base {
def methodFromBase = ...do something
def otherMethodFromBase = ...something else
def yetAnotherBaseMethod = ...show working here
}
@proxyfor[classOf[Base]] class Decorator(base: Base) {
def methodFromBase = ...enhanced version of base.methodFromBase
def brandNewMethod = ...
}
should give me:
class Decorator(base: Base) {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def base2decorator(base: Base) = new Decorator(base)
}
Where the code in red has been transformed to the code in blue
The syntax is a little cluttered, and it's a shame that we lose the override keyword, but the concept still looks good :)
On Thu, Jun 18, 2009 at 4:09 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
If I can't add a pure keyword, then I can certainly add an annotation!
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Thu, 2009-06-18, 17:27
#12
Re: Dynamic object composition
My thinking was that it wouldn't be needed, given that the proxy already exposes all the functionality of the delegated base class, it would also be necessary to expose the base variable as well (presumably by making it a val)
So here's my next attempt:
class Decorator(val base : @proxy UnderlyingClass) {
def methodFromBase = ...enhanced version of UnderlyingClass.methodFromBase
def brandNewMethod = ...
}
becomes
class Decorator {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def apply(base: UnderlyingClass) : Decorator = new Decorator(base)
implicit def unproxy(decorator: Decorator) : UnderlyingClass = decorator.base
}
much nicer! No need to mention the proxied class name twice, plus the exact name of the "base" variable can be explicitly specified by the user, so no risk of a clash with any such generated name.
Next challenge is to start thinking how this might interoperate with pattern matching!
On Thu, Jun 18, 2009 at 4:44 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
So here's my next attempt:
class Decorator(val base : @proxy UnderlyingClass) {
def methodFromBase = ...enhanced version of UnderlyingClass.methodFromBase
def brandNewMethod = ...
}
becomes
class Decorator {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def apply(base: UnderlyingClass) : Decorator = new Decorator(base)
implicit def unproxy(decorator: Decorator) : UnderlyingClass = decorator.base
}
much nicer! No need to mention the proxied class name twice, plus the exact name of the "base" variable can be explicitly specified by the user, so no risk of a clash with any such generated name.
Next challenge is to start thinking how this might interoperate with pattern matching!
On Thu, Jun 18, 2009 at 4:44 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
You won't get the implicit conversion on calls defined for Base. I wonder, then, if you couldn't accomplish this with two way implicits?
On Thu, Jun 18, 2009 at 12:21 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
trait Base {
def methodFromBase = ...do something
def otherMethodFromBase = ...something else
def yetAnotherBaseMethod = ...show working here
}
@proxyfor[classOf[Base]] class Decorator(base: Base) {
def methodFromBase = ...enhanced version of base.methodFromBase
def brandNewMethod = ...
}
should give me:
class Decorator(base: Base) {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def base2decorator(base: Base) = new Decorator(base)
}
Where the code in red has been transformed to the code in blue
The syntax is a little cluttered, and it's a shame that we lose the override keyword, but the concept still looks good :)
On Thu, Jun 18, 2009 at 4:09 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
If I can't add a pure keyword, then I can certainly add an annotation!
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Thu, 2009-06-18, 17:57
#13
Re: Dynamic object composition
I didn't mean two way implicits in addition to annotation. What I meant is, wouldn't two way implicits do what you need without annotations?
On Thu, Jun 18, 2009 at 1:17 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
On Thu, Jun 18, 2009 at 1:17 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
My thinking was that it wouldn't be needed, given that the proxy already exposes all the functionality of the delegated base class, it would also be necessary to expose the base variable as well (presumably by making it a val)
So here's my next attempt:
class Decorator(val base : @proxy UnderlyingClass) {
def methodFromBase = ...enhanced version of UnderlyingClass.methodFromBase
def brandNewMethod = ...
}
becomes
class Decorator {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def apply(base: UnderlyingClass) : Decorator = new Decorator(base)
implicit def unproxy(decorator: Decorator) : UnderlyingClass = decorator.base
}
much nicer! No need to mention the proxied class name twice, plus the exact name of the "base" variable can be explicitly specified by the user, so no risk of a clash with any such generated name.
Next challenge is to start thinking how this might interoperate with pattern matching!
On Thu, Jun 18, 2009 at 4:44 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
You won't get the implicit conversion on calls defined for Base. I wonder, then, if you couldn't accomplish this with two way implicits?
On Thu, Jun 18, 2009 at 12:21 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
trait Base {
def methodFromBase = ...do something
def otherMethodFromBase = ...something else
def yetAnotherBaseMethod = ...show working here
}
@proxyfor[classOf[Base]] class Decorator(base: Base) {
def methodFromBase = ...enhanced version of base.methodFromBase
def brandNewMethod = ...
}
should give me:
class Decorator(base: Base) {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def base2decorator(base: Base) = new Decorator(base)
}
Where the code in red has been transformed to the code in blue
The syntax is a little cluttered, and it's a shame that we lose the override keyword, but the concept still looks good :)
On Thu, Jun 18, 2009 at 4:09 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
If I can't add a pure keyword, then I can certainly add an annotation!
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Fri, 2009-06-19, 08:07
#14
Re: Dynamic object composition
If interface injection ever makes it to the JVM (see http://blogs.sun.com/jrose/entry/interface_injection_in_the_vm) you could conceivably write a method with the following type signature:
def inject[T, S](obj: T, interface: Class[S]): T with S
And use it like:
inject("string", classOf[RichString]).capitalize == "String"
If Scala doesn't support injection at a language level, you could just do some bytecode rewriting to get the method to work out.
--j
On Thu, Jun 18, 2009 at 9:17 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
def inject[T, S](obj: T, interface: Class[S]): T with S
And use it like:
inject("string", classOf[RichString]).capitalize == "String"
If Scala doesn't support injection at a language level, you could just do some bytecode rewriting to get the method to work out.
--j
On Thu, Jun 18, 2009 at 9:17 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
My thinking was that it wouldn't be needed, given that the proxy already exposes all the functionality of the delegated base class, it would also be necessary to expose the base variable as well (presumably by making it a val)
So here's my next attempt:
class Decorator(val base : @proxy UnderlyingClass) {
def methodFromBase = ...enhanced version of UnderlyingClass.methodFromBase
def brandNewMethod = ...
}
becomes
class Decorator {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def apply(base: UnderlyingClass) : Decorator = new Decorator(base)
implicit def unproxy(decorator: Decorator) : UnderlyingClass = decorator.base
}
much nicer! No need to mention the proxied class name twice, plus the exact name of the "base" variable can be explicitly specified by the user, so no risk of a clash with any such generated name.
Next challenge is to start thinking how this might interoperate with pattern matching!
On Thu, Jun 18, 2009 at 4:44 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
You won't get the implicit conversion on calls defined for Base. I wonder, then, if you couldn't accomplish this with two way implicits?
On Thu, Jun 18, 2009 at 12:21 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
trait Base {
def methodFromBase = ...do something
def otherMethodFromBase = ...something else
def yetAnotherBaseMethod = ...show working here
}
@proxyfor[classOf[Base]] class Decorator(base: Base) {
def methodFromBase = ...enhanced version of base.methodFromBase
def brandNewMethod = ...
}
should give me:
class Decorator(base: Base) {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def base2decorator(base: Base) = new Decorator(base)
}
Where the code in red has been transformed to the code in blue
The syntax is a little cluttered, and it's a shame that we lose the override keyword, but the concept still looks good :)
On Thu, Jun 18, 2009 at 4:09 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
If I can't add a pure keyword, then I can certainly add an annotation!
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Fri, 2009-06-19, 08:17
#15
Re: Dynamic object composition
On Fri, 2009-06-19 at 00:00 -0700, Jorge Ortiz wrote:
> If interface injection ever makes it to the JVM
I don't know if you saw it, but Martin said in another thread that
interface injection may not be available in JDK 7.
Ismael
Fri, 2009-06-19, 09:27
#16
Re: Dynamic object composition
That's pretty much the existing pimp-my-library pattern. But it doesn't solve the particular issues I had in mind:
1. I want to avoid repeated conversion between the base and decorator types. This also means that the decorator needs to expose, through delegation, EVERY method from the base object that hasn't been explicitly overridden.
okay, so converting decorator -> base is just a member lookup which I'd expect the JIT compiler to inline, but there's an overhead in converting base->decorator every time I use a method in the decorator, with an associated object construction cost.
2. I want to be able to select from a number of decorators with the same signature, with the ability to use different decorators in different parts of the program, according to whatever role the object needs to play.
3. I want for decorators to be able to override methods with the same signature from the base object, implicit conversion won't even be considered by the compiler in this case.
4. Implicit conversions just don't work if I have two decorators with the same signature.
On Thu, Jun 18, 2009 at 5:48 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
1. I want to avoid repeated conversion between the base and decorator types. This also means that the decorator needs to expose, through delegation, EVERY method from the base object that hasn't been explicitly overridden.
okay, so converting decorator -> base is just a member lookup which I'd expect the JIT compiler to inline, but there's an overhead in converting base->decorator every time I use a method in the decorator, with an associated object construction cost.
2. I want to be able to select from a number of decorators with the same signature, with the ability to use different decorators in different parts of the program, according to whatever role the object needs to play.
3. I want for decorators to be able to override methods with the same signature from the base object, implicit conversion won't even be considered by the compiler in this case.
4. Implicit conversions just don't work if I have two decorators with the same signature.
On Thu, Jun 18, 2009 at 5:48 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I didn't mean two way implicits in addition to annotation. What I meant is, wouldn't two way implicits do what you need without annotations?
On Thu, Jun 18, 2009 at 1:17 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
My thinking was that it wouldn't be needed, given that the proxy already exposes all the functionality of the delegated base class, it would also be necessary to expose the base variable as well (presumably by making it a val)
So here's my next attempt:
class Decorator(val base : @proxy UnderlyingClass) {
def methodFromBase = ...enhanced version of UnderlyingClass.methodFromBase
def brandNewMethod = ...
}
becomes
class Decorator {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def apply(base: UnderlyingClass) : Decorator = new Decorator(base)
implicit def unproxy(decorator: Decorator) : UnderlyingClass = decorator.base
}
much nicer! No need to mention the proxied class name twice, plus the exact name of the "base" variable can be explicitly specified by the user, so no risk of a clash with any such generated name.
Next challenge is to start thinking how this might interoperate with pattern matching!
On Thu, Jun 18, 2009 at 4:44 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
You won't get the implicit conversion on calls defined for Base. I wonder, then, if you couldn't accomplish this with two way implicits?
On Thu, Jun 18, 2009 at 12:21 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
trait Base {
def methodFromBase = ...do something
def otherMethodFromBase = ...something else
def yetAnotherBaseMethod = ...show working here
}
@proxyfor[classOf[Base]] class Decorator(base: Base) {
def methodFromBase = ...enhanced version of base.methodFromBase
def brandNewMethod = ...
}
should give me:
class Decorator(base: Base) {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def base2decorator(base: Base) = new Decorator(base)
}
Where the code in red has been transformed to the code in blue
The syntax is a little cluttered, and it's a shame that we lose the override keyword, but the concept still looks good :)
On Thu, Jun 18, 2009 at 4:09 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
If I can't add a pure keyword, then I can certainly add an annotation!
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Fri, 2009-06-19, 09:37
#17
Re: Dynamic object composition
I'm curious, given the ongoing work to expose the AST from the compiler to IDEs, would methods generated in this way be made visible for code completion, etc?
On Thu, Jun 18, 2009 at 5:17 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On Thu, Jun 18, 2009 at 5:17 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
My thinking was that it wouldn't be needed, given that the proxy already exposes all the functionality of the delegated base class, it would also be necessary to expose the base variable as well (presumably by making it a val)
So here's my next attempt:
class Decorator(val base : @proxy UnderlyingClass) {
def methodFromBase = ...enhanced version of UnderlyingClass.methodFromBase
def brandNewMethod = ...
}
becomes
class Decorator {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def apply(base: UnderlyingClass) : Decorator = new Decorator(base)
implicit def unproxy(decorator: Decorator) : UnderlyingClass = decorator.base
}
much nicer! No need to mention the proxied class name twice, plus the exact name of the "base" variable can be explicitly specified by the user, so no risk of a clash with any such generated name.
Next challenge is to start thinking how this might interoperate with pattern matching!
On Thu, Jun 18, 2009 at 4:44 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
You won't get the implicit conversion on calls defined for Base. I wonder, then, if you couldn't accomplish this with two way implicits?
On Thu, Jun 18, 2009 at 12:21 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
trait Base {
def methodFromBase = ...do something
def otherMethodFromBase = ...something else
def yetAnotherBaseMethod = ...show working here
}
@proxyfor[classOf[Base]] class Decorator(base: Base) {
def methodFromBase = ...enhanced version of base.methodFromBase
def brandNewMethod = ...
}
should give me:
class Decorator(base: Base) {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def base2decorator(base: Base) = new Decorator(base)
}
Where the code in red has been transformed to the code in blue
The syntax is a little cluttered, and it's a shame that we lose the override keyword, but the concept still looks good :)
On Thu, Jun 18, 2009 at 4:09 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
If I can't add a pure keyword, then I can certainly add an annotation!
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
Fri, 2009-06-19, 13:57
#18
Re: Dynamic object composition
Heh... I wonder something else. If you try val x : Any = List(1) in REPL, and then type x.<TAB>, you'll see all of List's methods, even though you can't use them.
I hope they get around that in the AST-IDE project. :-)
On Fri, Jun 19, 2009 at 5:25 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
I hope they get around that in the AST-IDE project. :-)
On Fri, Jun 19, 2009 at 5:25 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm curious, given the ongoing work to expose the AST from the compiler to IDEs, would methods generated in this way be made visible for code completion, etc?
On Thu, Jun 18, 2009 at 5:17 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
My thinking was that it wouldn't be needed, given that the proxy already exposes all the functionality of the delegated base class, it would also be necessary to expose the base variable as well (presumably by making it a val)
So here's my next attempt:
class Decorator(val base : @proxy UnderlyingClass) {
def methodFromBase = ...enhanced version of UnderlyingClass.methodFromBase
def brandNewMethod = ...
}
becomes
class Decorator {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def apply(base: UnderlyingClass) : Decorator = new Decorator(base)
implicit def unproxy(decorator: Decorator) : UnderlyingClass = decorator.base
}
much nicer! No need to mention the proxied class name twice, plus the exact name of the "base" variable can be explicitly specified by the user, so no risk of a clash with any such generated name.
Next challenge is to start thinking how this might interoperate with pattern matching!
On Thu, Jun 18, 2009 at 4:44 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
You won't get the implicit conversion on calls defined for Base. I wonder, then, if you couldn't accomplish this with two way implicits?
On Thu, Jun 18, 2009 at 12:21 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
trait Base {
def methodFromBase = ...do something
def otherMethodFromBase = ...something else
def yetAnotherBaseMethod = ...show working here
}
@proxyfor[classOf[Base]] class Decorator(base: Base) {
def methodFromBase = ...enhanced version of base.methodFromBase
def brandNewMethod = ...
}
should give me:
class Decorator(base: Base) {
def methodFromBase = ...
def brandNewMethod = ...
def otherMethodFromBase = base.otherMethodFromBase
def yetAnotherBaseMethod = base.yetAnotherBaseMethod
}
object Decorator {
implicit def base2decorator(base: Base) = new Decorator(base)
}
Where the code in red has been transformed to the code in blue
The syntax is a little cluttered, and it's a shame that we lose the override keyword, but the concept still looks good :)
On Thu, Jun 18, 2009 at 4:09 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
If I can't add a pure keyword, then I can certainly add an annotation!
Maybe I can "borrow" the code used for @BeanProperty, it seems to fit the goal of adding new methods to an existing trait at compile time
So long as I can pass types to an annotation, all should be good :)
On Thu, Jun 18, 2009 at 3:30 PM, Daniel Sobral <dcsobral@gmail.com> wrote:
I asked this on #scala very recently and the answer was no. I wonder if keywords are identified in lexing...
On Thu, Jun 18, 2009 at 11:14 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
I'm wondering here, is it possible to support a new keyword (such as "proxies" or "proxyfor" via a compiler plugin?
If I know it's possible, I'm thinking to try knocking out a proof of concept.
On Thu, Jun 18, 2009 at 9:47 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
On second thoughts, there isn't really any need to automatically generate some abstact supertype for the proxy, to do this on the JVM it would have to be a structural type so that it could be retrofitted to Parent.
In the example I gave below, it would be far easier (and much more performant) to just generate an implicit conversion from Decorator to Parent
This then makes the solution little more than trivial code generation, very easy to implement within the current scala compiler. Still, it would be interesting to consider possible problems involving the interaction with implicit conversions, self types, etc.
Generics should also be fine too:
trait Decorator[T] proxies Parent[T] {
...
}
On Thu, Jun 18, 2009 at 9:29 AM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
Actually, I was considering this as a cleaner way to implement "pimp my library"
At the moment, we have implicit conversions and view bounds, but to use these to extend functionality on a wrapped object then there is still need to expose all the necessary functionality via an anonymous trait, then implement these methods to delegate to the wrapped implementation.
Scala is already doing something similar via the Proxy trait. This is very close to my thinking, but sadly it only works for methods on the Trait "Any"
I have some concers my original suggestion for the syntax though.
In static comosition, the construct:
val a = new <class> with <trait>
is linearised with <trait> nested inside <class>
To duplicate this with dynamic composition, it would be consistent to have:
val a = new <decorator trait> with <existing object>
I'm not even sure if the compiler could be written to handle this. What if, instead of just using a simple val for the existing object, a function was used to supply the instance, things could get very confusing very quickly.
Another idea would be to introduce alternative syntax:
Trait Decorator proxies Parent {
def someNewMethod = ... do something
override def someOtherMethod() = ... do something with super.someOtherMethod()
// all other methods of Type are delegated to an existing instance
}
super would refer to the instance of Parent being proxied and Decorator would be considered to be a subtype of Parent, or of some anonymous automatically generated abstract trait that declares all the methods of Parent (this would be a nice way to handle proxying of classes declared final)
These proxies could also be made implicit, so any method argument requiring a Decorator could transparently accept a Parent
I'd also imagine it to be used something like:
val a = new Decorator(<instance of parent>)
On Thu, Jun 18, 2009 at 8:46 AM, Adriaan Moors <adriaan.moors@cs.kuleuven.be> wrote:
I quite like dynamic object composition. Michael Pradel did his master's thesis on something closely related: his talk. There's also a paper.
cheers, adriaan
On Thu, Jun 18, 2009 at 2:18 AM, Jorge Ortiz <jorge.ortiz@gmail.com> wrote:
A similar effect can be achieved with the Pimp My Library pattern.
--j
On Wed, Jun 17, 2009 at 2:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
As a possible new language feature, How plausible would it be to extend a live instantiated object with a trait, by reusing the "with" keyword that already exists for mixins / static object composition? This would help greatly in implementing decorators and the DCI pattern
Disclaimer: http://www.kuleuven.be/cwis/email_disclaimer.htm for more information.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.
On Wed, Jun 17, 2009 at 6:55 PM, Kevin Wright <kev.lee.wright@googlemail.com> wrote:
--
Daniel C. Sobral
Something I learned in academia: there are three kinds of academic reviews: review by name, review by reference and review by value.