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
>
>

Reply via email to