Re: Checking for nil return

[email protected] (yary) Sun, 20 Dec 2020 15:01:34 -0500
Newsgroups perl.perl6.language
Message-ID <CAG2CFAaSQ+kSqCPbv7maym=-26heYK8X7J_UG725pLnbt4i+zg@mail.gmail.com>
--00000000000098c59805b6eacfea
Content-Type: text/plain; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

After writing that email, I remembered a bit of logic from a class long
ago, that any assertion made on the empty set is true. Since Nil is a
representation of no results, it would make sense to have assertions about
it return true. I think this example shows an optimization to skip return
type checking on Nil, more than a container reverting to its default value.

In particular the error message on using Nil for "in-check (non-Nil $in)"
says "expected non-Nil but got Nil (Nil)" which is preserving the Nil, it
isn't complaining about Any. And in fact "Any" passes the in-check, as I
expect it to.

I suspect that the return value assertion in the signature is a
work-in-progress=E2=80=93 in fact part of the reason this test uses "subset
non-Nil" is that having a "where" clause in the returns signature is
explicitly a TODO:

    > sub returns-prime (Int $ident --> Int where *.is-prime) { $ident }
    =3D=3D=3DSORRY!=3D=3D=3D Error while compiling:
    Cannot do non-typename cases of type_constraint yet

Thus I think that handling "Nil" in the return type checking is similarly
something that is going to be fixed. Though I am still not completely sure
due to the nature of Nil being a defined type object.

-y


On Sun, Dec 20, 2020 at 2:35 PM Joseph Brenner <[email protected]> wrote:

> yary <[email protected]> wrote:
> > Is this a known issue, or my misunderstanding?
> >
> >> subset non-Nil where * !=3D=3D=3D Nil;
> > (non-Nil)
> >> sub out-check($out) returns non-Nil { return $out }
> > &out-check
> >> out-check(44)
> > 44
> >> out-check(Nil)
> > Nil
> >
> > ^ Huh, I expected an exception on "out-check(Nil)" saying the return
> value
> > failed the "returns" constraint.
>
> I'm seeing the same behavior that Yary does, and it does seem pretty
> peculiar.
>
> I would guess it has to do with this behavior:
>
> # https://docs.raku.org/type/Nil#index-entry-Nil_assignment
>
> # When assigned to a container, the Nil value (but not any subclass
> # of Nil) will attempt to revert the container to its default
> # value; if no such default is declared, Raku assumes Any.
>
> Something like: the Nil is getting transformed into an empty (Any),
> which passes the constraint, but then gets turned back into a Nil
> later.
>

--00000000000098c59805b6eacfea
Content-Type: text/html; charset="UTF-8"
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div dir=3D"ltr"><div di=
r=3D"ltr">After writing that email, I remembered a bit of logic from a clas=
s long ago, that any assertion made on the empty set is true. Since Nil is =
a representation of no results, it would make sense to have assertions abou=
t it return true. I think this example shows an optimization to skip return=
 type checking on Nil, more than a container reverting to its default=C2=A0=
value.<div><br></div><div>In particular the error message on using Nil for =
&quot;in-check (non-Nil $in)&quot; says &quot;expected non-Nil but got Nil =
(Nil)&quot; which is preserving the Nil, it isn&#39;t complaining about Any=
. And in fact=C2=A0&quot;Any&quot; passes the in-check, as I expect it to.<=
/div><div><br></div><div>I suspect that the return value assertion in the s=
ignature is a work-in-progress=E2=80=93 in fact part of the reason this tes=
t uses &quot;subset non-Nil&quot; is that having a &quot;where&quot; clause=
 in the returns signature is explicitly a TODO:</div><div><br></div><div><d=
iv>=C2=A0 =C2=A0 &gt; sub returns-prime (Int $ident --&gt; Int where *.is-p=
rime) { $ident }</div><div>=C2=A0 =C2=A0 =3D=3D=3DSORRY!=3D=3D=3D Error whi=
le compiling:</div><div>=C2=A0 =C2=A0 Cannot do non-typename cases of type_=
constraint yet</div><div><br></div><div>Thus I think that handling &quot;Ni=
l&quot; in the return type checking is similarly something that is going to=
 be fixed. Though I am still not completely sure due to the nature of Nil b=
eing a defined type object.</div><div><br></div><div><div dir=3D"ltr" class=
=3D"gmail_signature">-y<br></div></div><br></div></div></div></div></div></=
div><br><div class=3D"gmail_quote"><div dir=3D"ltr" class=3D"gmail_attr">On=
 Sun, Dec 20, 2020 at 2:35 PM Joseph Brenner &lt;<a href=3D"mailto:doomvox@=
gmail.com">[email protected]</a>&gt; wrote:<br></div><blockquote class=3D"g=
mail_quote" style=3D"margin:0px 0px 0px 0.8ex;border-left-width:1px;border-=
left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">yary =
&lt;<a href=3D"mailto:[email protected]" target=3D"_blank">[email protected]=
m</a>&gt; wrote:<br>
&gt; Is this a known issue, or my misunderstanding?<br>
&gt;<br>
&gt;&gt; subset non-Nil where * !=3D=3D=3D Nil;<br>
&gt; (non-Nil)<br>
&gt;&gt; sub out-check($out) returns non-Nil { return $out }<br>
&gt; &amp;out-check<br>
&gt;&gt; out-check(44)<br>
&gt; 44<br>
&gt;&gt; out-check(Nil)<br>
&gt; Nil<br>
&gt;<br>
&gt; ^ Huh, I expected an exception on &quot;out-check(Nil)&quot; saying th=
e return value<br>
&gt; failed the &quot;returns&quot; constraint.<br>
<br>
I&#39;m seeing the same behavior that Yary does, and it does seem pretty pe=
culiar.<br>
<br>
I would guess it has to do with this behavior:<br>
<br>
# <a href=3D"https://docs.raku.org/type/Nil#index-entry-Nil_assignment" rel=
=3D"noreferrer" target=3D"_blank">https://docs.raku.org/type/Nil#index-entr=
y-Nil_assignment</a><br>
<br>
# When assigned to a container, the Nil value (but not any subclass<br>
# of Nil) will attempt to revert the container to its default<br>
# value; if no such default is declared, Raku assumes Any.<br>
<br>
Something like: the Nil is getting transformed into an empty (Any),<br>
which passes the constraint, but then gets turned back into a Nil<br>
later.<br>
</blockquote></div>

--00000000000098c59805b6eacfea--