Going back to Dec 3rd explanation: "... I had a chain of methods which should do some side effect. It all went fine only the side effect was not there. I then figured out after some time that one of methods returned Nil and somehow silently it did not do what I expected."
This looks like an incomplete set of rules – an API contract that needs filling in – more than a language issue. From the illustrative example now in play $drone.engine.start; the original code as described in the Dec 3rd extract above, implies these rules: Each method - has a side effect on success, no side effect on failure. - returns a defined object on success. return behavior on failure not explicitly defined. Expectation- failure should show more than lack of side effects plus Nil return value at final step. Now if all of the "$drone" object/class, the "engine" method, and the "start" method are app code, then we can fill out the contract so that $drone.engine.start does the right thing. If on the other hand it was a Rakudo call which returned Nil instead of failing, then there is a language issue. Which is what E.M. posted on Dec 3rd: Nil is really a Failure that doesn't throw. It indicates the absence of a > value where there is one expected. > That is why Nil doesn't throw. If you want to indicate a soft failure, > you should use fail(). > If the chain of methods you mention are core methods, and one of them is > returning Nil, then perhaps we have a bug. Could you elaborate on the > situation where you encountered this? For the sake of discussion, let's fill out the contract each method adheres to. Side effect has no change - has a side effect on success, no side effect on failure. To fulfill the expectation that a failure anywhere "shows up" early, there are a few tweaks available. 1. On failure, method throws an exception/"die"s - https://docs.raku.org/language/exceptions 2. On failure, method returns an failure object - https://docs.raku.org/type/Failure 3. Methods never return Nil. - requires a little work to check at the returns. Any of those will make a failure show up closer to where it happened. I can only recommend #3 in the case where there must be an engine. A slight modification to the example can show why a method may want to return Nil on success, and also show that the behavior of Nil with method calls is actually rather useful: $drone.wheels.lock; If a drone has no wheels, the "wheels" method returns Nil and the code still works. For a drone with wheels, it can throw an exception or return a failure if there's a problem with the "wheels" method– or if the brakes don't work, then "lock" can die or return a failure. -y On Fri, Dec 18, 2020 at 12:58 PM Konrad Bucheli via perl6-users < perl6-us...@perl.org> wrote: > > > On 16.12.20 12:39, Brad Gilbert wrote: > > with $drone.engine { > > .start; > > say "engine started"; > > } > > Now we get the inverse pyramid of doom. Above code does not the same as > mine, it only improves the debugging output, but does not fail: > > with $drone.engine { > .start; > say "engine started"; > } > orelse { > die "looks like we lost the engine"; > } > > My point is that I never expected the engine to be lost, because it is > an integral part of the drone. And that is correct because it was only a > bug in `engine` which was revealed during testing and when fixed I do > not need all this any more. > > So to understand all the implications of > > $drone.engine.start; > > I need in depth Raku understanding. Is that already tribal knowledge?. > Or you have already been hurt by it as I was. It is definitively not > beginner friendly and not even intermediate friendly. > > I feel uncomfortable with that. Whenever I see something like this I > have to be aware that the normally obvious assumptions are incorrect. > These bugs are more difficult to find because the program continues and > only later on you will see that some data or state is incorrect. And the > problem with incorrect data is that you might not even spot it. > > > > > > On Tue, Dec 15, 2020, 11:10 PM Konrad Bucheli via perl6-users > > <perl6-us...@perl.org <mailto:perl6-us...@perl.org>> wrote: > > > > > > Hi Ralph > > > > Thanks a lot for the extensive answer. > > > > I still consider it a trap because it does not do what it tells it > does. > > > > If I have: > > > > say "launching drone"; > > $drone.engine.start; > > say "engine started"; > > > > After I run the above I got both messages, but no propeller > > spinning. So I checked start() in and out, because that is where the > > problem is obviously. > > But it was not, it was in engine(). > > And I want my programming language/runtime to tell me if I am doing > > obviously stupid things. > > Note that it has nothing to do with the "pyramid of doom". It would > > make sense in a pure functional environment, but Raku is > > multi-paradigm, no? > > > > Now to be "safe" (as in fail fast) I have to always > > > > say "launching drone"; > > # this intermediate variable is important defensive programming, > > else it will not explode on Nil if there are stupid errors in > engine() > > my $engine = $drone.engine; > > $engine.start; > > say "engine started"; > > > > which is the opposite of concise. > > > > But Raku is Raku, there is surely a way to make sure that my Nil > > explodes in my code. Is there a `use FailingNil`? > > > > Concerning documentation: I do not know where there is an > > appropriate place to warn about this behavior. There where we teach > > how methods are called? Surely it would not have found me. I look up > > a lot in documentation, but not such trivial stuff. > > > > Cheers > > > > Konrad > > > > From: Ralph Mellor <ralphdjmel...@gmail.com > > <mailto:ralphdjmel...@gmail.com>> > > Sent: Saturday, 5 December 2020 15:58 > > To: Konrad Bucheli <kbuch...@open-systems.com > > <mailto:kbuch...@open-systems.com>> > > Cc: perl6-users <perl6-us...@perl.org <mailto:perl6-us...@perl.org>> > > Subject: Re: Missing NullPointerException > > > > On Thu, Dec 3, 2020 at 10:20 PM Konrad Bucheli via perl6-users > > <perl6-us...@perl.org <mailto:perl6-us...@perl.org>> wrote: > > > > > > What is actually the rationale for such a behaviour? > > > > Ergonomically sound null safety. > > > > First, consider what other languages have. Quoting > > https://en.wikipedia.org/wiki/Safe_navigation_operator > > <https://en.wikipedia.org/wiki/Safe_navigation_operator>: > > > > > In object-oriented programming, the safe navigation operator > > > ... is used to avoid sequential explicit null checks ... > > ... > > > In programming languages where the navigation operator > > > (e.g. ".") leads to an error if applied to a null object, the safe > > > navigation operator stops the evaluation of a method/field > > > chain and returns null as the value of the chain expression. > > ... > > > It is currently supported in languages such as Apex, Groovy, > > > Swift, Ruby, C#, Kotlin, CoffeeScript, Scala, Dart and others. > > ... > > > The main advantage of using this operator is that it avoids the > > > pyramid of doom. ... > > > > Many aspects of Raku's design are better solutions than are found > > in older PLs like those listed above. This is an example. Instead of > > devs having unsafe operations by default, and having to write `?.` > > to get safety, in Raku one just writes `.` and always gets safety. > > > > > For me it was an unexpected trap > > > > This statement couples deep wisdom (the "for me" qualification,, > > deferring it till after you'd first asked about what the rationale > was, > > and sharing your experience) with a Canby.[1] > > > > It's clear that you were missing some knowledge, and that it > > bit you, and are now exploring how best to learn from that. > > > > I accept without reservation the claim it was "unexpected". (That > > is the sort of thing that is typically experienced and reported by > > request of our right hemispheres, and it is generally reliable.) > > > > I also recognize what I imagine as a negative effect associated > > with classifying this experience / situation as a "trap", and the > > negative affect associated with applying that classification, which > > is to say your right hemisphere's experience of that classification. > > > > With that said, I now wish to engage our respective unreliable > > left hemispheres, the ones that drive classification, and wish to > > suggest another way to view this situation. > > > > I would argue that you are classifying safe navigation as a trap, > > and thus likely experiencing it negatively. Perhaps for you this > > can/will instead become a gift (perhaps also unexpected)? > > > > A fundamental part of human experience is interpreting one's > > reactions to things in the light of further knowledge and/or > > experience. Larry has made it clear to me that this is one of > > the keys to his approach to life, and to PL design, in both the > > sense of how he approaches a PL's design and how the PL's > > designed features reward those who think the same way. (I > > have found this endlessly inspiring.) > > > > Applying that to your experience, you could alternately view > > what happened as a surprise that arises from Raku's default > > of safety, which is about freedom (avoiding both the extensive > > boilerplate of the pyramid of doom, and the modern shorter > > but still boilerplate additional ?), and not, it could reasonably > > be argued, about a trap. > > > > cf my discussion of what Vadim Belman had classified as a WAT in > > > https://www.nntp.perl.org/group/perl.perl6.users/2018/09/msg5418.html?mc_phishing_protection_id=45408-bvcv3ppeg2buflbq1e30 > > < > https://www.nntp.perl.org/group/perl.perl6.users/2018/09/msg5418.html?mc_phishing_protection_id=45408-bvcv3ppeg2buflbq1e30 > > > > > > > It all went fine only the side effect was not there. I then > figured > > > out after some time that one of methods returned Nil and > > > somehow silently it did not do what I expected. > > > > The "somehow" was automatic safe navigation, By definition, > > this is silent as far as it goes. > > > > But if you think about it, it wasn't *entirely* silent. You knew > > *something* wasn't working right, because somewhere you > > expected a value and didn't get one. So you then had to go > > chase that down. > > > > This is another pervasive principle in Larry's design approach. > > If a PL tries too hard to avoid programming errors, it becomes > > a police state. If it ignores the potential for programming errors > > it forgets to introduce things like safe navigation by default. > > > > The sweetspot is a balance between trade offs that overall > > lets devs reasonably easily "get" working code (in both the > > sense of arriving at it when writing, and comprehending it > > when reading), and keep making progress in the event of > > things not working out as expected. > > > > I see signs that Raku gets that right a lot of the time for me, > > and for others I see using and discussing it, and that the > > culture is generally agreeably open to figuring out whether > > any given negative experiences are best left as something > > for individual involved devs to adapt to, or as necessitating > > improvements in the doc, or Raku, or Rakudo, or modules etc > > > > And at the foundation of it all, is our open minded but also > > mindful right hemispheres, which it's clear we all share. > > > > Which leads me to a concluding question. > > > > Given your own reflections on the rationale I have described, > > and perhaps the wisdom that comes when we "sleep on it", > > is your conclusion that it would be best if there were some > > change in the doc, or Raku, or Rakudo, etc., or does it make > > enough sense now that it was, in the final analysis, really > > just unexpected rather than also being a trap? > > > > love, raiph > > > > [1] > > > http://quotegeek.com/literature/norton-juster/the-phantom-tollbooth/3184/?mc_phishing_protection_id=45408-bvcv3ppeg2buflbq1e30 > > < > http://quotegeek.com/literature/norton-juster/the-phantom-tollbooth/3184/?mc_phishing_protection_id=45408-bvcv3ppeg2buflbq1e30 > > > > > > -- > Konrad Bucheli > Systems Engineering Fellow > > O. +41 58 100 10 10 > W. open-systems.com > > Open Systems > >