You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@groovy.apache.org by Paolo Di Tommaso <pa...@gmail.com> on 2016/05/28 16:26:37 UTC

Add a marker interface to bypass Collections and Maps formatting

Hi all,

Groovy implements a built-in formatting strategy for collection and map
objects that is surely nicer and more useful than the one provided by the
default Java implementation for these classes.

However there are use cases in which custom collection or map classes need
to implement their own formatting rule.

Currently in Groovy this is quite painful and may lead to inconsistent
results. Take in consideration the following example:

class MyList extends ArrayList {
 String toString() {
    this.join('-')
  }
}

def x = new MyList()
x << 1 << 2 << 3

println x.toString()
println x
println "$x"

Which prints:

1-2-3
[1, 2, 3]
[1, 2, 3]

Both the second and third `println` use the Groovy built-in formatting
method and there's no easy way to override this behaviour. Also there's not
a clear reason why the first and the second print return a different
output.

The only options I've found is to define `MyList` with a @Delegate without
implementing the `List` interface. But this leads to other weird side
effects. The remaining possibility is to use some bytecode manipulation to
bypass the default Groovy formatting, but it looks to me a really
overkilling solution for such problem.

For this reason a would like to propose to introduce a mechanism that would
allow custom collection and map classes to bypass the default formatting
method. This should not be too difficult. The current Groovy built-in
formatting is implemented by formatList
<https://github.com/apache/groovy/blob/master/src/main/org/codehaus/groovy/runtime/InvokerHelper.java#L678-L712>
and formatMap
<https://github.com/apache/groovy/blob/master/src/main/org/codehaus/groovy/runtime/InvokerHelper.java#L641-L668>
methods.

It would be enough to add a marker interface (or an annotation) that when
applied to a class it would be used to by-pass the logic in the formatList
and formatMap methods and simply return the string provided by the object
`toString` method.


I could easily contribute this patch however I would know the opinion of
the Groovy core committers. In particular:

1) What name should have this marker interface? groovy.lagn.Something?
2) Are formatList and formatMap methods the right place to add this logic?
3) A similar problem exists also when using the `equals` (and hashCode?)
method for collections and maps. Should this mechanism be extended also to
this case?



Best,
Paolo

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paolo Di Tommaso <pa...@gmail.com>.
I want to report an update on the status of this issue. In the conversation
in the GitHub pull request <https://github.com/apache/groovy/pull/566> I
was requested to perform a benchmark to evaluate  the impact of this
change.

The results are showed below:

Benchmark                        (size)   Mode  Cnt        Score
Error   Units
ListBench.equalsDefaultGroovy         1  thrpt   15  2320508.042 ±
84277.415  ops/ms
ListBench.equalsDefaultGroovy        10  thrpt   15  2329172.399 ±
69070.211  ops/ms
ListBench.equalsDefaultGroovy       100  thrpt   15  2354738.681 ±
64525.890  ops/ms
ListBench.equalsDefaultGroovy      1000  thrpt   15  2358917.549 ±
46171.873  ops/ms
ListBench.equalsDefaultGroovy   1000000  thrpt   15  2377102.274 ±
48227.814  ops/ms
ListBench.equalsWithAnnotation        1  thrpt   15  2213530.048 ±
93671.364  ops/ms
ListBench.equalsWithAnnotation       10  thrpt   15  2277729.772 ±
89214.824  ops/ms
ListBench.equalsWithAnnotation      100  thrpt   15  2256582.572 ±
85712.999  ops/ms
ListBench.equalsWithAnnotation     1000  thrpt   15  2266409.619 ±
45408.683  ops/ms
ListBench.equalsWithAnnotation  1000000  thrpt   15  2197481.973 ±
127202.807  ops/ms
ListBench.equalsWithInterface         1  thrpt   15  2155416.804 ±
80496.840  ops/ms
ListBench.equalsWithInterface        10  thrpt   15  2061873.464 ±
211658.982  ops/ms
ListBench.equalsWithInterface       100  thrpt   15  2106467.218 ±
89659.046  ops/ms
ListBench.equalsWithInterface      1000  thrpt   15  2219947.677 ±
87623.149  ops/ms
ListBench.equalsWithInterface   1000000  thrpt   15  2092834.055 ±
165819.668  ops/ms
ListBench.equalsDefaultGroovy         1   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsDefaultGroovy        10   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsDefaultGroovy       100   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsDefaultGroovy      1000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsDefaultGroovy   1000000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation        1   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation       10   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation      100   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation     1000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithAnnotation  1000000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface         1   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface        10   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface       100   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface      1000   avgt   15       ≈ 10⁻⁶
    ms/op
ListBench.equalsWithInterface   1000000   avgt   15       ≈ 10⁻⁶
    ms/op


The benchmark code is available at this link
<https://github.com/apache/groovy/compare/master...pditommaso:jmh-list-equals-benchmark>.
These numbers suggest that checking the class annotation in the
`DefaultGroovyMethods.equals` method adds an overhead of ~5%, doing the
same with a marker interface ~10%.


What do you think ?


p



On Fri, Jan 26, 2018 at 3:21 PM, Paolo Di Tommaso <paolo.ditommaso@gmail.com
> wrote:

> I agree. The name @GroovyOverride sounds a good option.
>
>
>
> Cheers,
> Paolo
>
>
> On Thu, Jan 25, 2018 at 11:53 PM, MG <mg...@arscreat.com> wrote:
>
>> This looks like something that might be useful in certain scenarios. A
>> "perfect fix" would always be better, but since that might be some time off
>> (2019 being optimistic - some of the things I want Groovy to improve in
>> date back to at least 2006)...
>>
>> My only question would be, if it would perhaps make sense to introduce a
>> more generically named annotation (@AutomatismOverride, @GroovyOverride,
>> @Configuration,...), that would allow overriding/fine-tuning many of
>> Groovy's automatisms through different parameters, to avoid an
>> annotation-explosion over time ?
>>
>> mg
>>
>>
>> On 23.01.2018 09:25, Paolo Di Tommaso wrote:
>>
>> Hi all,
>>
>> I want to take the opportunity to renew my proposal and PR to add an
>> annotation that allows the override of the Groovy default formatting for
>> certain classes.
>>
>> https://github.com/apache/groovy/pull/566
>>
>>
>> To quickly remind you what the problem is, Groovy provides a nice default
>> formatting for some classes i.e. String, Map, and Collection data
>> structures which is good. But it makes impossible to override it by
>> sub-classes that implements their own toString method. The same problem for
>> the `equals` method. This makes difficult to handle some specific use
>> cases, leaving bytecode manipulation as the only alternative.
>>
>>
>> My proposal is to add an annotation named @IgnoreDefaultEqualsAndToString
>> (or maybe @OverrideEqualsAndToString) to bypass the Groovy formatting and
>> allow the invocation of sub-classes `toString` and `equals` methods.
>>
>> I agree that's a sub-optional solution, however no better solutions have
>> been proposed for the current and future releases.
>>
>>
>>
>> Cheers,
>> Paolo
>>
>>
>>
>> On Sun, Jun 25, 2017 at 8:35 PM, Paolo Di Tommaso <
>> paolo.ditommaso@gmail.com> wrote:
>>
>>> Dear all,
>>>
>>> Groovy still does not provide a mechanism to override the `toString` and
>>> `equals` methods for custom Collection and Map objects. This is a serious
>>> limitation in some use cases.
>>>
>>> I'm proposing with the following pull request to introduce a marker
>>> annotation that allows a custom object to use the `toString` and `equals`
>>> as expected.
>>>
>>> https://github.com/apache/groovy/pull/566
>>>
>>>
>>> Any comment or improvement is welcome.
>>>
>>>
>>> Cheers,
>>> Paolo
>>>
>>>
>>> On Thu, Jun 2, 2016 at 1:38 AM, Paul King <pa...@asert.com.au> wrote:
>>>
>>>> I am +1 on improving how we handle formatting for lists and maps. My
>>>> default position would be -1 on an implementation that smells like it
>>>> might be "yet another hack" that we have to maintain long term. The
>>>> main reason being that we are trying to streamline method selection
>>>> for our revised MOP (I know not much is happening in that space right
>>>> now) and it would be nicer if once that is done, the "inconsistent"
>>>> results you mention could be handled in an easy to understand way.
>>>> Having said that, if I get time to look into it further and can't
>>>> think of a better way to approach it long term, then I could easily be
>>>> moved to at least a -0.
>>>>
>>>> Cheers, Paul.
>>>>
>>>> On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
>>>> <pa...@gmail.com> wrote:
>>>> > Hello guys,
>>>> >
>>>> > No feedback on this? Would you take in consideration a PR for this
>>>> proposal?
>>>> >
>>>> >
>>>> > Thanks,
>>>> > Paolo
>>>> >
>>>> >
>>>> > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
>>>> > <pa...@gmail.com> wrote:
>>>> >>
>>>> >> Hi all,
>>>> >>
>>>> >> Groovy implements a built-in formatting strategy for collection and
>>>> map
>>>> >> objects that is surely nicer and more useful than the one provided
>>>> by the
>>>> >> default Java implementation for these classes.
>>>> >>
>>>> >> However there are use cases in which custom collection or map
>>>> classes need
>>>> >> to implement their own formatting rule.
>>>> >>
>>>> >> Currently in Groovy this is quite painful and may lead to
>>>> inconsistent
>>>> >> results. Take in consideration the following example:
>>>> >>
>>>> >> class MyList extends ArrayList {
>>>> >>  String toString() {
>>>> >>     this.join('-')
>>>> >>   }
>>>> >> }
>>>> >>
>>>> >> def x = new MyList()
>>>> >> x << 1 << 2 << 3
>>>> >>
>>>> >> println x.toString()
>>>> >> println x
>>>> >> println "$x"
>>>> >>
>>>> >> Which prints:
>>>> >>
>>>> >> 1-2-3
>>>> >> [1, 2, 3]
>>>> >> [1, 2, 3]
>>>> >>
>>>> >> Both the second and third `println` use the Groovy built-in
>>>> formatting
>>>> >> method and there's no easy way to override this behaviour. Also
>>>> there's not
>>>> >> a clear reason why the first and the second print return a different
>>>> output.
>>>> >>
>>>> >> The only options I've found is to define `MyList` with a @Delegate
>>>> without
>>>> >> implementing the `List` interface. But this leads to other weird side
>>>> >> effects. The remaining possibility is to use some bytecode
>>>> manipulation to
>>>> >> bypass the default Groovy formatting, but it looks to me a really
>>>> >> overkilling solution for such problem.
>>>> >>
>>>> >> For this reason a would like to propose to introduce a mechanism that
>>>> >> would allow custom collection and map classes to bypass the default
>>>> >> formatting method. This should not be too difficult. The current
>>>> Groovy
>>>> >> built-in formatting is implemented by formatList and formatMap
>>>> methods.
>>>> >>
>>>> >> It would be enough to add a marker interface (or an annotation) that
>>>> when
>>>> >> applied to a class it would be used to by-pass the logic in the
>>>> formatList
>>>> >> and formatMap methods and simply return the string provided by the
>>>> object
>>>> >> `toString` method.
>>>> >>
>>>> >>
>>>> >> I could easily contribute this patch however I would know the
>>>> opinion of
>>>> >> the Groovy core committers. In particular:
>>>> >>
>>>> >> 1) What name should have this marker interface?
>>>> groovy.lagn.Something?
>>>> >> 2) Are formatList and formatMap methods the right place to add this
>>>> logic?
>>>> >> 3) A similar problem exists also when using the `equals` (and
>>>> hashCode?)
>>>> >> method for collections and maps. Should this mechanism be extended
>>>> also to
>>>> >> this case?
>>>> >>
>>>> >>
>>>> >>
>>>> >> Best,
>>>> >> Paolo
>>>> >>
>>>> >>
>>>> >
>>>>
>>>
>>>
>>
>>
>

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paolo Di Tommaso <pa...@gmail.com>.
I agree. The name @GroovyOverride sounds a good option.



Cheers,
Paolo


On Thu, Jan 25, 2018 at 11:53 PM, MG <mg...@arscreat.com> wrote:

> This looks like something that might be useful in certain scenarios. A
> "perfect fix" would always be better, but since that might be some time off
> (2019 being optimistic - some of the things I want Groovy to improve in
> date back to at least 2006)...
>
> My only question would be, if it would perhaps make sense to introduce a
> more generically named annotation (@AutomatismOverride, @GroovyOverride,
> @Configuration,...), that would allow overriding/fine-tuning many of
> Groovy's automatisms through different parameters, to avoid an
> annotation-explosion over time ?
>
> mg
>
>
> On 23.01.2018 09:25, Paolo Di Tommaso wrote:
>
> Hi all,
>
> I want to take the opportunity to renew my proposal and PR to add an
> annotation that allows the override of the Groovy default formatting for
> certain classes.
>
> https://github.com/apache/groovy/pull/566
>
>
> To quickly remind you what the problem is, Groovy provides a nice default
> formatting for some classes i.e. String, Map, and Collection data
> structures which is good. But it makes impossible to override it by
> sub-classes that implements their own toString method. The same problem for
> the `equals` method. This makes difficult to handle some specific use
> cases, leaving bytecode manipulation as the only alternative.
>
>
> My proposal is to add an annotation named @IgnoreDefaultEqualsAndToString
> (or maybe @OverrideEqualsAndToString) to bypass the Groovy formatting and
> allow the invocation of sub-classes `toString` and `equals` methods.
>
> I agree that's a sub-optional solution, however no better solutions have
> been proposed for the current and future releases.
>
>
>
> Cheers,
> Paolo
>
>
>
> On Sun, Jun 25, 2017 at 8:35 PM, Paolo Di Tommaso <
> paolo.ditommaso@gmail.com> wrote:
>
>> Dear all,
>>
>> Groovy still does not provide a mechanism to override the `toString` and
>> `equals` methods for custom Collection and Map objects. This is a serious
>> limitation in some use cases.
>>
>> I'm proposing with the following pull request to introduce a marker
>> annotation that allows a custom object to use the `toString` and `equals`
>> as expected.
>>
>> https://github.com/apache/groovy/pull/566
>>
>>
>> Any comment or improvement is welcome.
>>
>>
>> Cheers,
>> Paolo
>>
>>
>> On Thu, Jun 2, 2016 at 1:38 AM, Paul King <pa...@asert.com.au> wrote:
>>
>>> I am +1 on improving how we handle formatting for lists and maps. My
>>> default position would be -1 on an implementation that smells like it
>>> might be "yet another hack" that we have to maintain long term. The
>>> main reason being that we are trying to streamline method selection
>>> for our revised MOP (I know not much is happening in that space right
>>> now) and it would be nicer if once that is done, the "inconsistent"
>>> results you mention could be handled in an easy to understand way.
>>> Having said that, if I get time to look into it further and can't
>>> think of a better way to approach it long term, then I could easily be
>>> moved to at least a -0.
>>>
>>> Cheers, Paul.
>>>
>>> On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
>>> <pa...@gmail.com> wrote:
>>> > Hello guys,
>>> >
>>> > No feedback on this? Would you take in consideration a PR for this
>>> proposal?
>>> >
>>> >
>>> > Thanks,
>>> > Paolo
>>> >
>>> >
>>> > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
>>> > <pa...@gmail.com> wrote:
>>> >>
>>> >> Hi all,
>>> >>
>>> >> Groovy implements a built-in formatting strategy for collection and
>>> map
>>> >> objects that is surely nicer and more useful than the one provided by
>>> the
>>> >> default Java implementation for these classes.
>>> >>
>>> >> However there are use cases in which custom collection or map classes
>>> need
>>> >> to implement their own formatting rule.
>>> >>
>>> >> Currently in Groovy this is quite painful and may lead to inconsistent
>>> >> results. Take in consideration the following example:
>>> >>
>>> >> class MyList extends ArrayList {
>>> >>  String toString() {
>>> >>     this.join('-')
>>> >>   }
>>> >> }
>>> >>
>>> >> def x = new MyList()
>>> >> x << 1 << 2 << 3
>>> >>
>>> >> println x.toString()
>>> >> println x
>>> >> println "$x"
>>> >>
>>> >> Which prints:
>>> >>
>>> >> 1-2-3
>>> >> [1, 2, 3]
>>> >> [1, 2, 3]
>>> >>
>>> >> Both the second and third `println` use the Groovy built-in formatting
>>> >> method and there's no easy way to override this behaviour. Also
>>> there's not
>>> >> a clear reason why the first and the second print return a different
>>> output.
>>> >>
>>> >> The only options I've found is to define `MyList` with a @Delegate
>>> without
>>> >> implementing the `List` interface. But this leads to other weird side
>>> >> effects. The remaining possibility is to use some bytecode
>>> manipulation to
>>> >> bypass the default Groovy formatting, but it looks to me a really
>>> >> overkilling solution for such problem.
>>> >>
>>> >> For this reason a would like to propose to introduce a mechanism that
>>> >> would allow custom collection and map classes to bypass the default
>>> >> formatting method. This should not be too difficult. The current
>>> Groovy
>>> >> built-in formatting is implemented by formatList and formatMap
>>> methods.
>>> >>
>>> >> It would be enough to add a marker interface (or an annotation) that
>>> when
>>> >> applied to a class it would be used to by-pass the logic in the
>>> formatList
>>> >> and formatMap methods and simply return the string provided by the
>>> object
>>> >> `toString` method.
>>> >>
>>> >>
>>> >> I could easily contribute this patch however I would know the opinion
>>> of
>>> >> the Groovy core committers. In particular:
>>> >>
>>> >> 1) What name should have this marker interface? groovy.lagn.Something?
>>> >> 2) Are formatList and formatMap methods the right place to add this
>>> logic?
>>> >> 3) A similar problem exists also when using the `equals` (and
>>> hashCode?)
>>> >> method for collections and maps. Should this mechanism be extended
>>> also to
>>> >> this case?
>>> >>
>>> >>
>>> >>
>>> >> Best,
>>> >> Paolo
>>> >>
>>> >>
>>> >
>>>
>>
>>
>
>

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by MG <mg...@arscreat.com>.
This looks like something that might be useful in certain scenarios. A 
"perfect fix" would always be better, but since that might be some time 
off (2019 being optimistic - some of the things I want Groovy to improve 
in date back to at least 2006)...

My only question would be, if it would perhaps make sense to introduce a 
more generically named annotation (@AutomatismOverride, @GroovyOverride, 
@Configuration,...), that would allow overriding/fine-tuning many of 
Groovy's automatisms through different parameters, to avoid an 
annotation-explosion over time ?

mg

On 23.01.2018 09:25, Paolo Di Tommaso wrote:
> Hi all,
>
> I want to take the opportunity to renew my proposal and PR to add an 
> annotation that allows the override of the Groovy default formatting 
> for certain classes.
>
> https://github.com/apache/groovy/pull/566
>
>
> To quickly remind you what the problem is, Groovy provides a nice 
> default formatting for some classes i.e. String, Map, and Collection 
> data structures which is good. But it makes impossible to override it 
> by sub-classes that implements their own toString method. The same 
> problem for the `equals` method. This makes difficult to handle some 
> specific use cases, leaving bytecode manipulation as the only alternative.
>
>
> My proposal is to add an annotation named 
> @IgnoreDefaultEqualsAndToString (or maybe @OverrideEqualsAndToString) 
> to bypass the Groovy formatting and allow the invocation of 
> sub-classes `toString` and `equals` methods.
>
> I agree that's a sub-optional solution, however no better solutions 
> have been proposed for the current and future releases.
>
>
>
> Cheers,
> Paolo
>
>
> On Sun, Jun 25, 2017 at 8:35 PM, Paolo Di Tommaso 
> <paolo.ditommaso@gmail.com <ma...@gmail.com>> wrote:
>
>     Dear all,
>
>     Groovy still does not provide a mechanism to override the
>     `toString` and `equals` methods for custom Collection and Map
>     objects. This is a serious limitation in some use cases.
>
>     I'm proposing with the following pull request to introduce a
>     marker annotation that allows a custom object to use the
>     `toString` and `equals` as expected.
>
>     https://github.com/apache/groovy/pull/566
>     <https://github.com/apache/groovy/pull/566>
>
>
>     Any comment or improvement is welcome.
>
>
>     Cheers,
>     Paolo
>
>
>     On Thu, Jun 2, 2016 at 1:38 AM, Paul King <paulk@asert.com.au
>     <ma...@asert.com.au>> wrote:
>
>         I am +1 on improving how we handle formatting for lists and
>         maps. My
>         default position would be -1 on an implementation that smells
>         like it
>         might be "yet another hack" that we have to maintain long
>         term. The
>         main reason being that we are trying to streamline method
>         selection
>         for our revised MOP (I know not much is happening in that
>         space right
>         now) and it would be nicer if once that is done, the
>         "inconsistent"
>         results you mention could be handled in an easy to understand way.
>         Having said that, if I get time to look into it further and can't
>         think of a better way to approach it long term, then I could
>         easily be
>         moved to at least a -0.
>
>         Cheers, Paul.
>
>         On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
>         <paolo.ditommaso@gmail.com <ma...@gmail.com>>
>         wrote:
>         > Hello guys,
>         >
>         > No feedback on this? Would you take in consideration a PR
>         for this proposal?
>         >
>         >
>         > Thanks,
>         > Paolo
>         >
>         >
>         > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
>         > <paolo.ditommaso@gmail.com
>         <ma...@gmail.com>> wrote:
>         >>
>         >> Hi all,
>         >>
>         >> Groovy implements a built-in formatting strategy for
>         collection and map
>         >> objects that is surely nicer and more useful than the one
>         provided by the
>         >> default Java implementation for these classes.
>         >>
>         >> However there are use cases in which custom collection or
>         map classes need
>         >> to implement their own formatting rule.
>         >>
>         >> Currently in Groovy this is quite painful and may lead to
>         inconsistent
>         >> results. Take in consideration the following example:
>         >>
>         >> class MyList extends ArrayList {
>         >>  String toString() {
>         >>     this.join('-')
>         >>   }
>         >> }
>         >>
>         >> def x = new MyList()
>         >> x << 1 << 2 << 3
>         >>
>         >> println x.toString()
>         >> println x
>         >> println "$x"
>         >>
>         >> Which prints:
>         >>
>         >> 1-2-3
>         >> [1, 2, 3]
>         >> [1, 2, 3]
>         >>
>         >> Both the second and third `println` use the Groovy built-in
>         formatting
>         >> method and there's no easy way to override this behaviour.
>         Also there's not
>         >> a clear reason why the first and the second print return a
>         different output.
>         >>
>         >> The only options I've found is to define `MyList` with a
>         @Delegate without
>         >> implementing the `List` interface. But this leads to other
>         weird side
>         >> effects. The remaining possibility is to use some bytecode
>         manipulation to
>         >> bypass the default Groovy formatting, but it looks to me a
>         really
>         >> overkilling solution for such problem.
>         >>
>         >> For this reason a would like to propose to introduce a
>         mechanism that
>         >> would allow custom collection and map classes to bypass the
>         default
>         >> formatting method. This should not be too difficult. The
>         current Groovy
>         >> built-in formatting is implemented by formatList and
>         formatMap methods.
>         >>
>         >> It would be enough to add a marker interface (or an
>         annotation) that when
>         >> applied to a class it would be used to by-pass the logic in
>         the formatList
>         >> and formatMap methods and simply return the string provided
>         by the object
>         >> `toString` method.
>         >>
>         >>
>         >> I could easily contribute this patch however I would know
>         the opinion of
>         >> the Groovy core committers. In particular:
>         >>
>         >> 1) What name should have this marker interface?
>         groovy.lagn.Something?
>         >> 2) Are formatList and formatMap methods the right place to
>         add this logic?
>         >> 3) A similar problem exists also when using the `equals`
>         (and hashCode?)
>         >> method for collections and maps. Should this mechanism be
>         extended also to
>         >> this case?
>         >>
>         >>
>         >>
>         >> Best,
>         >> Paolo
>         >>
>         >>
>         >
>
>
>


Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paolo Di Tommaso <pa...@gmail.com>.
Hi all,

I want to take the opportunity to renew my proposal and PR to add an
annotation that allows the override of the Groovy default formatting for
certain classes.

https://github.com/apache/groovy/pull/566


To quickly remind you what the problem is, Groovy provides a nice default
formatting for some classes i.e. String, Map, and Collection data
structures which is good. But it makes impossible to override it by
sub-classes that implements their own toString method. The same problem for
the `equals` method. This makes difficult to handle some specific use
cases, leaving bytecode manipulation as the only alternative.


My proposal is to add an annotation named @IgnoreDefaultEqualsAndToString
(or maybe @OverrideEqualsAndToString) to bypass the Groovy formatting and
allow the invocation of sub-classes `toString` and `equals` methods.

I agree that's a sub-optional solution, however no better solutions have
been proposed for the current and future releases.



Cheers,
Paolo



On Sun, Jun 25, 2017 at 8:35 PM, Paolo Di Tommaso <paolo.ditommaso@gmail.com
> wrote:

> Dear all,
>
> Groovy still does not provide a mechanism to override the `toString` and
> `equals` methods for custom Collection and Map objects. This is a serious
> limitation in some use cases.
>
> I'm proposing with the following pull request to introduce a marker
> annotation that allows a custom object to use the `toString` and `equals`
> as expected.
>
> https://github.com/apache/groovy/pull/566
>
>
> Any comment or improvement is welcome.
>
>
> Cheers,
> Paolo
>
>
> On Thu, Jun 2, 2016 at 1:38 AM, Paul King <pa...@asert.com.au> wrote:
>
>> I am +1 on improving how we handle formatting for lists and maps. My
>> default position would be -1 on an implementation that smells like it
>> might be "yet another hack" that we have to maintain long term. The
>> main reason being that we are trying to streamline method selection
>> for our revised MOP (I know not much is happening in that space right
>> now) and it would be nicer if once that is done, the "inconsistent"
>> results you mention could be handled in an easy to understand way.
>> Having said that, if I get time to look into it further and can't
>> think of a better way to approach it long term, then I could easily be
>> moved to at least a -0.
>>
>> Cheers, Paul.
>>
>> On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
>> <pa...@gmail.com> wrote:
>> > Hello guys,
>> >
>> > No feedback on this? Would you take in consideration a PR for this
>> proposal?
>> >
>> >
>> > Thanks,
>> > Paolo
>> >
>> >
>> > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
>> > <pa...@gmail.com> wrote:
>> >>
>> >> Hi all,
>> >>
>> >> Groovy implements a built-in formatting strategy for collection and map
>> >> objects that is surely nicer and more useful than the one provided by
>> the
>> >> default Java implementation for these classes.
>> >>
>> >> However there are use cases in which custom collection or map classes
>> need
>> >> to implement their own formatting rule.
>> >>
>> >> Currently in Groovy this is quite painful and may lead to inconsistent
>> >> results. Take in consideration the following example:
>> >>
>> >> class MyList extends ArrayList {
>> >>  String toString() {
>> >>     this.join('-')
>> >>   }
>> >> }
>> >>
>> >> def x = new MyList()
>> >> x << 1 << 2 << 3
>> >>
>> >> println x.toString()
>> >> println x
>> >> println "$x"
>> >>
>> >> Which prints:
>> >>
>> >> 1-2-3
>> >> [1, 2, 3]
>> >> [1, 2, 3]
>> >>
>> >> Both the second and third `println` use the Groovy built-in formatting
>> >> method and there's no easy way to override this behaviour. Also
>> there's not
>> >> a clear reason why the first and the second print return a different
>> output.
>> >>
>> >> The only options I've found is to define `MyList` with a @Delegate
>> without
>> >> implementing the `List` interface. But this leads to other weird side
>> >> effects. The remaining possibility is to use some bytecode
>> manipulation to
>> >> bypass the default Groovy formatting, but it looks to me a really
>> >> overkilling solution for such problem.
>> >>
>> >> For this reason a would like to propose to introduce a mechanism that
>> >> would allow custom collection and map classes to bypass the default
>> >> formatting method. This should not be too difficult. The current Groovy
>> >> built-in formatting is implemented by formatList and formatMap methods.
>> >>
>> >> It would be enough to add a marker interface (or an annotation) that
>> when
>> >> applied to a class it would be used to by-pass the logic in the
>> formatList
>> >> and formatMap methods and simply return the string provided by the
>> object
>> >> `toString` method.
>> >>
>> >>
>> >> I could easily contribute this patch however I would know the opinion
>> of
>> >> the Groovy core committers. In particular:
>> >>
>> >> 1) What name should have this marker interface? groovy.lagn.Something?
>> >> 2) Are formatList and formatMap methods the right place to add this
>> logic?
>> >> 3) A similar problem exists also when using the `equals` (and
>> hashCode?)
>> >> method for collections and maps. Should this mechanism be extended
>> also to
>> >> this case?
>> >>
>> >>
>> >>
>> >> Best,
>> >> Paolo
>> >>
>> >>
>> >
>>
>
>

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paolo Di Tommaso <pa...@gmail.com>.
Dear all,

Groovy still does not provide a mechanism to override the `toString` and
`equals` methods for custom Collection and Map objects. This is a serious
limitation in some use cases.

I'm proposing with the following pull request to introduce a marker
annotation that allows a custom object to use the `toString` and `equals`
as expected.

https://github.com/apache/groovy/pull/566


Any comment or improvement is welcome.


Cheers,
Paolo


On Thu, Jun 2, 2016 at 1:38 AM, Paul King <pa...@asert.com.au> wrote:

> I am +1 on improving how we handle formatting for lists and maps. My
> default position would be -1 on an implementation that smells like it
> might be "yet another hack" that we have to maintain long term. The
> main reason being that we are trying to streamline method selection
> for our revised MOP (I know not much is happening in that space right
> now) and it would be nicer if once that is done, the "inconsistent"
> results you mention could be handled in an easy to understand way.
> Having said that, if I get time to look into it further and can't
> think of a better way to approach it long term, then I could easily be
> moved to at least a -0.
>
> Cheers, Paul.
>
> On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
> <pa...@gmail.com> wrote:
> > Hello guys,
> >
> > No feedback on this? Would you take in consideration a PR for this
> proposal?
> >
> >
> > Thanks,
> > Paolo
> >
> >
> > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
> > <pa...@gmail.com> wrote:
> >>
> >> Hi all,
> >>
> >> Groovy implements a built-in formatting strategy for collection and map
> >> objects that is surely nicer and more useful than the one provided by
> the
> >> default Java implementation for these classes.
> >>
> >> However there are use cases in which custom collection or map classes
> need
> >> to implement their own formatting rule.
> >>
> >> Currently in Groovy this is quite painful and may lead to inconsistent
> >> results. Take in consideration the following example:
> >>
> >> class MyList extends ArrayList {
> >>  String toString() {
> >>     this.join('-')
> >>   }
> >> }
> >>
> >> def x = new MyList()
> >> x << 1 << 2 << 3
> >>
> >> println x.toString()
> >> println x
> >> println "$x"
> >>
> >> Which prints:
> >>
> >> 1-2-3
> >> [1, 2, 3]
> >> [1, 2, 3]
> >>
> >> Both the second and third `println` use the Groovy built-in formatting
> >> method and there's no easy way to override this behaviour. Also there's
> not
> >> a clear reason why the first and the second print return a different
> output.
> >>
> >> The only options I've found is to define `MyList` with a @Delegate
> without
> >> implementing the `List` interface. But this leads to other weird side
> >> effects. The remaining possibility is to use some bytecode manipulation
> to
> >> bypass the default Groovy formatting, but it looks to me a really
> >> overkilling solution for such problem.
> >>
> >> For this reason a would like to propose to introduce a mechanism that
> >> would allow custom collection and map classes to bypass the default
> >> formatting method. This should not be too difficult. The current Groovy
> >> built-in formatting is implemented by formatList and formatMap methods.
> >>
> >> It would be enough to add a marker interface (or an annotation) that
> when
> >> applied to a class it would be used to by-pass the logic in the
> formatList
> >> and formatMap methods and simply return the string provided by the
> object
> >> `toString` method.
> >>
> >>
> >> I could easily contribute this patch however I would know the opinion of
> >> the Groovy core committers. In particular:
> >>
> >> 1) What name should have this marker interface? groovy.lagn.Something?
> >> 2) Are formatList and formatMap methods the right place to add this
> logic?
> >> 3) A similar problem exists also when using the `equals` (and hashCode?)
> >> method for collections and maps. Should this mechanism be extended also
> to
> >> this case?
> >>
> >>
> >>
> >> Best,
> >> Paolo
> >>
> >>
> >
>

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paolo Di Tommaso <pa...@gmail.com>.
Hi,

Thanks for your reply. I see your points and I really hope you can manage
to find a better solution to handle this issue.

In any case I will try to submit a PR at my earliest convenience at least
to have it as remainder in the tracking system.

Cheers,
Paolo


On Thu, Jun 2, 2016 at 1:38 AM, Paul King <pa...@asert.com.au> wrote:

> I am +1 on improving how we handle formatting for lists and maps. My
> default position would be -1 on an implementation that smells like it
> might be "yet another hack" that we have to maintain long term. The
> main reason being that we are trying to streamline method selection
> for our revised MOP (I know not much is happening in that space right
> now) and it would be nicer if once that is done, the "inconsistent"
> results you mention could be handled in an easy to understand way.
> Having said that, if I get time to look into it further and can't
> think of a better way to approach it long term, then I could easily be
> moved to at least a -0.
>
> Cheers, Paul.
>
> On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
> <pa...@gmail.com> wrote:
> > Hello guys,
> >
> > No feedback on this? Would you take in consideration a PR for this
> proposal?
> >
> >
> > Thanks,
> > Paolo
> >
> >
> > On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
> > <pa...@gmail.com> wrote:
> >>
> >> Hi all,
> >>
> >> Groovy implements a built-in formatting strategy for collection and map
> >> objects that is surely nicer and more useful than the one provided by
> the
> >> default Java implementation for these classes.
> >>
> >> However there are use cases in which custom collection or map classes
> need
> >> to implement their own formatting rule.
> >>
> >> Currently in Groovy this is quite painful and may lead to inconsistent
> >> results. Take in consideration the following example:
> >>
> >> class MyList extends ArrayList {
> >>  String toString() {
> >>     this.join('-')
> >>   }
> >> }
> >>
> >> def x = new MyList()
> >> x << 1 << 2 << 3
> >>
> >> println x.toString()
> >> println x
> >> println "$x"
> >>
> >> Which prints:
> >>
> >> 1-2-3
> >> [1, 2, 3]
> >> [1, 2, 3]
> >>
> >> Both the second and third `println` use the Groovy built-in formatting
> >> method and there's no easy way to override this behaviour. Also there's
> not
> >> a clear reason why the first and the second print return a different
> output.
> >>
> >> The only options I've found is to define `MyList` with a @Delegate
> without
> >> implementing the `List` interface. But this leads to other weird side
> >> effects. The remaining possibility is to use some bytecode manipulation
> to
> >> bypass the default Groovy formatting, but it looks to me a really
> >> overkilling solution for such problem.
> >>
> >> For this reason a would like to propose to introduce a mechanism that
> >> would allow custom collection and map classes to bypass the default
> >> formatting method. This should not be too difficult. The current Groovy
> >> built-in formatting is implemented by formatList and formatMap methods.
> >>
> >> It would be enough to add a marker interface (or an annotation) that
> when
> >> applied to a class it would be used to by-pass the logic in the
> formatList
> >> and formatMap methods and simply return the string provided by the
> object
> >> `toString` method.
> >>
> >>
> >> I could easily contribute this patch however I would know the opinion of
> >> the Groovy core committers. In particular:
> >>
> >> 1) What name should have this marker interface? groovy.lagn.Something?
> >> 2) Are formatList and formatMap methods the right place to add this
> logic?
> >> 3) A similar problem exists also when using the `equals` (and hashCode?)
> >> method for collections and maps. Should this mechanism be extended also
> to
> >> this case?
> >>
> >>
> >>
> >> Best,
> >> Paolo
> >>
> >>
> >
>

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paul King <pa...@asert.com.au>.
I am +1 on improving how we handle formatting for lists and maps. My
default position would be -1 on an implementation that smells like it
might be "yet another hack" that we have to maintain long term. The
main reason being that we are trying to streamline method selection
for our revised MOP (I know not much is happening in that space right
now) and it would be nicer if once that is done, the "inconsistent"
results you mention could be handled in an easy to understand way.
Having said that, if I get time to look into it further and can't
think of a better way to approach it long term, then I could easily be
moved to at least a -0.

Cheers, Paul.

On Tue, May 31, 2016 at 7:36 PM, Paolo Di Tommaso
<pa...@gmail.com> wrote:
> Hello guys,
>
> No feedback on this? Would you take in consideration a PR for this proposal?
>
>
> Thanks,
> Paolo
>
>
> On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso
> <pa...@gmail.com> wrote:
>>
>> Hi all,
>>
>> Groovy implements a built-in formatting strategy for collection and map
>> objects that is surely nicer and more useful than the one provided by the
>> default Java implementation for these classes.
>>
>> However there are use cases in which custom collection or map classes need
>> to implement their own formatting rule.
>>
>> Currently in Groovy this is quite painful and may lead to inconsistent
>> results. Take in consideration the following example:
>>
>> class MyList extends ArrayList {
>>  String toString() {
>>     this.join('-')
>>   }
>> }
>>
>> def x = new MyList()
>> x << 1 << 2 << 3
>>
>> println x.toString()
>> println x
>> println "$x"
>>
>> Which prints:
>>
>> 1-2-3
>> [1, 2, 3]
>> [1, 2, 3]
>>
>> Both the second and third `println` use the Groovy built-in formatting
>> method and there's no easy way to override this behaviour. Also there's not
>> a clear reason why the first and the second print return a different output.
>>
>> The only options I've found is to define `MyList` with a @Delegate without
>> implementing the `List` interface. But this leads to other weird side
>> effects. The remaining possibility is to use some bytecode manipulation to
>> bypass the default Groovy formatting, but it looks to me a really
>> overkilling solution for such problem.
>>
>> For this reason a would like to propose to introduce a mechanism that
>> would allow custom collection and map classes to bypass the default
>> formatting method. This should not be too difficult. The current Groovy
>> built-in formatting is implemented by formatList and formatMap methods.
>>
>> It would be enough to add a marker interface (or an annotation) that when
>> applied to a class it would be used to by-pass the logic in the formatList
>> and formatMap methods and simply return the string provided by the object
>> `toString` method.
>>
>>
>> I could easily contribute this patch however I would know the opinion of
>> the Groovy core committers. In particular:
>>
>> 1) What name should have this marker interface? groovy.lagn.Something?
>> 2) Are formatList and formatMap methods the right place to add this logic?
>> 3) A similar problem exists also when using the `equals` (and hashCode?)
>> method for collections and maps. Should this mechanism be extended also to
>> this case?
>>
>>
>>
>> Best,
>> Paolo
>>
>>
>

Re: Add a marker interface to bypass Collections and Maps formatting

Posted by Paolo Di Tommaso <pa...@gmail.com>.
Hello guys,

No feedback on this? Would you take in consideration a PR for this
proposal?


Thanks,
Paolo


On Sat, May 28, 2016 at 6:26 PM, Paolo Di Tommaso <paolo.ditommaso@gmail.com
> wrote:

> Hi all,
>
> Groovy implements a built-in formatting strategy for collection and map
> objects that is surely nicer and more useful than the one provided by the
> default Java implementation for these classes.
>
> However there are use cases in which custom collection or map classes need
> to implement their own formatting rule.
>
> Currently in Groovy this is quite painful and may lead to inconsistent
> results. Take in consideration the following example:
>
> class MyList extends ArrayList {
>  String toString() {
>     this.join('-')
>   }
> }
>
> def x = new MyList()
> x << 1 << 2 << 3
>
> println x.toString()
> println x
> println "$x"
>
> Which prints:
>
> 1-2-3
> [1, 2, 3]
> [1, 2, 3]
>
> Both the second and third `println` use the Groovy built-in formatting
> method and there's no easy way to override this behaviour. Also there's not
> a clear reason why the first and the second print return a different
> output.
>
> The only options I've found is to define `MyList` with a @Delegate without
> implementing the `List` interface. But this leads to other weird side
> effects. The remaining possibility is to use some bytecode manipulation to
> bypass the default Groovy formatting, but it looks to me a really
> overkilling solution for such problem.
>
> For this reason a would like to propose to introduce a mechanism that
> would allow custom collection and map classes to bypass the default
> formatting method. This should not be too difficult. The current Groovy
> built-in formatting is implemented by formatList
> <https://github.com/apache/groovy/blob/master/src/main/org/codehaus/groovy/runtime/InvokerHelper.java#L678-L712>
> and formatMap
> <https://github.com/apache/groovy/blob/master/src/main/org/codehaus/groovy/runtime/InvokerHelper.java#L641-L668>
> methods.
>
> It would be enough to add a marker interface (or an annotation) that when
> applied to a class it would be used to by-pass the logic in the formatList
> and formatMap methods and simply return the string provided by the object
> `toString` method.
>
>
> I could easily contribute this patch however I would know the opinion of
> the Groovy core committers. In particular:
>
> 1) What name should have this marker interface? groovy.lagn.Something?
> 2) Are formatList and formatMap methods the right place to add this logic?
> 3) A similar problem exists also when using the `equals` (and hashCode?)
> method for collections and maps. Should this mechanism be extended also to
> this case?
>
>
>
> Best,
> Paolo
>
>
>