return type for closures

619 views
Skip to first unread message

jct

unread,
Feb 3, 2011, 6:07:22 PM2/3/11
to Groovy++
Hi,

Is there a way to specify the return type of a closure in groovy++?

Roshan Dawrani

unread,
Feb 4, 2011, 12:28:59 AM2/4/11
to groovyp...@googlegroups.com
Does it help (http://gppconsole.appspot.com/script/16001)?

========================================
@Typed package test

Function0<String"hello" }

def r(// type of x inferred from Closure return type

​assert x.toUpperCase()​ == 'HELLO'
========================================

On Fri, Feb 4, 2011 at 4:37 AM, jct <groo...@gmail.com> wrote:
Hi,

Is there a way to specify the return type of a closure in groovy++?



--
Roshan
Blog: http://roshandawrani.wordpress.com/
Twitter: @roshandawrani
Skype: roshandawrani

Alex Tkachman

unread,
Feb 4, 2011, 5:10:38 AM2/4/11
to groovyp...@googlegroups.com
You can do even better - use def instead of Closure

http://gppconsole.appspot.com/script/17001

@Typed package test

def r = { "hello" }

def x = r() // type of x inferred from Closure return type

assert x.toUpperCase() == 'HELLO'

jct

unread,
Feb 4, 2011, 7:53:15 PM2/4/11
to Groovy++
If I want to explicitly declare the return type of a closure, would it
be like this?
Closure<T> closure = { ... return T; }

What is the difference between Function0 and Closure?

How does groovy++ handle closures that can return different return
types?
For example:
@Typed
...
Closure closure = { Boolean b -> if (b) return 123; else return
"abc"; }

On Feb 4, 2:10 am, Alex Tkachman <alex.tkach...@gmail.com> wrote:
> You can do even better - use def instead of Closure
>
> http://gppconsole.appspot.com/script/17001
>
> @Typed package test
>
> def r = { "hello" }
>
> def x = r() // type of x inferred from Closure return type
>
> assert x.toUpperCase() == 'HELLO'
>
> On Fri, Feb 4, 2011 at 8:28 AM, Roshan Dawrani <roshandawr...@gmail.com> wrote:
> > Does it help (http://gppconsole.appspot.com/script/16001)?
> > ========================================
> > @Typed package test
>
> > Function0<String> r = { "hello" }
>
> > def x = r() // type of x inferred from Closure return type
>
> > assert x.toUpperCase() == 'HELLO'
> > ========================================

Roshan Dawrani

unread,
Feb 4, 2011, 10:56:18 PM2/4/11
to groovyp...@googlegroups.com
On Sat, Feb 5, 2011 at 6:23 AM, jct <groo...@gmail.com> wrote:
If I want to explicitly declare the return type of a closure, would it
be like this?
Closure<T> closure = { ... return T; }

No, it wouldn't be - because Groovy 1.7.x's Closure class is not generic

1.8.x onwards, Groovy's Closure is generic (Closure<V>, where V is the return type) - but for that you will need to wait because core groovy will not do static type checking on the return type, so you will not get what you are looking for. 

When Groovy++ provides a version that is based on Groovy 1.8.x, you will be able to do it, but Groovy 1.8.RC-x has to get released as an officially stable version first.
 

What is the difference between Function0 and Closure?

Function0<R> is equivalent of a Closure that takes no parameters and has return type R

Similarly Function1<T, R> is equivalent of a Closure that takes 1 parameter of type T and has return type R. Here is an example that shows static typing working for both the input parameter and the return value (Experiment on Groovy++ Console here)

Roshan Dawrani

unread,
Feb 4, 2011, 11:11:07 PM2/4/11
to groovyp...@googlegroups.com
On Sat, Feb 5, 2011 at 6:23 AM, jct <groo...@gmail.com> wrote:
How does groovy++ handle closures that can return different return
types?

Then Groovy++ type inferencing looks at return types at all possible return paths and identifies the best parent type that it common to them all and uses that as the return type. Here is an example

============================================================
@Typed package test

def cl = {hint -> 
    if(hint == 1) 
        new B()
    else {
        new C()
    }
}

def x = cl(2)

// allowed because type inference logic finds type A as the common type
x.foo()

// following will give a compilation error because of reason explained above
// x.bar()

class A {
    def foo(){'foo'}
}

class B extends A {
    def bar(){'bar'}
}

class C extends A {
    def baz(){'baz'}
}
============================================================
Reply all
Reply to author
Forward
0 new messages