You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@groovy.apache.org by "ocs@ocs" <oc...@ocs.cz> on 2018/08/14 11:28:01 UTC

suggestion: ImplicitSafeNavigation annotation

Gentlemen,

some NPE-related problems of today brought me to re-interate one of my older suggestions.

We have the so-called “safe navigation”[*], which in some cases allows a null to be propagated out of an expression instead of throwing a NPE. At the moment, it can be triggered for a particular sub-expression (like property/method-call and, as of 3, newly also indexing) using a question mark (e.g., “foo?.bar()” or “foo?[bar]”).

Do please correct me if I am wrong, but far as I know, there still are expressions which do not allow the “safe mode”, e.g., arithmetic (“a+b” etc). Furthermore, there are cases when one simply wants a bigger block of code to contain only null-propagating expressions and never NPE; in such case, using the question mark syntax is both inconvenient and error-prone (for it is very easy to forget one of the lot of question marks needed in such a code, and then get an uncaught unwanted NPE).

For these reasons, I would suggest adding a new annotation, whose name might be e.g., “ImplicitSafeNavigation”; it would simply force a null-propagation to be implicitly and automatically used for *all* expressions in the annotated scope, i.e., NPE would never be thrown for them; for example:

===
@ImplicitSafeNavigation class Foo {
 static foo(a,b,c,d,e) {
   a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any* expression which NPEs today
 }
}
assert null == Foo.foo(null,null,null,null,null)
===

I wonder whether this enhancement would be possible to implement in some forthcoming Groovy release? Myself, I believe it would help tremendously.

If feasible, then it is for a further discussion whether in the scope of this annotation
(a) a safe-navigation syntax (“foo?.bar”) should be ignored as superfluous;
(b) or, whether in this scope it should reverse the behaviour to trigger an NPE anyway;
(c) or, whether it should be ignored as (a), and aside of that it would be worth the effort (and technically possible) to add another syntax to force NPE over a particular sub-expression (e.g., “foo!.bar”).

Thanks and all the best,
OC

[*] The name might not be quite apt, for propagating a null is not inherently safer than NPEing; those are simply two different approaches, both of which serve best in different circumstances. A better name would be something like “null-propagating” or “non-NPE” mode, I guess. Myself, I don't think we should change the name though, for all are used to it.


Re: suggestion: ImplicitSafeNavigation annotation

Posted by "ocs@ocs" <oc...@ocs.cz>.
Jenn,

> On 15 Aug 2018, at 12:28 AM, Jennifer Strater <je...@gmail.com> wrote:
> First, I agree with Paul and Andres that it would be nice to see how well this works outside of groovy core. Hopefully, someone here can help you make it a reality.

The main problem I can (perhaps mistakenly) see there is that — far as I can say — the only viable way to make it work in the current Groovy is the Null metaclass trick (with some ASTT side support). ASTT-only solution, at least when I have tried myself with my limited extent of knowledge, proved rather at the unfeasible side.

The self-evident drawback of the Null metaclass trick is that it can't be — again, far as I can say and far as my knowledge goes — easily made class- or even method- or even block-granular, based on annotations. That's no problem for me, who don't want to see any NPE ever; very grave problem though for a general audience, which would presumably want to switch the null-propagating “safe” mode on just intermittently and only for clearly marked parts of the code.

> In addition, I would really appreciate it, if, in the future, you did not use 'gentlemen' to address the entire mailing list.

Oh, I do apologise to all the ladies. I just came here from an extensive and prolonged debate in another (private) maillist where there really happen to be gentlemen only, and sorta unthinkingly I just went on using the same address I used in there. No offence meant!

Thanks and all the best,
OC

> 
> On Tue, Aug 14, 2018 at 1:28 PM, ocs@ocs <ocs@ocs.cz <ma...@ocs.cz>> wrote:
> Gentlemen,
> 
> some NPE-related problems of today brought me to re-interate one of my older suggestions.
> 
> We have the so-called “safe navigation”[*], which in some cases allows a null to be propagated out of an expression instead of throwing a NPE. At the moment, it can be triggered for a particular sub-expression (like property/method-call and, as of 3, newly also indexing) using a question mark (e.g., “foo?.bar()” or “foo?[bar]”).
> 
> Do please correct me if I am wrong, but far as I know, there still are expressions which do not allow the “safe mode”, e.g., arithmetic (“a+b” etc). Furthermore, there are cases when one simply wants a bigger block of code to contain only null-propagating expressions and never NPE; in such case, using the question mark syntax is both inconvenient and error-prone (for it is very easy to forget one of the lot of question marks needed in such a code, and then get an uncaught unwanted NPE).
> 
> For these reasons, I would suggest adding a new annotation, whose name might be e.g., “ImplicitSafeNavigation”; it would simply force a null-propagation to be implicitly and automatically used for *all* expressions in the annotated scope, i.e., NPE would never be thrown for them; for example:
> 
> ===
> @ImplicitSafeNavigation class Foo {
>  static foo(a,b,c,d,e) {
>    a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any* expression which NPEs today
>  }
> }
> assert null == Foo.foo(null,null,null,null,null)
> ===
> 
> I wonder whether this enhancement would be possible to implement in some forthcoming Groovy release? Myself, I believe it would help tremendously.
> 
> If feasible, then it is for a further discussion whether in the scope of this annotation
> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as superfluous;
> (b) or, whether in this scope it should reverse the behaviour to trigger an NPE anyway;
> (c) or, whether it should be ignored as (a), and aside of that it would be worth the effort (and technically possible) to add another syntax to force NPE over a particular sub-expression (e.g., “foo!.bar”).
> 
> Thanks and all the best,
> OC
> 
> [*] The name might not be quite apt, for propagating a null is not inherently safer than NPEing; those are simply two different approaches, both of which serve best in different circumstances. A better name would be something like “null-propagating” or “non-NPE” mode, I guess. Myself, I don't think we should change the name though, for all are used to it.
> 
> 


Re: suggestion: ImplicitSafeNavigation annotation

Posted by h2...@abula.org.
Den 2018-08-15 00:28, skrev Jennifer Strater:
> Hi OC,
> 
> First, I agree with Paul and Andres that it would be nice to see how
> well this works outside of groovy core. Hopefully, someone here can
> help you make it a reality.
> 
> In addition, I would really appreciate it, if, in the future, you did
> not use 'gentlemen' to address the entire mailing list.

Good point, and not very gentleman-like! Will 'ladies and gentlemen do'? 
:-)

H2
Gentleman, hopefully...

> Best,
> Jenn
> On Tue, Aug 14, 2018 at 1:28 PM, ocs@ocs <oc...@ocs.cz> wrote:
> 
>> Gentlemen,
>> 
>> some NPE-related problems of today brought me to re-interate one of
>> my older suggestions.
>> 
>> We have the so-called “safe navigation”[*], which in some cases
>> allows a null to be propagated out of an expression instead of
>> throwing a NPE. At the moment, it can be triggered for a particular
>> sub-expression (like property/method-call and, as of 3, newly also
>> indexing) using a question mark (e.g., “foo?.bar()” or
>> “foo?[bar]”).
>> 
>> Do please correct me if I am wrong, but far as I know, there still
>> are expressions which do not allow the “safe mode”, e.g.,
>> arithmetic (“a+b” etc). Furthermore, there are cases when one
>> simply wants a bigger block of code to contain only null-propagating
>> expressions and never NPE; in such case, using the question mark
>> syntax is both inconvenient and error-prone (for it is very easy to
>> forget one of the lot of question marks needed in such a code, and
>> then get an uncaught unwanted NPE).
>> 
>> For these reasons, I would suggest adding a new annotation, whose
>> name might be e.g., “ImplicitSafeNavigation”; it would simply
>> force a null-propagation to be implicitly and automatically used for
>> *all* expressions in the annotated scope, i.e., NPE would never be
>> thrown for them; for example:
>> 
>> ===
>> @ImplicitSafeNavigation class Foo {
>> static foo(a,b,c,d,e) {
>> a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any*
>> expression which NPEs today
>> }
>> }
>> assert null == Foo.foo(null,null,null,null,null)
>> ===
>> 
>> I wonder whether this enhancement would be possible to implement in
>> some forthcoming Groovy release? Myself, I believe it would help
>> tremendously.
>> 
>> If feasible, then it is for a further discussion whether in the
>> scope of this annotation
>> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as
>> superfluous;
>> (b) or, whether in this scope it should reverse the behaviour to
>> trigger an NPE anyway;
>> (c) or, whether it should be ignored as (a), and aside of that it
>> would be worth the effort (and technically possible) to add another
>> syntax to force NPE over a particular sub-expression (e.g.,
>> “foo!.bar”).
>> 
>> Thanks and all the best,
>> OC
>> 
>> [*] The name might not be quite apt, for propagating a null is not
>> inherently safer than NPEing; those are simply two different
>> approaches, both of which serve best in different circumstances. A
>> better name would be something like “null-propagating” or
>> “non-NPE” mode, I guess. Myself, I don't think we should change
>> the name though, for all are used to it.

Re: suggestion: ImplicitSafeNavigation annotation

Posted by Jennifer Strater <je...@gmail.com>.
Hi OC,

First, I agree with Paul and Andres that it would be nice to see how well
this works outside of groovy core. Hopefully, someone here can help you
make it a reality.

In addition, I would really appreciate it, if, in the future, you did not
use 'gentlemen' to address the entire mailing list.

Best,
Jenn

On Tue, Aug 14, 2018 at 1:28 PM, ocs@ocs <oc...@ocs.cz> wrote:

> Gentlemen,
>
> some NPE-related problems of today brought me to re-interate one of my
> older suggestions.
>
> We have the so-called “safe navigation”[*], which in some cases allows a
> null to be propagated out of an expression instead of throwing a NPE. At
> the moment, it can be triggered for a particular sub-expression (like
> property/method-call and, as of 3, newly also indexing) using a question
> mark (e.g., “foo?.bar()” or “foo?[bar]”).
>
> Do please correct me if I am wrong, but far as I know, there still are
> expressions which do not allow the “safe mode”, e.g., arithmetic (“a+b”
> etc). Furthermore, there are cases when one simply wants a bigger block of
> code to contain only null-propagating expressions and never NPE; in such
> case, using the question mark syntax is both inconvenient and error-prone
> (for it is very easy to forget one of the lot of question marks needed in
> such a code, and then get an uncaught unwanted NPE).
>
> For these reasons, I would suggest adding a new annotation, whose name
> might be e.g., “ImplicitSafeNavigation”; it would simply force a
> null-propagation to be implicitly and automatically used for *all*
> expressions in the annotated scope, i.e., NPE would never be thrown for
> them; for example:
>
> ===
> @ImplicitSafeNavigation class Foo {
>  static foo(a,b,c,d,e) {
>    a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any* expression
> which NPEs today
>  }
> }
> assert null == Foo.foo(null,null,null,null,null)
> ===
>
> I wonder whether this enhancement would be possible to implement in some
> forthcoming Groovy release? Myself, I believe it would help tremendously.
>
> If feasible, then it is for a further discussion whether in the scope of
> this annotation
> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as superfluous;
> (b) or, whether in this scope it should reverse the behaviour to trigger
> an NPE anyway;
> (c) or, whether it should be ignored as (a), and aside of that it would be
> worth the effort (and technically possible) to add another syntax to force
> NPE over a particular sub-expression (e.g., “foo!.bar”).
>
> Thanks and all the best,
> OC
>
> [*] The name might not be quite apt, for propagating a null is not
> inherently safer than NPEing; those are simply two different approaches,
> both of which serve best in different circumstances. A better name would be
> something like “null-propagating” or “non-NPE” mode, I guess. Myself, I
> don't think we should change the name though, for all are used to it.
>
>

Re: suggestion: ImplicitSafeNavigation annotation

Posted by Paul King <pa...@asert.com.au>.
Sounds like a good candidate for macro methods, maybe extending this:
https://github.com/touchez-du-bois/akatsuki/blob/master/src/main/java/org/jggug/magica/akatsuki/NullSafeMacro.java#L21

I'd be inclined to wait for some macro libraries to be published outside
groovy core to start with and see what usage they get.
If they are popular, we can easily bring them into core perhaps with some
polish/tweaks gained from usage insights.
Once introduced though, it's a little harder to evolve/deprecate/remove
given backwards compatibility etc.

Cheers, Paul.


On Tue, Aug 14, 2018 at 9:28 PM ocs@ocs <oc...@ocs.cz> wrote:

> Gentlemen,
>
> some NPE-related problems of today brought me to re-interate one of my
> older suggestions.
>
> We have the so-called “safe navigation”[*], which in some cases allows a
> null to be propagated out of an expression instead of throwing a NPE. At
> the moment, it can be triggered for a particular sub-expression (like
> property/method-call and, as of 3, newly also indexing) using a question
> mark (e.g., “foo?.bar()” or “foo?[bar]”).
>
> Do please correct me if I am wrong, but far as I know, there still are
> expressions which do not allow the “safe mode”, e.g., arithmetic (“a+b”
> etc). Furthermore, there are cases when one simply wants a bigger block of
> code to contain only null-propagating expressions and never NPE; in such
> case, using the question mark syntax is both inconvenient and error-prone
> (for it is very easy to forget one of the lot of question marks needed in
> such a code, and then get an uncaught unwanted NPE).
>
> For these reasons, I would suggest adding a new annotation, whose name
> might be e.g., “ImplicitSafeNavigation”; it would simply force a
> null-propagation to be implicitly and automatically used for *all*
> expressions in the annotated scope, i.e., NPE would never be thrown for
> them; for example:
>
> ===
> @ImplicitSafeNavigation class Foo {
>  static foo(a,b,c,d,e) {
>    a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any* expression
> which NPEs today
>  }
> }
> assert null == Foo.foo(null,null,null,null,null)
> ===
>
> I wonder whether this enhancement would be possible to implement in some
> forthcoming Groovy release? Myself, I believe it would help tremendously.
>
> If feasible, then it is for a further discussion whether in the scope of
> this annotation
> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as superfluous;
> (b) or, whether in this scope it should reverse the behaviour to trigger
> an NPE anyway;
> (c) or, whether it should be ignored as (a), and aside of that it would be
> worth the effort (and technically possible) to add another syntax to force
> NPE over a particular sub-expression (e.g., “foo!.bar”).
>
> Thanks and all the best,
> OC
>
> [*] The name might not be quite apt, for propagating a null is not
> inherently safer than NPEing; those are simply two different approaches,
> both of which serve best in different circumstances. A better name would be
> something like “null-propagating” or “non-NPE” mode, I guess. Myself, I
> don't think we should change the name though, for all are used to it.
>
>

Re: suggestion: ImplicitSafeNavigation annotation

Posted by "ocs@ocs" <oc...@ocs.cz>.
Jochen,

sorry for the example (I have written it in hurry); it should have looked rather like this:

===
266 /tmp> <q.groovy 
class q {
    static main(args) {
        def mc=new OCSNMC(org.codehaus.groovy.runtime.NullObject)
        mc.initialize()
        org.codehaus.groovy.runtime.NullObject.metaClass=mc

        println "null.foo() is OK: ${null.foo()==null}"
        println "null+null is OK: ${null+null==null}"
        println "null[null] is OK (and no 3 needed, ha!): ${null[null]==null}"
        println "null.foo though we won't see: ${null.foo==null}"
    }
}

class OCSNMC extends DelegatingMetaClass {
    OCSNMC(Class clazz) { super(clazz) }
    Object invokeMethod(Object object, String methodName, Object[] arguments) { null }
    Object getProperty(Class sender, Object receiver, String property, boolean isCallToSuper, boolean fromInsideClass) {
        println "getProperty called!" // actually never happens, dunno why
        null
    }
}
267 /tmp> /usr/local/groovy-2.4.15/bin/groovy q
null.foo() is OK: true
null+null is OK: true
null[null] is OK (and no 3 needed, ha!): true
Caught: java.lang.NullPointerException: Cannot get property 'foo' on null object
java.lang.NullPointerException: Cannot get property 'foo' on null object
	at q.main(q.groovy:10)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
268 /tmp> 
===

Thanks and all the best,
OC

> On 14 Aug 2018, at 7:10 PM, ocs@ocs <oc...@ocs.cz> wrote:
> 
> Jochen,
> 
>> On 14 Aug 2018, at 6:34 PM, Jochen Theodorou <blackdrag@gmx.org <ma...@gmx.org>> wrote:
>> [...]
>>> For the moment, the best solution — far as I have been able to ascertain — consists of [*]
>>> (a) at launch, setting own DelegatingMetaClass subclass for a Null.metaclass; it essentially would return null from invokeMethod, but still needs to process special cases (like e.g., null.is <http://null.is/> <http://null.is <http://null.is/>>(foo)) explicitly;
>> 
>> so for general Groovy... how are we supposed to recognized in a transform if "is" has been replaced?
> 
> It is definitely highly arguable, but in the very specific case of “null?.is(null)“, which currently returns an absurd (though technically understandable) false value, I would rather suggest to break the backward compatibility.
> 
> I can't really see anyone whose code would actually use "?.is", and moreover, rely on that “null?.is(null)“ is valid and returns null (instead of true). Is there such a person in the sweet world?
> 
> Anyway, the point is, I'd say, rather at the unimportant side, for I believe is() is being won't be widely used anyway, given we got === and !=== now.
> 
> Thus, even if we decide that breaking backward compatibility even in this slightly insane case is a big no-no, we just can keep the current behaviour of “null?.is(null)==null“ unchanged. There's no real harm; new code would simply use === instead, and old one would work as before.
> 
>>> (b) since the above for some godforsaken reason does not work for property access at all, still implement an ASTT with a ClassCodeExpressionTransformer to set expression.safe=true for get/setProperty, guarding explicitly against the known problematic cases (e.g., super.getProperty).
>> 
>> are you saying x?.foo will NPE if x is null? Or that x?.getFoo() will NPE in that case? Not sure how to read your comment.
> 
> Provided only (a) “the Null.metaclass; returning null from invokeMethod” is used and no ASTT, then yes, it would NPE. Easiest thing on earth to try:
> 
> ===
> 262 /tmp> <q.groovy                            
> class q {
>     static main(args) {
>         // ExpandoMetaClass.enableGlobally() // I thought this is needed; seems not (though my application use it anyway)
>         def mc=new OCSNMC(org.codehaus.groovy.runtime.NullObject)
>         mc.initialize()
>         org.codehaus.groovy.runtime.NullObject.metaClass=mc
> 
>         println "null.foo() is OK: ${null.foo()==null}"
>         println "null.foo we won't see: ${null.foo==null}"
>     }
> }
> 
> class OCSNMC extends DelegatingMetaClass {
>     OCSNMC(Class clazz){
>         super(clazz)
>     }
>     Object invokeMethod(Object object, String methodName, Object[] arguments) {
>         null
>     }
> }
> 263 /tmp> /usr/local/groovy-2.4.15/bin/groovy q
> null.foo() is OK: true
> Caught: java.lang.NullPointerException: Cannot get property 'foo' on null object
> java.lang.NullPointerException: Cannot get property 'foo' on null object
> 	at q.main(q.groovy:9)
> 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 264 /tmp> 
> ===
> 
>>> For all I know, this probably would not work properly with @CompileStatic (which I do not use at all myself, but others do frequently).
>> 
>> the result type could be a problem... Worth to check.
> 
> Definitely :)
> 
>>> Trust me, been there, done that. I am pretty darn sure it would be /infinitely/ easier and, what's important, more reliable in the core with an explicit compiler support.
>> 
>> How about making a small github project to dump the current state there?
> 
> Not that easy, for my code is mixed up with other ASTT and runtime stuff; but I'll try to make some simple proof-of-concept ASAP and send here.
> 
> Thanks and all the best,
> OC
> 


Re: suggestion: ImplicitSafeNavigation annotation

Posted by "ocs@ocs" <oc...@ocs.cz>.
Jochen,

> On 15 Aug 2018, at 10:13 AM, Jochen Theodorou <bl...@gmx.org> wrote:
> Am 14.08.2018 um 19:10 schrieb ocs@ocs:
>> Jochen,
>>> On 14 Aug 2018, at 6:34 PM, Jochen Theodorou <blackdrag@gmx.org <ma...@gmx.org>> wrote:
> [...]
>>> are you saying x?.foo will NPE if x is null? Or that x?.getFoo() will NPE in that case? Not sure how to read your comment.
>> Provided only (a) “the Null.metaclass; returning null from invokeMethod” is used and no ASTT, then yes, it would NPE. Easiest thing on earth to try:
>> ===
>> 262 */tmp>* <q.groovy
>> class q {
>>     static main(args) {
>>         // ExpandoMetaClass.enableGlobally() // I thought this is needed; seems not (though my application use it anyway)
>>         def mc=new OCSNMC(org.codehaus.groovy.runtime.NullObject)
>>         mc.initialize()
>>         org.codehaus.groovy.runtime.NullObject.metaClass=mc
>>         println "null.foo() is OK: ${null.foo()==null}"
>>         println "null.foo we won't see: ${null.foo==null}"
>>     }
>> }
>> class OCSNMC extends DelegatingMetaClass {
>>     OCSNMC(Class clazz){
>>         super(clazz)
>>     }
>>     Object invokeMethod(Object object, String methodName, Object[] arguments) {
>>         null
>>     }
>> }
> 
> null.foo will of course NPE, if you only take care of invokeMethod. have to do the same treatment for get/setProperty, potentially also for get/setAttribute

That does not help; I do apologise again for sending a wrong example at first — check please instead

> On 14 Aug 2018, at 11:17 PM, ocs@ocs <oc...@ocs.cz> wrote:
> 
> sorry for the example (I have written it in hurry); it should have looked rather like this:
> 
> ===
> 266 /tmp> <q.groovy 
> class q {
>     static main(args) {
>         def mc=new OCSNMC(org.codehaus.groovy.runtime.NullObject)
>         mc.initialize()
>         org.codehaus.groovy.runtime.NullObject.metaClass=mc
> 
>         println "null.foo() is OK: ${null.foo()==null}"
>         println "null+null is OK: ${null+null==null}"
>         println "null[null] is OK (and no 3 needed, ha!): ${null[null]==null}"
>         println "null.foo though we won't see: ${null.foo==null}"
>     }
> }
> 
> class OCSNMC extends DelegatingMetaClass {
>     OCSNMC(Class clazz) { super(clazz) }
>     Object invokeMethod(Object object, String methodName, Object[] arguments) { null }
>     Object getProperty(Class sender, Object receiver, String property, boolean isCallToSuper, boolean fromInsideClass) {
>         println "getProperty called!" // actually never happens, dunno why
>         null
>     }
> }
> 267 /tmp> /usr/local/groovy-2.4.15/bin/groovy q
> null.foo() is OK: true
> null+null is OK: true
> null[null] is OK (and no 3 needed, ha!): true
> Caught: java.lang.NullPointerException: Cannot get property 'foo' on null object
> java.lang.NullPointerException: Cannot get property 'foo' on null object
> 	at q.main(q.groovy:10)
> 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
> 	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
> 	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
> 268 /tmp> 
> ===

Thanks and all the best,
OC

metaclass getProperty does not work at all (2.4) (was: suggestion: ImplicitSafeNavigation annotation)

Posted by "ocs@ocs" <oc...@ocs.cz>.
Jochen,

> On 15 Aug 2018, at 10:13 AM, Jochen Theodorou <bl...@gmx.org> wrote:
> have to do the same treatment for get/setProperty

I have tried repeatedly, but the thing simply does not work :( Any idea why?

===
585 /tmp> <q.groovy 
class q {
    static main(args) {
        def mc=new XMC(q)
        mc.initialize()
        q.metaClass=mc

        def qq=newInstance()
        println "mc used: "+qq.method()
        println "mc NOT used?!?: "+qq.prop
    }
    def method() { return 'm' }
    def prop='p'
}
class XMC extends DelegatingMetaClass {
    XMC(Class clazz) { super(clazz) }
    Object invokeMethod(Object object, String methodName, Object[] arguments) {
        println "invoking '$methodName' for $object"
        super.invokeMethod(object,methodName,arguments)
    }
    Object getProperty(Class sender, Object receiver, String property, boolean isCallToSuper, boolean fromInsideClass) {
        println "getting property '$property' for $receiver"
        super.getProperty(sender,receiver,property,isCallToSuper,fromInsideClass)
    }
}
586 /tmp> /usr/local/groovy-2.4.15/bin/groovy q
WARNING: An illegal reflective access operation has occurred
...
invoking 'method' for q@77102b91
mc used: m
mc NOT used?!?: p
587 /tmp> 
===

Thanks,
OC



Re: suggestion: ImplicitSafeNavigation annotation

Posted by Jochen Theodorou <bl...@gmx.org>.

Am 14.08.2018 um 19:10 schrieb ocs@ocs:
> Jochen,
> 
>> On 14 Aug 2018, at 6:34 PM, Jochen Theodorou <blackdrag@gmx.org 
>> <ma...@gmx.org>> wrote:
[...]
>> are you saying x?.foo will NPE if x is null? Or that x?.getFoo() will 
>> NPE in that case? Not sure how to read your comment.
> 
> Provided only (a) “the Null.metaclass; returning null from invokeMethod” 
> is used and no ASTT, then yes, it would NPE. Easiest thing on earth to try:
> 
> ===
> 262 */tmp>* <q.groovy
> class q {
>      static main(args) {
>          // ExpandoMetaClass.enableGlobally() // I thought this is 
> needed; seems not (though my application use it anyway)
>          def mc=new OCSNMC(org.codehaus.groovy.runtime.NullObject)
>          mc.initialize()
>          org.codehaus.groovy.runtime.NullObject.metaClass=mc
> 
>          println "null.foo() is OK: ${null.foo()==null}"
>          println "null.foo we won't see: ${null.foo==null}"
>      }
> }
> 
> class OCSNMC extends DelegatingMetaClass {
>      OCSNMC(Class clazz){
>          super(clazz)
>      }
>      Object invokeMethod(Object object, String methodName, Object[] 
> arguments) {
>          null
>      }
> }

null.foo will of course NPE, if you only take care of invokeMethod. have 
to do the same treatment for get/setProperty, potentially also for 
get/setAttribute


[...]
>>> For all I know, this probably would not work properly 
>>> with @CompileStatic (which I do not use at all myself, but others do 
>>> frequently).
>>
>> the result type could be a problem... Worth to check.
> 
> Definitely :)

judging by this small snippet:

> @groovy.transform.CompileStatic
> def m() {
>   def foo = "s"
>   def bar = foo?.toUpperCase()
>   println bar.toUpperCase()
> }

and that it compiles (and runs fine) I would say the correct type is 
preserved.

>>> Trust me, been there, done that. I am pretty darn sure it would be 
>>> /infinitely/ easier and, what's important, more reliable in the core 
>>> with an explicit compiler support.
>>
>> How about making a small github project to dump the current state there?
> 
> Not that easy, for my code is mixed up with other ASTT and runtime 
> stuff; but I'll try to make some simple proof-of-concept ASAP and send here.

would help a lot

bye Jochen

Re: suggestion: ImplicitSafeNavigation annotation

Posted by "ocs@ocs" <oc...@ocs.cz>.
Jochen,

> On 14 Aug 2018, at 6:34 PM, Jochen Theodorou <bl...@gmx.org> wrote:
> [...]
>> For the moment, the best solution — far as I have been able to ascertain — consists of [*]
>> (a) at launch, setting own DelegatingMetaClass subclass for a Null.metaclass; it essentially would return null from invokeMethod, but still needs to process special cases (like e.g., null.is <http://null.is>(foo)) explicitly;
> 
> so for general Groovy... how are we supposed to recognized in a transform if "is" has been replaced?

It is definitely highly arguable, but in the very specific case of “null?.is(null)“, which currently returns an absurd (though technically understandable) false value, I would rather suggest to break the backward compatibility.

I can't really see anyone whose code would actually use "?.is", and moreover, rely on that “null?.is(null)“ is valid and returns null (instead of true). Is there such a person in the sweet world?

Anyway, the point is, I'd say, rather at the unimportant side, for I believe is() is being won't be widely used anyway, given we got === and !=== now.

Thus, even if we decide that breaking backward compatibility even in this slightly insane case is a big no-no, we just can keep the current behaviour of “null?.is(null)==null“ unchanged. There's no real harm; new code would simply use === instead, and old one would work as before.

>> (b) since the above for some godforsaken reason does not work for property access at all, still implement an ASTT with a ClassCodeExpressionTransformer to set expression.safe=true for get/setProperty, guarding explicitly against the known problematic cases (e.g., super.getProperty).
> 
> are you saying x?.foo will NPE if x is null? Or that x?.getFoo() will NPE in that case? Not sure how to read your comment.

Provided only (a) “the Null.metaclass; returning null from invokeMethod” is used and no ASTT, then yes, it would NPE. Easiest thing on earth to try:

===
262 /tmp> <q.groovy                            
class q {
    static main(args) {
        // ExpandoMetaClass.enableGlobally() // I thought this is needed; seems not (though my application use it anyway)
        def mc=new OCSNMC(org.codehaus.groovy.runtime.NullObject)
        mc.initialize()
        org.codehaus.groovy.runtime.NullObject.metaClass=mc

        println "null.foo() is OK: ${null.foo()==null}"
        println "null.foo we won't see: ${null.foo==null}"
    }
}

class OCSNMC extends DelegatingMetaClass {
    OCSNMC(Class clazz){
        super(clazz)
    }
    Object invokeMethod(Object object, String methodName, Object[] arguments) {
        null
    }
}
263 /tmp> /usr/local/groovy-2.4.15/bin/groovy q
null.foo() is OK: true
Caught: java.lang.NullPointerException: Cannot get property 'foo' on null object
java.lang.NullPointerException: Cannot get property 'foo' on null object
	at q.main(q.groovy:9)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
264 /tmp> 
===

>> For all I know, this probably would not work properly with @CompileStatic (which I do not use at all myself, but others do frequently).
> 
> the result type could be a problem... Worth to check.

Definitely :)

>> Trust me, been there, done that. I am pretty darn sure it would be /infinitely/ easier and, what's important, more reliable in the core with an explicit compiler support.
> 
> How about making a small github project to dump the current state there?

Not that easy, for my code is mixed up with other ASTT and runtime stuff; but I'll try to make some simple proof-of-concept ASAP and send here.

Thanks and all the best,
OC


Re: suggestion: ImplicitSafeNavigation annotation

Posted by Jochen Theodorou <bl...@gmx.org>.
I have to confess I do like the NPE. It is usually one of the most easy 
to fix exceptions. But well, not everyone likes to program with that I 
understand ;)

More comments inline

Am 14.08.2018 um 15:07 schrieb ocs@ocs:
[...]
> For the moment, the best solution — far as I have been able to ascertain 
> — consists of [*]
> 
> (a) at launch, setting own DelegatingMetaClass subclass for a 
> Null.metaclass; it essentially would return null from invokeMethod, but 
> still needs to process special cases (like e.g., null.is 
> <http://null.is>(foo)) explicitly;

so for general Groovy... how are we supposed to recognized in a 
transform if "is" has been replaced?

> (b) since the above for some godforsaken reason does not work for 
> property access at all, still implement an ASTT with 
> a ClassCodeExpressionTransformer to set expression.safe=true for 
> get/setProperty, guarding explicitly against the known problematic cases 
> (e.g., super.getProperty).

are you saying x?.foo will NPE if x is null? Or that x?.getFoo() will 
NPE in that case? Not sure how to read your comment.

> For all I know, this probably would not work properly 
> with @CompileStatic (which I do not use at all myself, but others do 
> frequently).

the result type could be a problem... Worth to check.

> Trust me, been there, done that. I am pretty darn sure it would be 
> /infinitely/ easier and, what's important, more reliable in the core 
> with an explicit compiler support.

How about making a small github project to dump the current state there?

bye Jochen

Re: suggestion: ImplicitSafeNavigation annotation

Posted by "ocs@ocs" <oc...@ocs.cz>.
Andres,

> On 14 Aug 2018, at 2:31 PM, Andres Almiray <aa...@gmail.com> wrote:
> This is a good example of a feature that can be experimented with as an external AST transformation, there's no need to add it to core just yet.

Not quite, alas. I am experimenting with it for years; it sort of works, but is far from easy or reliable.

To implement the non-NPE null-propagating behaviour solely at the ASTT side is extremely difficult; you have to cope with all the expressions explicitly, you have to manage a number of ugly special and side cases (e.g., AttributeExpression overrides safe as read-only and trying to set it on throws; an attempt to set the safe attribute for a super.whatever causes a verify error; null?.is(null) does not work reasonably, etc...)

For the moment, the best solution — far as I have been able to ascertain — consists of [*]

(a) at launch, setting own DelegatingMetaClass subclass for a Null.metaclass; it essentially would return null from invokeMethod, but still needs to process special cases (like e.g., null.is(foo)) explicitly;

(b) since the above for some godforsaken reason does not work for property access at all, still implement an ASTT with a ClassCodeExpressionTransformer to set expression.safe=true for get/setProperty, guarding explicitly against the known problematic cases (e.g., super.getProperty).

For all I know, this probably would not work properly with @CompileStatic (which I do not use at all myself, but others do frequently).

Trust me, been there, done that. I am pretty darn sure it would be infinitely easier and, what's important, more reliable in the core with an explicit compiler support.

> Advantages of such approach:
>  - faster development/release cycle.
>  - can target specific Groovy version to begin with.
>  - may break compatibility until feature works as expected.

Completely agreed; that's why I am suggesting this only after I used the ASTT/metaclass approach for years — and also when a major version with lots of potential compatibility breaks is about to come soon anyway.

> Adding this feature to core in an early stage (conception) is too early IMHO.
> Remember that @TailCall started life as an external AST xform, it was added to core when it became mature enough :-)

Quite: what I am suggesting is that it's the right time now to add it to core, alleviating the need of the [*] hacks :)

Thanks and all the best,
OC


> -------------------------------------------
> Java Champion; Groovy Enthusiast
> JCP EC Associate Seat
> http://andresalmiray.com <http://andresalmiray.com/>
> http://www.linkedin.com/in/aalmiray <http://www.linkedin.com/in/aalmiray>
> --
> What goes up, must come down. Ask any system administrator.
> There are 10 types of people in the world: Those who understand binary, and those who don't.
> To understand recursion, we must first understand recursion.
> 
> On Tue, Aug 14, 2018 at 1:28 PM, ocs@ocs <ocs@ocs.cz <ma...@ocs.cz>> wrote:
> Gentlemen,
> 
> some NPE-related problems of today brought me to re-interate one of my older suggestions.
> 
> We have the so-called “safe navigation”[*], which in some cases allows a null to be propagated out of an expression instead of throwing a NPE. At the moment, it can be triggered for a particular sub-expression (like property/method-call and, as of 3, newly also indexing) using a question mark (e.g., “foo?.bar()” or “foo?[bar]”).
> 
> Do please correct me if I am wrong, but far as I know, there still are expressions which do not allow the “safe mode”, e.g., arithmetic (“a+b” etc). Furthermore, there are cases when one simply wants a bigger block of code to contain only null-propagating expressions and never NPE; in such case, using the question mark syntax is both inconvenient and error-prone (for it is very easy to forget one of the lot of question marks needed in such a code, and then get an uncaught unwanted NPE).
> 
> For these reasons, I would suggest adding a new annotation, whose name might be e.g., “ImplicitSafeNavigation”; it would simply force a null-propagation to be implicitly and automatically used for *all* expressions in the annotated scope, i.e., NPE would never be thrown for them; for example:
> 
> ===
> @ImplicitSafeNavigation class Foo {
>  static foo(a,b,c,d,e) {
>    a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any* expression which NPEs today
>  }
> }
> assert null == Foo.foo(null,null,null,null,null)
> ===
> 
> I wonder whether this enhancement would be possible to implement in some forthcoming Groovy release? Myself, I believe it would help tremendously.
> 
> If feasible, then it is for a further discussion whether in the scope of this annotation
> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as superfluous;
> (b) or, whether in this scope it should reverse the behaviour to trigger an NPE anyway;
> (c) or, whether it should be ignored as (a), and aside of that it would be worth the effort (and technically possible) to add another syntax to force NPE over a particular sub-expression (e.g., “foo!.bar”).
> 
> Thanks and all the best,
> OC
> 
> [*] The name might not be quite apt, for propagating a null is not inherently safer than NPEing; those are simply two different approaches, both of which serve best in different circumstances. A better name would be something like “null-propagating” or “non-NPE” mode, I guess. Myself, I don't think we should change the name though, for all are used to it.
> 
> 


Re: suggestion: ImplicitSafeNavigation annotation

Posted by Andres Almiray <aa...@gmail.com>.
This is a good example of a feature that can be experimented with as an
external AST transformation, there's no need to add it to core just yet.

Advantages of such approach:
 - faster development/release cycle.
 - can target specific Groovy version to begin with.
 - may break compatibility until feature works as expected.

Adding this feature to core in an early stage (conception) is too early
IMHO.

Remember that @TailCall started life as an external AST xform, it was added
to core when it became mature enough :-)

Cheers,
Andres

-------------------------------------------
Java Champion; Groovy Enthusiast
JCP EC Associate Seat
http://andresalmiray.com
http://www.linkedin.com/in/aalmiray
--
What goes up, must come down. Ask any system administrator.
There are 10 types of people in the world: Those who understand binary, and
those who don't.
To understand recursion, we must first understand recursion.

On Tue, Aug 14, 2018 at 1:28 PM, ocs@ocs <oc...@ocs.cz> wrote:

> Gentlemen,
>
> some NPE-related problems of today brought me to re-interate one of my
> older suggestions.
>
> We have the so-called “safe navigation”[*], which in some cases allows a
> null to be propagated out of an expression instead of throwing a NPE. At
> the moment, it can be triggered for a particular sub-expression (like
> property/method-call and, as of 3, newly also indexing) using a question
> mark (e.g., “foo?.bar()” or “foo?[bar]”).
>
> Do please correct me if I am wrong, but far as I know, there still are
> expressions which do not allow the “safe mode”, e.g., arithmetic (“a+b”
> etc). Furthermore, there are cases when one simply wants a bigger block of
> code to contain only null-propagating expressions and never NPE; in such
> case, using the question mark syntax is both inconvenient and error-prone
> (for it is very easy to forget one of the lot of question marks needed in
> such a code, and then get an uncaught unwanted NPE).
>
> For these reasons, I would suggest adding a new annotation, whose name
> might be e.g., “ImplicitSafeNavigation”; it would simply force a
> null-propagation to be implicitly and automatically used for *all*
> expressions in the annotated scope, i.e., NPE would never be thrown for
> them; for example:
>
> ===
> @ImplicitSafeNavigation class Foo {
>  static foo(a,b,c,d,e) {
>    a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any* expression
> which NPEs today
>  }
> }
> assert null == Foo.foo(null,null,null,null,null)
> ===
>
> I wonder whether this enhancement would be possible to implement in some
> forthcoming Groovy release? Myself, I believe it would help tremendously.
>
> If feasible, then it is for a further discussion whether in the scope of
> this annotation
> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as superfluous;
> (b) or, whether in this scope it should reverse the behaviour to trigger
> an NPE anyway;
> (c) or, whether it should be ignored as (a), and aside of that it would be
> worth the effort (and technically possible) to add another syntax to force
> NPE over a particular sub-expression (e.g., “foo!.bar”).
>
> Thanks and all the best,
> OC
>
> [*] The name might not be quite apt, for propagating a null is not
> inherently safer than NPEing; those are simply two different approaches,
> both of which serve best in different circumstances. A better name would be
> something like “null-propagating” or “non-NPE” mode, I guess. Myself, I
> don't think we should change the name though, for all are used to it.
>
>

Re: suggestion: ImplicitSafeNavigation annotation

Posted by h2...@abula.org.
Den 2018-08-14 15:23, skrev 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.)

I kind of expected that... :-) I am curious about what others think, 
though.

>> If you want a shorthand notation for “a?.plus(b)” I'd say
>> “a?+b” was more consistent
> 
> quite, it might be worth adding to the language too; but it is
> irrelevant to the current case, where the problem with this approach
> is that
> 
>> there are cases when one simply wants a bigger block of code to
>> contain only null-propagating expressions and never NPE; in such
>> case, using the question mark syntax is both inconvenient and
>> error-prone (for it is very easy to forget one of the lot of
>> question marks needed in such a code, and then get an uncaught
>> unwanted NPE).
> 
> As for
> 
>> it would be impossible to know by looking at just the code how it is
>> going to behave
> 
> it would be actually easier than it is now: checking whether an
> annotation is used somewhere is _worlds_ easier than checking whether
> perhaps the Null.metaclass happens not to be overridden with one
> returning null from its invokeMethod — which anyone can do anytime.
> 
>> Wouldn't this create potential problems when the code finds its way
>> into different project by means of dependencies?
> 
> I think not; quite the contrary. When calling a 3rd party code, you
> can't ever know whether the NPE inside of there is caught or not
> anyway, can you?

If it's caught, I expect some some default value to be returned or 
exceptional handling to take place which yields the returned value.

If it isn't, I'll get the exception thrown in my face and will be forced 
to deal with it.

I fear that "safe arithmetic evaluation" may generate more null values 
than it should. If there is a difference between the semantics of "no 
value" and "failing to evaluate", I wouldn't want to obscure this by 
representing them the same way.


> And again as above, whilst an annotation would not be
> self-evident either, it would be at the very least considerably more
> intention-revealing and self-documenting than the current
> “equivalent” of a 3rd party method
> 
> ===
> def foo() {
>   try {
>     ... body which might NPE ...
>   } catch (java.lang.NullPointerException npe) {
>     null
>   }
> }
> ===
> 
> happens to be now.
> 
> Thanks and all the best,
> OC
> 
>> On 14 Aug 2018, at 2:50 PM, h2gr@abula.org wrote:
>> 
>> Den 2018-08-14 14:25, skrev ocs@ocs:
>> H2,
>> On 14 Aug 2018, at 1:38 PM, h2gr@abula.org wrote:
>> IMHO, there is an ever so subtle difference between navigation -
>> using the . operator explictly or implicitly (as with indexing) -
>> and arithmetic.
>> do please correct me if I am wrong, but I understand in Groovy,
>> arithmetic should be just a convenience thin syntactic sugar over
>> messages; e.g., “a+b” should be full equivalent to
>> “a.plus(b)”, but
>> for the syntactic inconvenience:
>> 
> http://docs.groovy-lang.org/latest/html/documentation/#Operator-Overloading
>> To me it seems rather unlucky and inconsistent that although I can
>> write “a?.plus(b)”, I can't do precisely the same with its more
>> convenient “a+b” equivalent. With other operators it is even
>> more
>> important, e.g., “a<<b”, which, in my experience, is used much
>> more
>> often as a shorthand for something like “a.append(b)” with
>> generic
>> objects a and b than as a numeric shift.
> 
> As a matter of personal preference, this is fine with me. If you write
> “a?.plus(b)” you are explicitly going out on a limb, and it is
> explicitly visible what you're doing.
> 
> However, “a+b” should work as one would expect. What might one
> expect? I guess that something to vote over, but I propose that at the
> very least, one should not expect unexpected errors or errors that are
> hard to catch or test. It's better to catch null-related errors where
> they occur than somewhere else because an entire expression gets
> evaluated to null instead of throwing an exception.
> 
> If you want a shorthand notation for “a?.plus(b)” I'd say
> “a?+b” was more consistent (but I am by no means suggesting it).
> 
>>> I am personally perfectly happy for my arithmetic expressions to
>>> fail with any applicable exception if I throw unacceptable values
>>> at them.
>> As for the (in)convenience of NPE vs null-propagation (or, in other
>> words, (un)acceptability of nulls inside expressions), I guess it
>> would rather be in the eye of the beholder.
>> Do please note though I am not suggesting to remove the possibility
>> to
>> rely on NPE which you cherish, nor I am suggesting even changing the
>> default behaviour in the slightest; what I would like to see in
>> Groovy
>> would be a way to intentionally switch to the non-NPE
>> null-propagating
>> behaviour where needed by very explicit using of an appropriate
>> annotation. You, of course, would never be forced to use the thing
>> :)
> 
> Of course not, but it would be impossible to know by looking at just
> the code how it is going to behave.
> 
> Wouldn't this create potential problems when the code finds its way
> into different project by means of dependencies?
> 
>> Thanks and all the best,
>> OC
> 
> Ditto! :-)
> 
> H2
> 
>> Den 2018-08-14 13:28, skrev ocs@ocs:
>> Gentlemen,
>> some NPE-related problems of today brought me to re-interate one of
>> my
>> older suggestions.
>> We have the so-called “safe navigation”[*], which in some cases
>> allows
>> a null to be propagated out of an expression instead of throwing a
>> NPE. At the moment, it can be triggered for a particular
>> sub-expression (like property/method-call and, as of 3, newly also
>> indexing) using a question mark (e.g., “foo?.bar()” or
>> “foo?[bar]”).
>> Do please correct me if I am wrong, but far as I know, there still
>> are
>> expressions which do not allow the “safe mode”, e.g., arithmetic
>> (“a+b” etc). Furthermore, there are cases when one simply wants
>> a
>> bigger block of code to contain only null-propagating expressions
>> and
>> never NPE; in such case, using the question mark syntax is both
>> inconvenient and error-prone (for it is very easy to forget one of
>> the
>> lot of question marks needed in such a code, and then get an
>> uncaught
>> unwanted NPE).
>> For these reasons, I would suggest adding a new annotation, whose
>> name
>> might be e.g., “ImplicitSafeNavigation”; it would simply force a
>> null-propagation to be implicitly and automatically used for *all*
>> expressions in the annotated scope, i.e., NPE would never be thrown
>> for them; for example:
>> ===
>> @ImplicitSafeNavigation class Foo {
>> static foo(a,b,c,d,e) {
>> a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any*
>> expression which NPEs today
>> }
>> }
>> assert null == Foo.foo(null,null,null,null,null)
>> ===
>> I wonder whether this enhancement would be possible to implement in
>> some forthcoming Groovy release? Myself, I believe it would help
>> tremendously.
>> If feasible, then it is for a further discussion whether in the
>> scope
>> of this annotation
>> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as
>> superfluous;
>> (b) or, whether in this scope it should reverse the behaviour to
>> trigger an NPE anyway;
>> (c) or, whether it should be ignored as (a), and aside of that it
>> would be worth the effort (and technically possible) to add another
>> syntax to force NPE over a particular sub-expression (e.g.,
>> “foo!.bar”).
>> Thanks and all the best,
>> OC
>> [*] The name might not be quite apt, for propagating a null is not
>> inherently safer than NPEing; those are simply two different
>> approaches, both of which serve best in different circumstances. A
>> better name would be something like “null-propagating” or
>> “non-NPE”
>> mode, I guess. Myself, I don't think we should change the name
>> though,
>> for all are used to it.

Re: suggestion: ImplicitSafeNavigation annotation

Posted by "ocs@ocs" <oc...@ocs.cz>.
Jochen,

> On 14 Aug 2018, at 6:25 PM, Jochen Theodorou <bl...@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




Re: suggestion: ImplicitSafeNavigation annotation

Posted by Jochen Theodorou <bl...@gmx.org>.

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

bye Jochen

Re: suggestion: ImplicitSafeNavigation annotation

Posted by "ocs@ocs" <oc...@ocs.cz>.
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.)

> If you want a shorthand notation for “a?.plus(b)” I'd say “a?+b” was more consistent

quite, it might be worth adding to the language too; but it is irrelevant to the current case, where the problem with this approach is that

> there are cases when one simply wants a bigger block of code to contain only null-propagating expressions and never NPE; in such case, using the question mark syntax is both inconvenient and error-prone (for it is very easy to forget one of the lot of question marks needed in such a code, and then get an uncaught unwanted NPE).

As for

> it would be impossible to know by looking at just the code how it is going to behave

it would be actually easier than it is now: checking whether an annotation is used somewhere is worlds easier than checking whether perhaps the Null.metaclass happens not to be overridden with one returning null from its invokeMethod — which anyone can do anytime.

> Wouldn't this create potential problems when the code finds its way into different project by means of dependencies?

I think not; quite the contrary. When calling a 3rd party code, you can't ever know whether the NPE inside of there is caught or not anyway, can you? And again as above, whilst an annotation would not be self-evident either, it would be at the very least considerably more intention-revealing and self-documenting than the current “equivalent” of a 3rd party method

===
def foo() {
  try {
    ... body which might NPE ...
  } catch (java.lang.NullPointerException npe) {
    null
  }
}
===

happens to be now.

Thanks and all the best,
OC

> On 14 Aug 2018, at 2:50 PM, h2gr@abula.org wrote:
> 
> Den 2018-08-14 14:25, skrev ocs@ocs:
>> H2,
>>> On 14 Aug 2018, at 1:38 PM, h2gr@abula.org wrote:
>>> IMHO, there is an ever so subtle difference between navigation - using the . operator explictly or implicitly (as with indexing) - and arithmetic.
>> do please correct me if I am wrong, but I understand in Groovy,
>> arithmetic should be just a convenience thin syntactic sugar over
>> messages; e.g., “a+b” should be full equivalent to “a.plus(b)”, but
>> for the syntactic inconvenience:
>> http://docs.groovy-lang.org/latest/html/documentation/#Operator-Overloading
>> To me it seems rather unlucky and inconsistent that although I can
>> write “a?.plus(b)”, I can't do precisely the same with its more
>> convenient “a+b” equivalent. With other operators it is even more
>> important, e.g., “a<<b”, which, in my experience, is used much more
>> often as a shorthand for something like “a.append(b)” with generic
>> objects a and b than as a numeric shift.
> 
> As a matter of personal preference, this is fine with me. If you write “a?.plus(b)” you are explicitly going out on a limb, and it is explicitly visible what you're doing.
> 
> However, “a+b” should work as one would expect. What might one expect? I guess that something to vote over, but I propose that at the very least, one should not expect unexpected errors or errors that are hard to catch or test. It's better to catch null-related errors where they occur than somewhere else because an entire expression gets evaluated to null instead of throwing an exception.
> 
> If you want a shorthand notation for “a?.plus(b)” I'd say “a?+b” was more consistent (but I am by no means suggesting it).
> 
>>> I am personally perfectly happy for my arithmetic expressions to fail with any applicable exception if I throw unacceptable values at them.
>> As for the (in)convenience of NPE vs null-propagation (or, in other
>> words, (un)acceptability of nulls inside expressions), I guess it
>> would rather be in the eye of the beholder.
>> Do please note though I am not suggesting to remove the possibility to
>> rely on NPE which you cherish, nor I am suggesting even changing the
>> default behaviour in the slightest; what I would like to see in Groovy
>> would be a way to intentionally switch to the non-NPE null-propagating
>> behaviour where needed by very explicit using of an appropriate
>> annotation. You, of course, would never be forced to use the thing :)
> 
> Of course not, but it would be impossible to know by looking at just the code how it is going to behave.
> 
> Wouldn't this create potential problems when the code finds its way into different project by means of dependencies?
> 
> 
> 
>> Thanks and all the best,
>> OC
> 
> Ditto! :-)
> 
> H2
> 
>>> Den 2018-08-14 13:28, skrev ocs@ocs:
>>>> Gentlemen,
>>>> some NPE-related problems of today brought me to re-interate one of my
>>>> older suggestions.
>>>> We have the so-called “safe navigation”[*], which in some cases allows
>>>> a null to be propagated out of an expression instead of throwing a
>>>> NPE. At the moment, it can be triggered for a particular
>>>> sub-expression (like property/method-call and, as of 3, newly also
>>>> indexing) using a question mark (e.g., “foo?.bar()” or “foo?[bar]”).
>>>> Do please correct me if I am wrong, but far as I know, there still are
>>>> expressions which do not allow the “safe mode”, e.g., arithmetic
>>>> (“a+b” etc). Furthermore, there are cases when one simply wants a
>>>> bigger block of code to contain only null-propagating expressions and
>>>> never NPE; in such case, using the question mark syntax is both
>>>> inconvenient and error-prone (for it is very easy to forget one of the
>>>> lot of question marks needed in such a code, and then get an uncaught
>>>> unwanted NPE).
>>>> For these reasons, I would suggest adding a new annotation, whose name
>>>> might be e.g., “ImplicitSafeNavigation”; it would simply force a
>>>> null-propagation to be implicitly and automatically used for *all*
>>>> expressions in the annotated scope, i.e., NPE would never be thrown
>>>> for them; for example:
>>>> ===
>>>> @ImplicitSafeNavigation class Foo {
>>>> static foo(a,b,c,d,e) {
>>>>  a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any*
>>>> expression which NPEs today
>>>> }
>>>> }
>>>> assert null == Foo.foo(null,null,null,null,null)
>>>> ===
>>>> I wonder whether this enhancement would be possible to implement in
>>>> some forthcoming Groovy release? Myself, I believe it would help
>>>> tremendously.
>>>> If feasible, then it is for a further discussion whether in the scope
>>>> of this annotation
>>>> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as superfluous;
>>>> (b) or, whether in this scope it should reverse the behaviour to
>>>> trigger an NPE anyway;
>>>> (c) or, whether it should be ignored as (a), and aside of that it
>>>> would be worth the effort (and technically possible) to add another
>>>> syntax to force NPE over a particular sub-expression (e.g.,
>>>> “foo!.bar”).
>>>> Thanks and all the best,
>>>> OC
>>>> [*] The name might not be quite apt, for propagating a null is not
>>>> inherently safer than NPEing; those are simply two different
>>>> approaches, both of which serve best in different circumstances. A
>>>> better name would be something like “null-propagating” or “non-NPE”
>>>> mode, I guess. Myself, I don't think we should change the name though,
>>>> for all are used to it.


Re: suggestion: ImplicitSafeNavigation annotation

Posted by h2...@abula.org.
Den 2018-08-14 14:25, skrev ocs@ocs:
> H2,
> 
>> On 14 Aug 2018, at 1:38 PM, h2gr@abula.org wrote:
>> IMHO, there is an ever so subtle difference between navigation - using 
>> the . operator explictly or implicitly (as with indexing) - and 
>> arithmetic.
> 
> do please correct me if I am wrong, but I understand in Groovy,
> arithmetic should be just a convenience thin syntactic sugar over
> messages; e.g., “a+b” should be full equivalent to “a.plus(b)”, but
> for the syntactic inconvenience:
> 
> http://docs.groovy-lang.org/latest/html/documentation/#Operator-Overloading
> 
> To me it seems rather unlucky and inconsistent that although I can
> write “a?.plus(b)”, I can't do precisely the same with its more
> convenient “a+b” equivalent. With other operators it is even more
> important, e.g., “a<<b”, which, in my experience, is used much more
> often as a shorthand for something like “a.append(b)” with generic
> objects a and b than as a numeric shift.

As a matter of personal preference, this is fine with me. If you write 
“a?.plus(b)” you are explicitly going out on a limb, and it is 
explicitly visible what you're doing.

However, “a+b” should work as one would expect. What might one expect? I 
guess that something to vote over, but I propose that at the very least, 
one should not expect unexpected errors or errors that are hard to catch 
or test. It's better to catch null-related errors where they occur than 
somewhere else because an entire expression gets evaluated to null 
instead of throwing an exception.

If you want a shorthand notation for “a?.plus(b)” I'd say “a?+b” was 
more consistent (but I am by no means suggesting it).

>> I am personally perfectly happy for my arithmetic expressions to fail 
>> with any applicable exception if I throw unacceptable values at them.
> 
> As for the (in)convenience of NPE vs null-propagation (or, in other
> words, (un)acceptability of nulls inside expressions), I guess it
> would rather be in the eye of the beholder.
> 
> Do please note though I am not suggesting to remove the possibility to
> rely on NPE which you cherish, nor I am suggesting even changing the
> default behaviour in the slightest; what I would like to see in Groovy
> would be a way to intentionally switch to the non-NPE null-propagating
> behaviour where needed by very explicit using of an appropriate
> annotation. You, of course, would never be forced to use the thing :)

Of course not, but it would be impossible to know by looking at just the 
code how it is going to behave.

Wouldn't this create potential problems when the code finds its way into 
different project by means of dependencies?



> Thanks and all the best,
> OC

Ditto! :-)

H2

>> Den 2018-08-14 13:28, skrev ocs@ocs:
>>> Gentlemen,
>>> some NPE-related problems of today brought me to re-interate one of 
>>> my
>>> older suggestions.
>>> We have the so-called “safe navigation”[*], which in some cases 
>>> allows
>>> a null to be propagated out of an expression instead of throwing a
>>> NPE. At the moment, it can be triggered for a particular
>>> sub-expression (like property/method-call and, as of 3, newly also
>>> indexing) using a question mark (e.g., “foo?.bar()” or “foo?[bar]”).
>>> Do please correct me if I am wrong, but far as I know, there still 
>>> are
>>> expressions which do not allow the “safe mode”, e.g., arithmetic
>>> (“a+b” etc). Furthermore, there are cases when one simply wants a
>>> bigger block of code to contain only null-propagating expressions and
>>> never NPE; in such case, using the question mark syntax is both
>>> inconvenient and error-prone (for it is very easy to forget one of 
>>> the
>>> lot of question marks needed in such a code, and then get an uncaught
>>> unwanted NPE).
>>> For these reasons, I would suggest adding a new annotation, whose 
>>> name
>>> might be e.g., “ImplicitSafeNavigation”; it would simply force a
>>> null-propagation to be implicitly and automatically used for *all*
>>> expressions in the annotated scope, i.e., NPE would never be thrown
>>> for them; for example:
>>> ===
>>> @ImplicitSafeNavigation class Foo {
>>> static foo(a,b,c,d,e) {
>>>   a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any*
>>> expression which NPEs today
>>> }
>>> }
>>> assert null == Foo.foo(null,null,null,null,null)
>>> ===
>>> I wonder whether this enhancement would be possible to implement in
>>> some forthcoming Groovy release? Myself, I believe it would help
>>> tremendously.
>>> If feasible, then it is for a further discussion whether in the scope
>>> of this annotation
>>> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as 
>>> superfluous;
>>> (b) or, whether in this scope it should reverse the behaviour to
>>> trigger an NPE anyway;
>>> (c) or, whether it should be ignored as (a), and aside of that it
>>> would be worth the effort (and technically possible) to add another
>>> syntax to force NPE over a particular sub-expression (e.g.,
>>> “foo!.bar”).
>>> Thanks and all the best,
>>> OC
>>> [*] The name might not be quite apt, for propagating a null is not
>>> inherently safer than NPEing; those are simply two different
>>> approaches, both of which serve best in different circumstances. A
>>> better name would be something like “null-propagating” or “non-NPE”
>>> mode, I guess. Myself, I don't think we should change the name 
>>> though,
>>> for all are used to it.

Re: suggestion: ImplicitSafeNavigation annotation

Posted by "ocs@ocs" <oc...@ocs.cz>.
Just a followup:

> On 14 Aug 2018, at 2:25 PM, ocs@ocs <oc...@ocs.cz> wrote:
> 
> what I would like to see in Groovy would be a way to intentionally switch to the non-NPE null-propagating behaviour where needed by very explicit using of an appropriate annotation.

... considering that, instead of a simple annotation, one with a boolean parameter to switch the behaviour on and off as needed might be better:

===
@ImplicitSafeNavigation(true) class Foo {
  static foo(a,b,c,d,e) {
    a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any* expression which NPEs today
  }
  @ImplicitSafeNavigation(false) bar(a) {
    a.bar
  }
}
assert null == Foo.foo(null,null,null,null,null)
Foo.bar(null) // throws NPE
===

> Begin forwarded message:
> 
> From: "ocs@ocs" <oc...@ocs.cz>
> Subject: suggestion: ImplicitSafeNavigation annotation
> Date: 14 August 2018 at 1:28:01 PM CEST
> To: dev@groovy.apache.org
> Reply-To: dev@groovy.apache.org
> 
> Gentlemen,
> 
> some NPE-related problems of today brought me to re-interate one of my older suggestions.
> 
> We have the so-called “safe navigation”[*], which in some cases allows a null to be propagated out of an expression instead of throwing a NPE. At the moment, it can be triggered for a particular sub-expression (like property/method-call and, as of 3, newly also indexing) using a question mark (e.g., “foo?.bar()” or “foo?[bar]”).
> 
> Do please correct me if I am wrong, but far as I know, there still are expressions which do not allow the “safe mode”, e.g., arithmetic (“a+b” etc). Furthermore, there are cases when one simply wants a bigger block of code to contain only null-propagating expressions and never NPE; in such case, using the question mark syntax is both inconvenient and error-prone (for it is very easy to forget one of the lot of question marks needed in such a code, and then get an uncaught unwanted NPE).
> 
> For these reasons, I would suggest adding a new annotation, whose name might be e.g., “ImplicitSafeNavigation”; it would simply force a null-propagation to be implicitly and automatically used for *all* expressions in the annotated scope, i.e., NPE would never be thrown for them; for example:
> 
> ===
> @ImplicitSafeNavigation class Foo {
> static foo(a,b,c,d,e) {
>   a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any* expression which NPEs today
> }
> }
> assert null == Foo.foo(null,null,null,null,null)
> ===
> 
> I wonder whether this enhancement would be possible to implement in some forthcoming Groovy release? Myself, I believe it would help tremendously.
> 
> If feasible, then it is for a further discussion whether in the scope of this annotation
> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as superfluous;
> (b) or, whether in this scope it should reverse the behaviour to trigger an NPE anyway;
> (c) or, whether it should be ignored as (a), and aside of that it would be worth the effort (and technically possible) to add another syntax to force NPE over a particular sub-expression (e.g., “foo!.bar”).
> 
> Thanks and all the best,
> OC
> 
> [*] The name might not be quite apt, for propagating a null is not inherently safer than NPEing; those are simply two different approaches, both of which serve best in different circumstances. A better name would be something like “null-propagating” or “non-NPE” mode, I guess. Myself, I don't think we should change the name though, for all are used to it.
> 


Re: suggestion: ImplicitSafeNavigation annotation

Posted by "ocs@ocs" <oc...@ocs.cz>.
H2,

> On 14 Aug 2018, at 1:38 PM, h2gr@abula.org wrote:
> IMHO, there is an ever so subtle difference between navigation - using the . operator explictly or implicitly (as with indexing) - and arithmetic.

do please correct me if I am wrong, but I understand in Groovy, arithmetic should be just a convenience thin syntactic sugar over messages; e.g., “a+b” should be full equivalent to “a.plus(b)”, but for the syntactic inconvenience:

http://docs.groovy-lang.org/latest/html/documentation/#Operator-Overloading

To me it seems rather unlucky and inconsistent that although I can write “a?.plus(b)”, I can't do precisely the same with its more convenient “a+b” equivalent. With other operators it is even more important, e.g., “a<<b”, which, in my experience, is used much more often as a shorthand for something like “a.append(b)” with generic objects a and b than as a numeric shift.

> I am personally perfectly happy for my arithmetic expressions to fail with any applicable exception if I throw unacceptable values at them.

As for the (in)convenience of NPE vs null-propagation (or, in other words, (un)acceptability of nulls inside expressions), I guess it would rather be in the eye of the beholder.

Do please note though I am not suggesting to remove the possibility to rely on NPE which you cherish, nor I am suggesting even changing the default behaviour in the slightest; what I would like to see in Groovy would be a way to intentionally switch to the non-NPE null-propagating behaviour where needed by very explicit using of an appropriate annotation. You, of course, would never be forced to use the thing :)

Thanks and all the best,
OC

> Den 2018-08-14 13:28, skrev ocs@ocs:
>> Gentlemen,
>> some NPE-related problems of today brought me to re-interate one of my
>> older suggestions.
>> We have the so-called “safe navigation”[*], which in some cases allows
>> a null to be propagated out of an expression instead of throwing a
>> NPE. At the moment, it can be triggered for a particular
>> sub-expression (like property/method-call and, as of 3, newly also
>> indexing) using a question mark (e.g., “foo?.bar()” or “foo?[bar]”).
>> Do please correct me if I am wrong, but far as I know, there still are
>> expressions which do not allow the “safe mode”, e.g., arithmetic
>> (“a+b” etc). Furthermore, there are cases when one simply wants a
>> bigger block of code to contain only null-propagating expressions and
>> never NPE; in such case, using the question mark syntax is both
>> inconvenient and error-prone (for it is very easy to forget one of the
>> lot of question marks needed in such a code, and then get an uncaught
>> unwanted NPE).
>> For these reasons, I would suggest adding a new annotation, whose name
>> might be e.g., “ImplicitSafeNavigation”; it would simply force a
>> null-propagation to be implicitly and automatically used for *all*
>> expressions in the annotated scope, i.e., NPE would never be thrown
>> for them; for example:
>> ===
>> @ImplicitSafeNavigation class Foo {
>> static foo(a,b,c,d,e) {
>>   a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any*
>> expression which NPEs today
>> }
>> }
>> assert null == Foo.foo(null,null,null,null,null)
>> ===
>> I wonder whether this enhancement would be possible to implement in
>> some forthcoming Groovy release? Myself, I believe it would help
>> tremendously.
>> If feasible, then it is for a further discussion whether in the scope
>> of this annotation
>> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as superfluous;
>> (b) or, whether in this scope it should reverse the behaviour to
>> trigger an NPE anyway;
>> (c) or, whether it should be ignored as (a), and aside of that it
>> would be worth the effort (and technically possible) to add another
>> syntax to force NPE over a particular sub-expression (e.g.,
>> “foo!.bar”).
>> Thanks and all the best,
>> OC
>> [*] The name might not be quite apt, for propagating a null is not
>> inherently safer than NPEing; those are simply two different
>> approaches, both of which serve best in different circumstances. A
>> better name would be something like “null-propagating” or “non-NPE”
>> mode, I guess. Myself, I don't think we should change the name though,
>> for all are used to it.


Re: suggestion: ImplicitSafeNavigation annotation

Posted by h2...@abula.org.
IMHO, there is an ever so subtle difference between navigation - using 
the . operator explictly or implicitly (as with indexing) - and 
arithmetic.

I am personally perfectly happy for my arithmetic expressions to fail 
with any applicable exception if I throw unacceptable values at them.

H2


Den 2018-08-14 13:28, skrev ocs@ocs:
> Gentlemen,
> 
> some NPE-related problems of today brought me to re-interate one of my
> older suggestions.
> 
> We have the so-called “safe navigation”[*], which in some cases allows
> a null to be propagated out of an expression instead of throwing a
> NPE. At the moment, it can be triggered for a particular
> sub-expression (like property/method-call and, as of 3, newly also
> indexing) using a question mark (e.g., “foo?.bar()” or “foo?[bar]”).
> 
> Do please correct me if I am wrong, but far as I know, there still are
> expressions which do not allow the “safe mode”, e.g., arithmetic
> (“a+b” etc). Furthermore, there are cases when one simply wants a
> bigger block of code to contain only null-propagating expressions and
> never NPE; in such case, using the question mark syntax is both
> inconvenient and error-prone (for it is very easy to forget one of the
> lot of question marks needed in such a code, and then get an uncaught
> unwanted NPE).
> 
> For these reasons, I would suggest adding a new annotation, whose name
> might be e.g., “ImplicitSafeNavigation”; it would simply force a
> null-propagation to be implicitly and automatically used for *all*
> expressions in the annotated scope, i.e., NPE would never be thrown
> for them; for example:
> 
> ===
> @ImplicitSafeNavigation class Foo {
>  static foo(a,b,c,d,e) {
>    a.bar+b*c[d]<<e.bax() // just e.g.; would work with *any*
> expression which NPEs today
>  }
> }
> assert null == Foo.foo(null,null,null,null,null)
> ===
> 
> I wonder whether this enhancement would be possible to implement in
> some forthcoming Groovy release? Myself, I believe it would help
> tremendously.
> 
> If feasible, then it is for a further discussion whether in the scope
> of this annotation
> (a) a safe-navigation syntax (“foo?.bar”) should be ignored as 
> superfluous;
> (b) or, whether in this scope it should reverse the behaviour to
> trigger an NPE anyway;
> (c) or, whether it should be ignored as (a), and aside of that it
> would be worth the effort (and technically possible) to add another
> syntax to force NPE over a particular sub-expression (e.g.,
> “foo!.bar”).
> 
> Thanks and all the best,
> OC
> 
> [*] The name might not be quite apt, for propagating a null is not
> inherently safer than NPEing; those are simply two different
> approaches, both of which serve best in different circumstances. A
> better name would be something like “null-propagating” or “non-NPE”
> mode, I guess. Myself, I don't think we should change the name though,
> for all are used to it.