Irrelevant, for both of those are the very same Groovy False :)

> On 15 Aug 2018, at 11:24 PM, mg <mg...@arscreat.com> wrote:
> 
> Sorry, bad/incorrect example, should read: Do you expect/want
> 
> true && null == null  // null == UNKNOWN
> 
> or
> 
> true && null == false // Groovy-truth-null
> 
> ?
> 
> 
> 
> -------- Ursprüngliche Nachricht --------
> Von: "ocs@ocs" <o...@ocs.cz>
> Datum
> 
> -------- Ursprüngliche Nachricht --------
> Von: mg <mg...@arscreat.com>
> Datum: 15.08.18 13:07 (GMT+00:00)
> An: dev@groovy.apache.org
> Betreff: Re: suggestion: ImplicitSafeNavigation annotation
> 
> Another question: How do you see boolean operations including null bein 
> handled ? Classical would be to again have most operations return null. Or 
> should null be interpreted as false here ?
> 
> E.g.
> true || null == null
> or
> true || null == false
> ?
> 
> 
> 
> -------- Ursprüngliche Nachricht --------
> Von: "ocs@ocs" <o...@ocs.cz>
> Datum: 15.08.18 03:18 (GMT+00:00)
> An: dev@groovy.apache.org
> Betreff: Re: suggestion: ImplicitSafeNavigation annotation
> 
> mg,
> 
>> On 15 Aug 2018, at 3:26 AM, mg <mg...@arscreat.com 
>> <mailto:mg...@arscreat.com>> wrote:
>> 
>> Fair enough (I am typing this on my smartphone on vacation, so keep samples 
>> small; also (your) more complex code samples are really hard to read in my 
>> mail reader). It still seems to be a big paradigm change
> 
> I might be missing something of importance here, but I can't see any paradigm 
> change; not even the slightest shift.
> 
> The only change suggested is that one could — in the extent of one needs 
> that, which would self-evidently differ for different people — decide whether 
> the “safe” behaviour is explicitly triggered by using the question-mark 
> syntax, or whether it is implicit.
> 
>> since regular Java/Groovy programs typically have very little null values
> 
> The very existence of ?. and ?[] suggests it is not quite the case — 
> otherwise, nobody would ever bother designing and implementing them.
> 
>> so am not convinced this is worth the effort (and as Jochen pointed out, 
>> there will still be cases where null will just be converted to "null").
> 
> Are there? Given my limited knowledge, I know of none such. 
> “null?.plus('foo')” yields a null, and so — for a consistency sake — very 
> definitely should also “null?+'foo'” and “@ImplicitSafeNavigation ... 
> null+foo”, had they existed.
> 
>> What I would suggest instead is considering to introduce nil, sql_null, 
>> empty, ... as type agnostic constants in addition to the existing null in 
>> Groovy. That way you could use e.g. nil in your code, which by definition 
>> exhibits your expected behavior, but it would make the usage more explicit, 
>> and one would not need to switch/bend the existing null semantics...
> 
> That's a nice idea; alas, so that it is viable, one would also have to be 
> able to set up which kind of null is to be returned from expressions like 
> “aMap['unknownkey']“ or “list.find { never-matches }” etc.
> 
> Thus, instead of my “@ImplicitSafeNavigation(true)” you would have to use 
> something like “@DefaultNullClass(nil)” — and instead of 
> “@ImplicitSafeNavigation(false)” you would need something like 
> “@DefaultNullClass(null)”.
> 
> Along with that, you would need a way to return “the current default null” 
> instead of just null; there would be a real problem with a legacy code which 
> returns null (but should return “the current default null” instead), and so 
> forth.
> 
> That all said, it definitely is an interesting idea worth checking; myself, 
> though, I do fear it would quickly lead to a real mess (unlike my suggestion, 
> which is considerably less flexible, but at the same moment, very simple and 
> highly intuitive).
> 
> Thanks and all the best,
> OC
> 
>> -------- Ursprüngliche Nachricht --------
>> Von: "ocs@ocs" <o...@ocs.cz <mailto:o...@ocs.cz>>
>> Datum: 15.08.18 00:53 (GMT+00:00)
>> An: dev@groovy.apache.org <mailto:dev@groovy.apache.org>
>> Betreff: Re: suggestion: ImplicitSafeNavigation annotation
>> 
>> mg,
>> 
>>> On 15 Aug 2018, at 1:33 AM, mg <mg...@arscreat.com 
>>> <mailto:mg...@arscreat.com>> wrote:
>>> 
>>> That's not how I meant my sample eval helper method to be used :-)
>>> 
>>> (for brevity I will write neval for eval(true) here)
>>> 
>>> What I meant was: How easy would it be to get a similar result to what you 
>>> want, by wrapping a few key places (e.g. a whole method body) in your code 
>>> in neval { ... } ? Evidently that would just mean that any NPE inside the 
>>> e.g. method would lead to the whole method result being null. 
>> 
>> Which is a serious problem. Rarely you want „a whole method be skipped  (and 
>> return null) if anything inside of it happens to be null“. What you normally 
>> want is the null-propagation, e.g.,
>> 
>> def foo=bar.baz[bax]?:default_value;
>> ... other code ...
>> 
>> The other code is always performed and never skipped (unless another 
>> exception occurs of course); but the null-propagation makes sure that if bar 
>> or bar.baz happens to be a null, then default_value is used. And so forth.
>> 
>>> To give a simple example:
>>> 
>>> final x = a?.b?.c?.d
>>> 
>>> could be written as
>>> 
>>> final x = neval { a.b.c.d }
>> 
>> Precisely. Do please note that even your simple example did not put a whole 
>> method body into neval, but just one sole expression instead. Essentially 
>> all expressions — often sub-expressions, wherever things like Elvis are used 
>> — would have to be embedded in nevals separately. Which is, alas, far from 
>> feasible.
>> 
>>> Of course the two expressions are not semantically identical, since neval 
>>> will transform any NPE inside evaluation of a, b, c, and d into the result 
>>> null - but since you say you never want to see any NPEs...
>> 
>> That indeed would not be a problem.
>> 
>>> (The performance of neval should be ok, since I do not assume that you 
>>> expect your code to actually encounter null values, and accordingly NPEs, 
>>> all the time)
>> 
>> This one possibly would though: I do expect my code to encounter null values 
>> often — with some code, they might well be the normal case with a non-null 
>> an exception. That's precisely why I do not want NPEs (but the quick, 
>> efficient and convenient null-propagation instead) :)
>> 
>> Thanks and all the best,
>> OC
>> 
>>> -------- Ursprüngliche Nachricht --------
>>> Von: "ocs@ocs" <o...@ocs.cz <mailto:o...@ocs.cz>>
>>> Datum: 14.08.18 23:14 (GMT+00:00)
>>> An: dev@groovy.apache.org <mailto:dev@groovy.apache.org>
>>> Betreff: Re: suggestion: ImplicitSafeNavigation annotation
>>> 
>>> mg,
>>> 
>>>> On 14 Aug 2018, at 11:36 PM, mg <mg...@arscreat.com 
>>>> <mailto: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 <mailto:o...@ocs.cz>>
>>>> Datum: 14.08.18 17:46 (GMT+00:00)
>>>> An: dev@groovy.apache.org <mailto: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