(Sorry, first version went out too soon, thanks to the silly, silly Touch Bar)
> On 31 Jan 2018, at 23.01, MG <mg...@arscreat.com> wrote: > > Hi Jesper, > > seen from a Groovy user perspective your proposal seems to make sense to me. > (I would at the same time hope you do not dent Daniel Sun's enthusiasm too > much, because as far as I can tell he is currently doing alot of the heavy > lifting in this project :-) ) > Yes, he is - and the lambda work has come a long way - I'm testing some scenarios, so i hope to lift a little, too! > How do you think what you propose fares with regards to "the principle of > least surprise" ? Are there any cases where this could lead to hard to track > bugs / unexpected behavior ? From the top of my hat, that would be my biggest > concern... I see static and dynamic as different concerns: For dynamic invocation, there could be some surprises, like example posted by 'avafanasiev' on GitHub: class R implements Runnable { void run(){}} def m(Runnable r1, R r2, r3) { r1() r2() r3() } m(new R(), new R(), new R()) Currently, in the 'native-lambda' branch, r1() succeeds, whereas the latter two fail to run/compile (depending on dynamic/static compilation), as 'avafanasiev' commented on. I do find that confusing: Dynamically, my opinion is that the three should work the same. For static compilation, r1() and r2() should work IMHO, and r3() should be rejected. This shouldn't surprise anyone, I think. Also, surprise-wise, consider: class Q implements Runnable, Supplier<String> { void run(){}; String get() { "Q" } } def n(Runnable q1, Supplier <String> q2, Q q2, q3) { q1() q2() q3() q4() } n(new Q(), new Q(), new Q(), new Q()) I'm thinking that all four should FAIL dynamically, but statically, q1 and q2 should work, using the appropriate interface. > "...only as a fallback if obj.call doesn't exist" seems like the safer > choice in this regard. Default behavior could also be made overridable by a > class annotation (then it would become the programmer's responsibility, to > make sure least surprise is not violated). > Without that the question to me is: Would choosing "fallback if obj.call > doesn't exist" weaken the elegance of the whole concept too much ? I don't think it would weaken the elegance. We hardly need annotations - we could simply use the presence of GroovyCallable to find out which objects would prefer to be call()'ed directly. -Jesper