You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@groovy.apache.org by "Paul King (JIRA)" <ji...@apache.org> on 2017/02/11 01:41:42 UTC

[jira] [Commented] (GROOVY-8071) 1st Class Messages

    [ https://issues.apache.org/jira/browse/GROOVY-8071?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=15862136#comment-15862136 ] 

Paul King commented on GROOVY-8071:
-----------------------------------

Do you have any more real-world examples? Or can you point to other languages that support this?

I think the idea is novel and worthy of consideration but you can accomplish similar results using existing language features:
{code}
def bar = 'Bar'

// method closure
def barCharAt = bar.&charAt
assert barCharAt(0) == 'B'
// method closure and curry
def barMiddle = barCharAt.curry(1)
assert barMiddle() == 'a'

// dynamic method call
def methods = ['length', 'isEmpty']
assert methods.collect{ bar."$it"() } == [3, false]

// roll your own - second class messages
def arg = 2
def message = [name:'charAt', arg:arg]
assert 'Cat'."$message.name"(message.arg) == 't'

// rehydrate trick to defer object selection
def foo = 'Foo'
def fooCharAt = barCharAt.rehydrate(foo, foo, foo)
assert fooCharAt(0) == 'F'

// cross-product (could be combined with above features/tricks)
assert ['d', 3, 'f', 4] ==
  ['dog', 'fish'].collectMany{ [it.charAt(0), it.size()] }
{code}
I think we'd have to make a good case for why we'd add this additional complexity to the language.

> 1st Class Messages
> ------------------
>
>                 Key: GROOVY-8071
>                 URL: https://issues.apache.org/jira/browse/GROOVY-8071
>             Project: Groovy
>          Issue Type: Improvement
>            Reporter: Suminda Dharmasena
>
> Just like the spread operator it would be good to have something similar to saving and calling function.
> E.g.
> ```
> def aCall = .equals(obj1)
> obj2.*aCall(obj1) // same as obj2.equals(obj1)
> ```
> Deciding to call and placing the call happens in 2 different instances.
> ```
> def l1 = [ .f1(a), .f2(b)]
> myObj.*l1
> // similarly
> myObj.*[ .f1(a), .f2(b)]
> myObj.*[ .f1 : a, .f2 : b]
> ```
> Calls both f1 and f2 and return the results as a list of 2 items.
> ```
> [obj1, obj2].*f1()
> ```
> Call f1 on both objects. Same as spread, but
> ```
> [obj1, obj2].*[.f1(), .f2()]
> ```
> Calls f1 and f2 on obj1 followed by obj2 returning nested list of the 2 values.
> ```
> [ Obj1.f1 : a, Obj1.f : b].*[.f3: c, .f4 : d]
> ```
> Call returning [Obj1.f1(a).f3(c), Obj1.f1(a).f4(d), Obj2.f2(b).f3(c), Obj2.f2(b).f4(d)]
> If you do not want to complete cross product you can have another operator say `.**` to mean you call on the objects on the corresponding index. Or you can have this as `.*` and `.**` for the full cross product.



--
This message was sent by Atlassian JIRA
(v6.3.15#6346)