But the call to Foo#baz() coud return an e.g. GroovyVoidObject instance, which in turn throws a "cannot return void from method" if that happens to be the last expression in your example, no ? It feels like returning null here is just a stopgap, not anything one actually wants to have in the language...

I don't expect the dynamic compiler to be changed, but should we really mirror the dynamic comiler behavior in the static compiler in this case ? I think it would be much more least surprise in the @CompileStatic case...

Cheers,
mg

PS: Calling void methods better be fine, otherwise why do they exist in the first place ;-)  - I am/was always referring to my initial question, so the whole thread is about expecting/using void method call results somewhere...


On 04.09.2018 01:41, Paul King wrote:
Calling void methods is fine. Expecting a result is the point in question.

For dynamic Groovy, you can't always tell which case you have:

class Foo {
  def bar() { 42 }
  void baz() { }
}

def method(boolean condition, delegate, meth1, meth2) {
  if (condition) delegate."$meth1"()
  else delegate."$meth2"()
}

println method(true, new Foo(), 'bar', 'baz') // 42
println method(false, new Foo(), 'bar', 'baz') // null

Here, "method" is expecting to return some value that happens to be the last expression, i.e. the result of the if/then/else expression, so we return null in such cases.

Cheers, Paul.


On Tue, Sep 4, 2018 at 7:38 AM MG <mg...@arscreat.com <mailto:mg...@arscreat.com>> wrote:

    What I meant was: What sense does letting void methods be called make
    for the dynamic case, i.e. the dynamic compiler ? From a programmer's
    perspective, i.e. what is a programming use case for that
    feature/behavior, in dynamic Groovy ?

    Of course I can do the following in dynamic Groovy:

    // Groovy 2.5.0
    class Goo {
         //void nogoo() { return 123 } // Dynamic Groovy compiler:
    RuntimeParserException: Cannot use return statement with an
    expression on a method that returns void
         void nogoo() { 123 }
    }

    final goo = new Goo()

    println "original: goo.nogoo()=${goo.nogoo()}"

    goo.metaClass.nogoo = { return 456 }

    println "mopped: goo.nogoo()=${goo.nogoo()}"


    Which will build, run, and output

    original: goo.nogoo()=null
    mopped: goo.nogoo()=456

      i.e. returning 456 from a void method in the second case.
    But if I am using a library that includes the Goo class, why would I
    ever expect a return value from the nogoo method (and therefore call
    it), considering its return type is void ? And if I control the Goo
    class myself, why would I not just change its return type to int
    or def ?

    Cheers,
    mg


    On 03.09.2018 22:36, Jochen Theodorou wrote:
    > On 03.09.2018 17:13, mg wrote:
    >> But in what scenario does the dynamic behavior make sense ?
    >
    > for a static compiler? none other than being compatible
    >
    > bye Jochen
    >


Reply via email to