groovy-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Graeme Rocher <graeme.roc...@gmail.com>
Subject Re: Proposal: Statically compileable builders
Date Tue, 04 Oct 2016 16:00:49 GMT
The use case is really around builders, not so much around regular objects.

Builders don't really use return types that much, but if you did want
return type information we could support methodMissing that return a
concrete type. Typical builder code that could be statically compiled

def json = new StreamingJsonBuilder()

json.message {
     title "Hello World"
}

Note return types don't play a factor much here. If you combine this
will my other proposal around allowing delegates to on maps you can
see that you could implement markup builder for static compilation

mkp.html {
      body {
           div id:"test"
      }
}

What you gain is performance, statically compiled builders will be
much faster because Groovy throws exceptions during method dispatch
(to resolve closure properties). Statically compiled code will give
you direct method dispatch to the method, whilst dynamic code will go
directly to invokeMethod. We see large performance gains when using
statically compiled JSON views due to:

https://github.com/grails/grails-views/blob/master/core/src/main/groovy/grails/views/compiler/BuilderTypeCheckingExtension.groovy

Cheers

On Tue, Oct 4, 2016 at 5:43 PM, Jochen Theodorou <blackdrag@gmx.org> wrote:
>
>
> On 04.10.2016 16:32, Graeme Rocher wrote:
> [...]
>>
>> I would like to propose adding the ability to create builders that can
>> be statically compiled by adding a capability similar to Scala's
>> Dynamic:
>>
>> https://issues.apache.org/jira/browse/GROOVY-7957
>
>
> the question is what you really gain from that... let us assume it is enough
> to annotate a class with @SDyn to make every use of it like you describe:
>
>
> @SDyn
> class Foo {
>   String bar(int i) {"i"}
>   def methodMissing(String s, Object args){ null }
> }
>
> @CompileStatic
> def test() {
>   def foo = new Foo()
>   String s1 = foo.bar(1)  // (1)
>   String s2 = foo.foo()   // (2)
>   def s3 = foo.bar("")    // (3)
> }
>
>
> (1), here we get the compile time checks for the existance of a method
> bar(int) as well as that the declared type of s1 and the return type of bar
> fit together
>
> (2) would compile against using methodMissing, but the result will be
> Object, so this will fail compilation
>
> (3) would compile using methodMissing, since bar(String) is not bar(int).
> This behaviour is in line with the dynamic methodMissing behavior, but not
> with the one from Scala.
>
>
> In other words, for static compilation you will not get any useful return
> types, you will not really get a faster builder and you will not gain
> protection against typos. I don't even see auto-completion in IDEs as pro
> argument here, since @DelegatesTo is in theory enough for that already. And
> if you start nesting in your builder you will have to write methods for it,
> otherwise you have no place for a @DelegatesTo.
>
> So I guess the goal of this feature needs a bit more discussion.
>
> bye Jochen
>
>



-- 
Graeme Rocher

Mime
View raw message