This page is no longer maintained — Please continue to the home page at www.scala-lang.org

Announcing autoproxy-lite

8 replies
Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
I now have a (slightly restricted) version of the long awaited autoproxy plugin passing the first few basic tests.
The jar isn't yet formally published anywhere, but the GitHub project can be found here: https://github.com/kevinwright/Autoproxy-Lite (Requires SBT 0.7.6.RC0 and targets Scala 2.9.0.RC1)
For anyone who likes like on the bleeding edge, please feel free to try it out and send me all your bug reports :)


--
Kevin Wright

gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
roland.kuhn
Joined: 2011-02-21,
User offline. Last seen 35 weeks 3 days ago.
Re: Announcing autoproxy-lite
Hi Kevin,
this looks truly awesome (and I don’t care much about the restriction, because delegating an interface is the whole point, right?).
On Apr 5, 2011, at 16:30 , Kevin Wright wrote:
I now have a (slightly restricted) version of the long awaited autoproxy plugin passing the first few basic tests.
The jar isn't yet formally published anywhere, but the GitHub project can be found here: https://github.com/kevinwright/Autoproxy-Lite (Requires SBT 0.7.6.RC0 and targets Scala 2.9.0.RC1)
For anyone who likes like on the bleeding edge, please feel free to try it out and send me all your bug reports :)
Okay, here it goes:
How do I get started? I cloned, ran "sbt shell" and "doc", which seemed to compile all the crucial stuff and failed on the Simple Example (plugin not found). I tried "deliver", which complained about unspecified repo, "deliver-local" then downloaded quite some stuff, but in the end plugin/deliver-local could not download scala-library.jar(src). What next?
Regards,
Roland
Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: Announcing autoproxy-lite
"package" will run the tests and build the jars.  The annotation sub-project provides the @proxy annotation, and the plugin project supplies the plugin proper.
packaging will initially fail when it tries to build the examples before the plugin jar is output.  Running it a second time will work just fine.


On 5 April 2011 18:17, Roland Kuhn <google@rkuhn.info> wrote:
Hi Kevin,
this looks truly awesome (and I don’t care much about the restriction, because delegating an interface is the whole point, right?).
On Apr 5, 2011, at 16:30 , Kevin Wright wrote:
I now have a (slightly restricted) version of the long awaited autoproxy plugin passing the first few basic tests.
The jar isn't yet formally published anywhere, but the GitHub project can be found here: https://github.com/kevinwright/Autoproxy-Lite (Requires SBT 0.7.6.RC0 and targets Scala 2.9.0.RC1)
For anyone who likes like on the bleeding edge, please feel free to try it out and send me all your bug reports :)
Okay, here it goes:
How do I get started? I cloned, ran "sbt shell" and "doc", which seemed to compile all the crucial stuff and failed on the Simple Example (plugin not found). I tried "deliver", which complained about unspecified repo, "deliver-local" then downloaded quite some stuff, but in the end plugin/deliver-local could not download scala-library.jar(src). What next?
Regards,
Roland



--
Kevin Wright

gtalk / msn : kev.lee.wright@gmail.com kev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
boisvert
Joined: 2009-11-11,
User offline. Last seen 38 weeks 5 days ago.
Re: Announcing autoproxy-lite
On Tue, Apr 5, 2011 at 7:30 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:
I now have a (slightly restricted) version of the long awaited autoproxy plugin passing the first few basic tests.
The jar isn't yet formally published anywhere, but the GitHub project can be found here: https://github.com/kevinwright/Autoproxy-Lite (Requires SBT 0.7.6.RC0 and targets Scala 2.9.0.RC1)
For anyone who likes like on the bleeding edge, please feel free to try it out and send me all your bug reports :)

Hi Kevin,
Just curious, how does proxying work in conjunction with class/trait linearization?  Are the rules defined/finalized and if so, is there a spec that explains the semantics?
alex
Kevin Wright 2
Joined: 2010-05-30,
User offline. Last seen 26 weeks 4 days ago.
Re: Announcing autoproxy-lite


On 6 April 2011 15:58, Alex Boisvert <alex.boisvert@gmail.com> wrote:
On Tue, Apr 5, 2011 at 7:30 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:
I now have a (slightly restricted) version of the long awaited autoproxy plugin passing the first few basic tests.
The jar isn't yet formally published anywhere, but the GitHub project can be found here: https://github.com/kevinwright/Autoproxy-Lite (Requires SBT 0.7.6.RC0 and targets Scala 2.9.0.RC1)
For anyone who likes like on the bleeding edge, please feel free to try it out and send me all your bug reports :)

Hi Kevin,
Just curious, how does proxying work in conjunction with class/trait linearization?  Are the rules defined/finalized and if so, is there a spec that explains the semantics?

No magic here, it's exactly as though you'd written the delegates by hand.  As per the example:
    trait SomeClass {
      def theString: String
      def theInt: Int
    }

    class DynamicMixin(@proxy instance: SomeClass) extends SomeClass {
      override def toString = "theString=" + theString + ", theInt=" + theInt
    }
 becomes:
    trait SomeClass {
      def theString: String
      def theInt: Int
    }

    class DynamicMixin(@proxy instance: SomeClass) extends SomeClass {
      override def toString = "theString=" + theString + ", theInt=" + theInt
      def theString = instance.theString
      def theInt = instance.theInt
    }
alex



--
Kevin Wright

gtalk / msn : kev.lee.wright@gmail.comkev.lee.wright@gmail.commail: kevin.wright@scalatechnology.com
vibe / skype: kev.lee.wrightquora: http://www.quora.com/Kevin-Wright
twitter: @thecoda

"My point today is that, if we wish to count lines of code, we should not regard them as "lines produced" but as "lines spent": the current conventional wisdom is so foolish as to book that count on the wrong side of the ledger" ~ Dijkstra
boisvert
Joined: 2009-11-11,
User offline. Last seen 38 weeks 5 days ago.
Re: Announcing autoproxy-lite
On Wed, Apr 6, 2011 at 8:04 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:


On 6 April 2011 15:58, Alex Boisvert <alex.boisvert@gmail.com> wrote:
On Tue, Apr 5, 2011 at 7:30 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:
I now have a (slightly restricted) version of the long awaited autoproxy plugin passing the first few basic tests.
The jar isn't yet formally published anywhere, but the GitHub project can be found here: https://github.com/kevinwright/Autoproxy-Lite (Requires SBT 0.7.6.RC0 and targets Scala 2.9.0.RC1)
For anyone who likes like on the bleeding edge, please feel free to try it out and send me all your bug reports :)

Hi Kevin,
Just curious, how does proxying work in conjunction with class/trait linearization?  Are the rules defined/finalized and if so, is there a spec that explains the semantics?

No magic here, it's exactly as though you'd written the delegates by hand.  As per the example:
    trait SomeClass {
      def theString: String
      def theInt: Int
    }

    class DynamicMixin(@proxy instance: SomeClass) extends SomeClass {
      override def toString = "theString=" + theString + ", theInt=" + theInt
    }
 becomes:
    trait SomeClass {
      def theString: String
      def theInt: Int
    }

    class DynamicMixin(@proxy instance: SomeClass) extends SomeClass {
      override def toString = "theString=" + theString + ", theInt=" + theInt
      def theString = instance.theString
      def theInt = instance.theInt
    }

Ok, more precisely, what happens in the face of overlapping methods?
trait Foo {  def x = 1 }
trait Bar {  def x = 2}
class FooBar(@proxy foo: Foo) extends Foo with Bar class BarFoo(@proxy foo: Foo) extends Bar with Foo
new FooBar.x // => 2?new BarFoo.x // => 1?
alex
boisvert
Joined: 2009-11-11,
User offline. Last seen 38 weeks 5 days ago.
Re: Announcing autoproxy-lite
On Wed, Apr 6, 2011 at 10:39 AM, Alex Boisvert <alex.boisvert@gmail.com> wrote:
On Wed, Apr 6, 2011 at 8:04 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:


On 6 April 2011 15:58, Alex Boisvert <alex.boisvert@gmail.com> wrote:
On Tue, Apr 5, 2011 at 7:30 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:
I now have a (slightly restricted) version of the long awaited autoproxy plugin passing the first few basic tests.
The jar isn't yet formally published anywhere, but the GitHub project can be found here: https://github.com/kevinwright/Autoproxy-Lite (Requires SBT 0.7.6.RC0 and targets Scala 2.9.0.RC1)
For anyone who likes like on the bleeding edge, please feel free to try it out and send me all your bug reports :)

Hi Kevin,
Just curious, how does proxying work in conjunction with class/trait linearization?  Are the rules defined/finalized and if so, is there a spec that explains the semantics?

No magic here, it's exactly as though you'd written the delegates by hand.  As per the example:
    trait SomeClass {
      def theString: String
      def theInt: Int
    }

    class DynamicMixin(@proxy instance: SomeClass) extends SomeClass {
      override def toString = "theString=" + theString + ", theInt=" + theInt
    }
 becomes:
    trait SomeClass {
      def theString: String
      def theInt: Int
    }

    class DynamicMixin(@proxy instance: SomeClass) extends SomeClass {
      override def toString = "theString=" + theString + ", theInt=" + theInt
      def theString = instance.theString
      def theInt = instance.theInt
    }

Ok, more precisely, what happens in the face of overlapping methods?
trait Foo {  def x = 1 }
trait Bar {  def x = 2}
class FooBar(@proxy foo: Foo) extends Foo with Bar class BarFoo(@proxy foo: Foo) extends Bar with Foo
new FooBar.x // => 2?new BarFoo.x // => 1?

Sorry, bad example/question since you'd need to explicitly override to disambiguate.
Assume instead:
trait Foo {  def x: Int}
new FooBar().x // invokes Bar.x or foo.x ?new BarFoo().x // invokes Bar.x or foo.x ?
See what I mean?
alex
roland.kuhn
Joined: 2011-02-21,
User offline. Last seen 35 weeks 3 days ago.
Re: Announcing autoproxy-lite
On Apr 6, 2011, at 19:45 , Alex Boisvert wrote:
On Wed, Apr 6, 2011 at 10:39 AM, Alex Boisvert <alex.boisvert@gmail.com> wrote:
On Wed, Apr 6, 2011 at 8:04 AM, Kevin Wright <kev.lee.wright@gmail.com> wrote:

No magic here, it's exactly as though you'd written the delegates by hand.  As per the example:

    trait SomeClass {
      def theString: String
      def theInt: Int
    }

    class DynamicMixin(@proxy instance: SomeClass) extends SomeClass {
      override def toString = "theString=" + theString + ", theInt=" + theInt
    }
 becomes:
    trait SomeClass {
      def theString: String
      def theInt: Int
    }

    class DynamicMixin(@proxy instance: SomeClass) extends SomeClass {
      override def toString = "theString=" + theString + ", theInt=" + theInt
      def theString = instance.theString
      def theInt = instance.theInt
    }

Ok, more precisely, what happens in the face of overlapping methods?
trait Foo {  def x = 1 }
trait Bar {  def x = 2}
class FooBar(@proxy foo: Foo) extends Foo with Bar class BarFoo(@proxy foo: Foo) extends Bar with Foo
new FooBar.x // => 2?new BarFoo.x // => 1?

Sorry, bad example/question since you'd need to explicitly override to disambiguate.
Assume instead:
trait Foo {  def x: Int}
new FooBar().x // invokes Bar.x or foo.x ?new BarFoo().x // invokes Bar.x or foo.x ?
See what I mean?

I am also researching the ways of this plugin, and the following transcript might shed some light:
scala> trait Foo { def x : Int }defined trait Foo
scala> trait Bar { def x = 2 }defined trait Bar
scala> object F extends Foo { val x = 1 }defined module F
scala> class FooBar(@proxy foo: Foo) extends Foo with Bardefined class FooBar
scala> class BarFoo(@proxy foo: Foo) extends Bar with Foodefined class BarFoo
scala> new FooBar(F).xres0: Int = 1
scala> new BarFoo(F).xres1: Int = 1
scala> :javap -c FooBarCompiled from "<console>"public class FooBar extends java.lang.Object implements Foo,Bar,scala.ScalaObject{public int x();  Code:   0: aload_0   1: getfield #12; //Field foo:LFoo;   4: invokeinterface #16,  1; //InterfaceMethod Foo.x:()I   9: ireturn
public FooBar(Foo);  Code:   0: aload_0   1: aload_1   2: putfield #12; //Field foo:LFoo;   5: aload_0   6: invokespecial #23; //Method java/lang/Object."<init>":()V   9: aload_0   10: invokestatic #29; //Method Bar$class.$init$:(LBar;)V   13: return
}

scala> :javap -c BarFooCompiled from "<console>"public class BarFoo extends java.lang.Object implements Bar,Foo,scala.ScalaObject{public int x();  Code:   0: aload_0   1: getfield #12; //Field foo:LFoo;   4: invokeinterface #16,  1; //InterfaceMethod Foo.x:()I   9: ireturn
public BarFoo(Foo);  Code:   0: aload_0   1: aload_1   2: putfield #12; //Field foo:LFoo;   5: aload_0   6: invokespecial #23; //Method java/lang/Object."<init>":()V   9: aload_0   10: invokestatic #29; //Method Bar$class.$init$:(LBar;)V   13: return
}

scala> class B extends Bar { def x = 3 }<console>:9: error: overriding method x in trait Bar of type => Int; method x needs `override' modifier       class B extends Bar { def x = 3 }                                 ^
scala> class C(@proxy foo:Foo) { def x = 12 }<console>:9: error: double definition:method x:=> Int andmethod x:=> Int at line 9have same type       class C(@proxy foo:Foo) { def x = 12 }
===============================
So, to summarize, the @proxy desugars quite literally to the methods being defined in the containing class. If there is already such a method, the normal “double definition” error ensues, on the other hand the synthetic methods override methods from mixed in traits unconditionally.
From this I conclude that one desirable improvement would be to leave out generation if a method of the same signature already exists. This would allow calling e.g. super.x in the above case.
Considering the shadowing of inherited methods, it would be nice if a warning could be emitted, possibly suppressible by annotating the @proxy annotation.
Regards,
Roland
PS: I LOVE :javap!!!D
boisvert
Joined: 2009-11-11,
User offline. Last seen 38 weeks 5 days ago.
Re: Announcing autoproxy-lite
On Wed, Apr 6, 2011 at 11:44 AM, Roland Kuhn <google@rkuhn.info> wrote:
So, to summarize, the @proxy desugars quite literally to the methods being defined in the containing class. If there is already such a method, the normal “double definition” error ensues, on the other hand the synthetic methods override methods from mixed in traits unconditionally.
From this I conclude that one desirable improvement would be to leave out generation if a method of the same signature already exists. This would allow calling e.g. super.x in the above case.
Considering the shadowing of inherited methods, it would be nice if a warning could be emitted, possibly suppressible by annotating the @proxy annotation.

Thanks Roland, you answered my question nicely.
alex

Copyright © 2012 École Polytechnique Fédérale de Lausanne (EPFL), Lausanne, Switzerland