mg,

> On 14 Aug 2018, at 11:36 PM, mg <mg...@arscreat.com> wrote:
> 
> I am wondering: In what case does what you are using/suggesting differ 
> significantly from simply catching a NPE that a specific code block throws 
> and letting said block evaluate to null in that case:
> 
> def eval(bool nullSafeQ, Closure cls) {
>   try {
>     return cls()
>   }
>   catch(NullPointerException e) {
>     if(nullSafeQ) {
>       return null
>     }
>     throw e
>   }
> }

Conceptually, not in the slightest.

In practice, there's a world of difference.

For one, it would be terrible far as the code cleanness, fragility and 
readability are concerned — even worse than those ubiquitous question marks:

=== the code should look, say, like this ===
@ImplicitSafeNavigation def foo(bar) {
  def x=baz(bar.foo)?:bax(bar.foo)
  x.allResults {
    def y=baz(it)
    if (y>1) y+bax(y-1)
    else y–bax(0)
  }
}
=== the eval-based equivalent would probably look somewhat like this ===
def foo(bar) {
  def x=eval(true){baz(eval(true){bar.foo})?:bax(bar.foo)}
  eval(true){
    x.allResults {
      def y=eval(true){baz(it)}
      if (y>1) eval(true){y+bax(y-1)}
      else eval(true){y–bax(0)}
    }
  }
}
===

and quite frankly I am not even sure whether the usage of eval above is right 
and whether I did not forget to use it somewhere where it should have been. It 
would be ways easier with those question marks.

Also, with the eval block, there might be a bit of a problem with the type 
information: I regret to say I do not know whether we can in Groovy declare a 
method with a block argument in such a way that the return type of the function 
is automatically recognised by the compiler as the same type as the block 
return value? (Definitely I don't know how to do that myself; Cédric or Jochen 
might, though ;))

Aside of that, I wonder about the efficiency; although premature optimisation 
definitely is a bitch, still an exception harness is not cheap if an exception 
is caught, I understand.

> (It feels a bit like what you wants is tri-logic/SQL type NULL support in 
> Groovy, not treating Java/Groovy null differently...)

In fact what I want is a bit like the Objective-C simple but very efficient and 
extremely practical nil behaviour, to which I am used to and which suits me 
immensely.

Agreed, the Java world takes a different approach (without even the safe 
navigation where it originated!); I have tried to embrace that approach a 
couple of times, and always I have found it seriously lacking.

I do not argue that the null-propagating behaviour is always better; on the 
other hand, I do argue that sometimes and for some people it definitely is 
better, and that Groovy should support those times and people just as well as 
it supports the NPE-based approach of Java.

Thanks and all the best,
OC

> -------- Ursprüngliche Nachricht --------
> Von: "ocs@ocs" <o...@ocs.cz>
> Datum: 14.08.18 17:46 (GMT+00:00)
> An: dev@groovy.apache.org
> Betreff: Re: suggestion: ImplicitSafeNavigation annotation
> 
> Jochen,
> 
>> On 14 Aug 2018, at 6:25 PM, Jochen Theodorou <blackd...@gmx.org 
>> <mailto:blackd...@gmx.org>> wrote:
>> Am 14.08.2018 um 15:23 schrieb ocs@ocs:
>>> H2,
>>>> However, “a+b” should work as one would expect
>>> Absolutely. Me, I very definitely expect that if a happens to be null, the 
>>> result is null too. (With b null it depends on the details of a.plus 
>>> implementation.)
>> 
>> the counter example is null plus String though
> 
> Not for me. In my world, if I am adding a string to a non-existent object, I 
> very much do expect the result is still a non-existent object. Precisely the 
> same as if I has been trying to turn it to lowercase or to count its 
> character or anything.
> 
> Whilst I definitely do not suggest forcing this POV to others, to me, it 
> seems perfectly reasonable and 100 per cent intuitive.
> 
> Besides, it actually (and expectably) does work so, if I use the 
> method-syntax to be able to use safe navigation:
> 
> ===
> 254 /tmp> <q.groovy 
> String s=null
> println "Should be null: ${s?.plus('foo')}"
> 255 /tmp> /usr/local/groovy-2.4.15/bin/groovy q
> WARNING: An illegal reflective access operation has occurred
> ... ...
> Should be null: null
> 256 /tmp> 
> ===
> 
> which is perfectly right. Similarly, a hypothetical “null?+'foo'” or 
> “@ImplicitSafeNavigation ... null+foo” should return null as well, to keep 
> consistent.
> 
> (Incidentally, do you — or anyone else — happen to know how to get rid of 
> those pesky warnings?)
> 
> Thanks and all the best,
> OC
> 
> 
> 

Reply via email to