Re: [gwt-contrib] RR: Two key GWT.create to avoid boilerplate
You know, we could get a lot of mileage and zero config out of... GWT.generateWith(UiBinder.class, optional, varargs, list, of, arbitrary, literals) :) On Sat, Feb 13, 2010 at 7:39 PM, Ray Ryan rj...@google.com wrote: Please, let's move the discussion to the issue tracker so it doesn't get lost. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] RR: Two key GWT.create to avoid boilerplate
On Sat, Feb 13, 2010 at 6:22 PM, Ray Cromwell cromwell...@gmail.com wrote: I'm not sure how my proposal creates more boilerplate, it adds the ability to specify arbitrary parameters to GWT.create, e.g. GWT.create(A.class, LiteralParam1, LiteralParam2, ...) Sweet. It looks like everyone is in favor of this part. Unless someone speaks to the contrary, it sounds like the lights are green for this one, as soon as someone has time to do it. public class MyLibrary { @GwtCreate public static T T create(Class? clazz) { return GWT.create(clazz); } } Usage: MyLibrary.create(Binder.class); This part has the down side that it requires a special class loader for it to work. To contrast, GWT.create can be intercepted using regular Java code by using GWT.setBridge. This has proven useful for writing test cases. It would be very helpful to refine this to the point that it doesn't strictly require using a special class loader. For example, maybe we could insist (and verify) that the body of one of these methods has the dev mode implementation, and that it is in a stylized form ? Also, the proposal on the blog entry mentions a variation of @GwtCreate that takes the generator as an argument: @GwtCreate(generator=com.foo.BarGenerator.class) T extends Bar T create(ClassT clazz) This version looks at odds with the way deferred binding normally works. Normally, the module file chooses the generator, and it can even choose a different generator for each permutation of the compile. For this, let's try and come up with a way to distinguish the separate interface types inherited by clazz. It might not even be necessary, though. Note that when looking at the above create() call, the supplied clazz argument has already been upcast to the Bar interface. Thus, even though the original class implemented Bar as well as a bunch of other generatable interfaces, this particular call should be deferred bound however Bar is deferred bound. Lex -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] RR: Two key GWT.create to avoid boilerplate
Actually, to tell you the truth…I can't figure out what you're actually proposing there. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] RR: Two key GWT.create to avoid boilerplate
Gotcha, neato. Is that explanation actually in the blog post you linked to? On Sat, Feb 13, 2010 at 3:22 PM, Ray Cromwell cromwell...@gmail.com wrote: I'm not sure how my proposal creates more boilerplate, it adds the ability to specify arbitrary parameters to GWT.create, e.g. GWT.create(A.class, LiteralParam1, LiteralParam2, ...) That's the first thing it does which is the same as your proposal. The generator can then look at the supplied parameters as well as the requested type. The second thing it allows you to do is bless any static method method of your choice as a GWT.create() equivalent. Consider the identity case: public class MyLibrary { @GwtCreate public static T T create(Class? clazz) { return GWT.create(clazz); } } Usage: MyLibrary.create(Binder.class); That is, you make cause any static method of the right signature to have the same compile time constraints as GWT.create(), with the added bonus that you may invoke GWT.create() inside of such methods with non-literal parameters, because the enclosing method parameters are guaranteed to be literals. I think I provided more than enough use-cases to justify why you'd want this. Currently, GWT.create() has many problems besides lack of parameterization: 1) Return type is not statically checked, so one cannot write type-safe methods that invoke GWT.create() 2) One can't check parameters to GWT.create(), so for example, if you want to create a UIBinder, and you accidently pass a non-UIBinder type, it silently gets deferred bound, and you won't catch the error until runtime when the cast is attempted. 3) If a class has more than 2 tagging interfaces, you can't decide which generator to run. The current situation makes it very hard to write idiomatic Java helper functions with proper type signatures and forces one to sprinkle GWT.create() calls through out one's code because you can't delegate creation. -Ray On Sat, Feb 13, 2010 at 3:09 PM, Ray Ryan rj...@google.com wrote: My goal is less boilerplate. While this looks cool and offers more flexibility, it takes me farther from that goal. These seem like orthogonal concerns to me. On Sat, Feb 13, 2010 at 3:05 PM, Ray Cromwell cromwell...@gmail.com wrote: Ray, I like this idea, but I feel it is not general enough to cover all the use cases. Now that Bob has added support for Annotations in the AST, I feel like it is time to revive this proposal: http://timepedia.blogspot.com/2009/03/relaxing-constraints-on-gwtcreate.html Which covers your case, but also the general case of writing library functions that can provide better type signatures that GWT.create(), as well as the ability to override the type of generator run. It wouldn't be hard to implement, the first time I looked at implementing it, it was actually lack of annotations in the AST that was a road block. -Ray On Sat, Feb 13, 2010 at 12:51 PM, Ray Ryan rj...@google.com wrote: I hate the boilerplate required in UiBinder owners: interface MyBinder extends UiBinderWidget, Me; private static final MyBinder binder = GWT.create(MyBinder.class); A two part fix comes to mind. Create a two argument overload of GWT.create, and eliminate one of the type params for UiBinder. /** Create an instance of T tailored to the needs of forClass */ public static T T create(Class? makeClass, Class? forClass) That lets me tell the Foo generator to create, say, a FooBar for my Bar to use. Or a Foo_Impl_For_Bar. Or whatever. The point is that I'm providing two keys to the generator. The first determines what generator is run, just as today, and the optional second gives me channel to pass configuration information to the generator without being forced to extend an interface or abstract class that isn't useful to me. On the UiBinder side, we can relax the arbitrary requirement that UiBinder have a single child and make the create...() method have a void return. For backward compatibility, we introduce a new super interface with these changes: interface UiBinderU, O extends BinderU, O { ... } interface BinderO { void createFor(O owner); } With this, we can reduce binder boilerplate to private static final Binder = GWT.create(UiBinder.class, Me.class); Well? rjrjr -- I wish this were a Wave -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- I wish this were a Wave -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- http://groups.google.com/group/Google-Web-Toolkit-Contributors -- I wish this were a Wave -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] RR: Two key GWT.create to avoid boilerplate
Probably not, I think that blog post is out of context since the discussion started on GWTC, so my apologies. It started with my frustration that I couldn't make GIN's API look more like Guice when the only issue was the ability to be able to parameterize the inject() method and rename it from create() to inject(). The other frustration was I was attempting to enhance RPC services with side-band auth data for OpenSocial and got irritated by the need to inline an interface and GWT.create() call when all I really wanted as to say something like: MyServiceAsync async = OAuth.authorize(MyService.class, credentials); or OAuth.authorize(MyService.class, credentials).method(param1, new AsyncCallback() { ... } ); When looking through the AST, I saw as how GWT.create() as represented as a JGwtCreate node, and I was like why is GWT.create() magic? Couldn't we just bless any static method and have it end up as a JGwtCreate node?). Matt Mattrascci came up with a clever transform/implementation too that preserves all normal GWT.create() and really just makes this compile time syntactic sugar, but the roadblock was the fact that everytime you want to do anything with a new Annotation in the compiler, you had to become a JDT wizard. :( -Ray On Sat, Feb 13, 2010 at 3:30 PM, Ray Ryan rj...@google.com wrote: Gotcha, neato. Is that explanation actually in the blog post you linked to? On Sat, Feb 13, 2010 at 3:22 PM, Ray Cromwell cromwell...@gmail.com wrote: I'm not sure how my proposal creates more boilerplate, it adds the ability to specify arbitrary parameters to GWT.create, e.g. GWT.create(A.class, LiteralParam1, LiteralParam2, ...) That's the first thing it does which is the same as your proposal. The generator can then look at the supplied parameters as well as the requested type. The second thing it allows you to do is bless any static method method of your choice as a GWT.create() equivalent. Consider the identity case: public class MyLibrary { @GwtCreate public static T T create(Class? clazz) { return GWT.create(clazz); } } Usage: MyLibrary.create(Binder.class); That is, you make cause any static method of the right signature to have the same compile time constraints as GWT.create(), with the added bonus that you may invoke GWT.create() inside of such methods with non-literal parameters, because the enclosing method parameters are guaranteed to be literals. I think I provided more than enough use-cases to justify why you'd want this. Currently, GWT.create() has many problems besides lack of parameterization: 1) Return type is not statically checked, so one cannot write type-safe methods that invoke GWT.create() 2) One can't check parameters to GWT.create(), so for example, if you want to create a UIBinder, and you accidently pass a non-UIBinder type, it silently gets deferred bound, and you won't catch the error until runtime when the cast is attempted. 3) If a class has more than 2 tagging interfaces, you can't decide which generator to run. The current situation makes it very hard to write idiomatic Java helper functions with proper type signatures and forces one to sprinkle GWT.create() calls through out one's code because you can't delegate creation. -Ray On Sat, Feb 13, 2010 at 3:09 PM, Ray Ryan rj...@google.com wrote: My goal is less boilerplate. While this looks cool and offers more flexibility, it takes me farther from that goal. These seem like orthogonal concerns to me. On Sat, Feb 13, 2010 at 3:05 PM, Ray Cromwell cromwell...@gmail.com wrote: Ray, I like this idea, but I feel it is not general enough to cover all the use cases. Now that Bob has added support for Annotations in the AST, I feel like it is time to revive this proposal: http://timepedia.blogspot.com/2009/03/relaxing-constraints-on-gwtcreate.html Which covers your case, but also the general case of writing library functions that can provide better type signatures that GWT.create(), as well as the ability to override the type of generator run. It wouldn't be hard to implement, the first time I looked at implementing it, it was actually lack of annotations in the AST that was a road block. -Ray On Sat, Feb 13, 2010 at 12:51 PM, Ray Ryan rj...@google.com wrote: I hate the boilerplate required in UiBinder owners: interface MyBinder extends UiBinderWidget, Me; private static final MyBinder binder = GWT.create(MyBinder.class); A two part fix comes to mind. Create a two argument overload of GWT.create, and eliminate one of the type params for UiBinder. /** Create an instance of T tailored to the needs of forClass */ public static T T create(Class? makeClass, Class? forClass) That lets me tell the Foo generator to create, say, a FooBar for my Bar to use. Or a Foo_Impl_For_Bar. Or whatever. The point is that I'm providing two keys to the generator. The first determines
Re: [gwt-contrib] RR: Two key GWT.create to avoid boilerplate
http://code.google.com/p/google-web-toolkit/issues/detail?id=4623 -- http://groups.google.com/group/Google-Web-Toolkit-Contributors
Re: [gwt-contrib] RR: Two key GWT.create to avoid boilerplate
BTW, Scott proposed an even more general mechanism, the idea that you could designate any expression and having to be done at compile time. A classic example would be something like String.format(), for example public class Formatter { @CompileTime(mypackage.compiletime.FormatterEval.class) public String format(String pattern, String... args) { // case where all parameters are NOT known at compile time } } In this case,if all parameters are guaranteed to be literals or known as constants at compile time, then the FormatterEval class will be invoked which returns a literal value which is inlined at the callsite. If all types are not known as constant literals, the fallback body is used. -Ray On Sat, Feb 13, 2010 at 3:30 PM, Ray Ryan rj...@google.com wrote: Gotcha, neato. Is that explanation actually in the blog post you linked to? On Sat, Feb 13, 2010 at 3:22 PM, Ray Cromwell cromwell...@gmail.com wrote: I'm not sure how my proposal creates more boilerplate, it adds the ability to specify arbitrary parameters to GWT.create, e.g. GWT.create(A.class, LiteralParam1, LiteralParam2, ...) That's the first thing it does which is the same as your proposal. The generator can then look at the supplied parameters as well as the requested type. The second thing it allows you to do is bless any static method method of your choice as a GWT.create() equivalent. Consider the identity case: public class MyLibrary { @GwtCreate public static T T create(Class? clazz) { return GWT.create(clazz); } } Usage: MyLibrary.create(Binder.class); That is, you make cause any static method of the right signature to have the same compile time constraints as GWT.create(), with the added bonus that you may invoke GWT.create() inside of such methods with non-literal parameters, because the enclosing method parameters are guaranteed to be literals. I think I provided more than enough use-cases to justify why you'd want this. Currently, GWT.create() has many problems besides lack of parameterization: 1) Return type is not statically checked, so one cannot write type-safe methods that invoke GWT.create() 2) One can't check parameters to GWT.create(), so for example, if you want to create a UIBinder, and you accidently pass a non-UIBinder type, it silently gets deferred bound, and you won't catch the error until runtime when the cast is attempted. 3) If a class has more than 2 tagging interfaces, you can't decide which generator to run. The current situation makes it very hard to write idiomatic Java helper functions with proper type signatures and forces one to sprinkle GWT.create() calls through out one's code because you can't delegate creation. -Ray On Sat, Feb 13, 2010 at 3:09 PM, Ray Ryan rj...@google.com wrote: My goal is less boilerplate. While this looks cool and offers more flexibility, it takes me farther from that goal. These seem like orthogonal concerns to me. On Sat, Feb 13, 2010 at 3:05 PM, Ray Cromwell cromwell...@gmail.com wrote: Ray, I like this idea, but I feel it is not general enough to cover all the use cases. Now that Bob has added support for Annotations in the AST, I feel like it is time to revive this proposal: http://timepedia.blogspot.com/2009/03/relaxing-constraints-on-gwtcreate.html Which covers your case, but also the general case of writing library functions that can provide better type signatures that GWT.create(), as well as the ability to override the type of generator run. It wouldn't be hard to implement, the first time I looked at implementing it, it was actually lack of annotations in the AST that was a road block. -Ray On Sat, Feb 13, 2010 at 12:51 PM, Ray Ryan rj...@google.com wrote: I hate the boilerplate required in UiBinder owners: interface MyBinder extends UiBinderWidget, Me; private static final MyBinder binder = GWT.create(MyBinder.class); A two part fix comes to mind. Create a two argument overload of GWT.create, and eliminate one of the type params for UiBinder. /** Create an instance of T tailored to the needs of forClass */ public static T T create(Class? makeClass, Class? forClass) That lets me tell the Foo generator to create, say, a FooBar for my Bar to use. Or a Foo_Impl_For_Bar. Or whatever. The point is that I'm providing two keys to the generator. The first determines what generator is run, just as today, and the optional second gives me channel to pass configuration information to the generator without being forced to extend an interface or abstract class that isn't useful to me. On the UiBinder side, we can relax the arbitrary requirement that UiBinder have a single child and make the create...() method have a void return. For backward compatibility, we introduce a new super interface with these changes: interface UiBinderU, O extends BinderU, O {
Re: [gwt-contrib] RR: Two key GWT.create to avoid boilerplate
Please, let's move the discussion to the issue tracker so it doesn't get lost. -- http://groups.google.com/group/Google-Web-Toolkit-Contributors