Front page | perl.perl5.porters |
Postings from June 2022
Re: Pre-RFC: yield true feature
Thread Previous
|
Thread Next
From:
Darren Duncan
Date:
June 18, 2022 03:00
Subject:
Re: Pre-RFC: yield true feature
Message ID:
c0b46306-5957-19ca-0146-4b394d661fe3@darrenduncan.net
I was having similar thoughts to what Ricardo said here, back when this thread
was started.
My thought was that if the feature in discussion was being treated consistently,
then it would necessarily have to affect a lot more things.
How I interpret Perl's current behavior is that we have a general feature such
that in any lexical context, meaning a block defined by a pair of curly braces
as well as the base scope of each file, users have the choice of having explicit
return statements or having implicit return statements. In each scope, an
explicit "return" means that is the result value from executing the block/file,
and otherwise if the last statement executed in a scope isn't a "return", then
the result is implicitly what the last statement returns.
So in this context, I interpret a generalization of "yield true" to behave as if
every lexical scope or block or file has an implicit "return true;" added to the
end of it.
So when "yield true" is in effect, every block will return true instead of the
result of the last statement, unless the last statement is a "return" statement.
And even then, logically it still works as if the implicit statement is
present, but its just never executed because the explicit "return" ends the
block before its reached.
In that case, "yield true" absolutely makes sense as a lexical scope, where one
can then turn it on or off between nested scopes.
But then the question is, how much code would this break, that is relying on
implicit returns in blocks. My thought is, it would break a lot, at least in
the case of blocks used within expressions like map/grep/sort/do/etc.
So, I have an alternate proposal:
1. Treat the "yield true" feature like how we treat explicit declarations of
file encoding, in that they are explicitly NOT lexical, and that having one
anywhere in a file causes it to apply to the entire file, and/or it is only
legal for the declaration to exist at the top level of a file and not inside any
block.
2. The above-mentioned version of "yield true" is included automatically when
one says "use v5.38;" and above, meaning the only legal thing one can actually
do is optionally say "no yield_true;" (or they can still say "use yield_true;"
but it would be redundant, unless this is also provided as a CPAN module for use
with older Perls).
3. The "yield true" feature only has any effect on the top-level lexical scope
of a file, meaning what is outside of all curly brace blocks.
4. We also add the ability, if it isn't already allowed, one to use explicit
"return" statements at the top level of a file. This empowers people to
explicitly say that a file returns an explicit value which could be anything
true or false. If that exists, one can say "use 5.38;" WITHOUT having to
explicitly turn off yield_true in order to yield something else, because any
return statement at the top level would override any yield_true that may be in
effect, because the implicit "return true;" at file's end isn't reached.
What are thoughts on this?
-- Darren Duncan
On 2022-06-17 5:00 p.m., Ricardo Signes wrote:
> Porters,
>
> Here's what I think, on the matter of eliminating that pesky magic true value.
>
> In "Foo.pm" we want a way to signal that when require-d, it is treated as if it
> had evaluated to true, even if (say) the last statement is "0;".
>
> The biggest question, for me, is how we signal that. The mostly-undebated
> option here has been:
>
> use feature 'xyzzy'; # for some value of "xyzzy"
>
>
> The problem with that is that "use feature" is always lexical, but it's not
> clear that this makes sense lexically.
>
> require v5.40.0; # assert version number is high enough but do not enable features
>
> do_some_stuff;
>
> package Foo {
> use v5.40.0;
> # strict is on
> }
>
> # strict is off again
>
> more_code_here;
>
> 0;
>
> # EOF
>
>
> If the yield-true feature exists and is enabled by v5.40, what should happen
> here? If it's treated as if on, we're violating the expectation of lexical
> effect. If it's treated as off, we've created a new kind of feature that only
> matters at top-level scope in a file. If a programmer has written all their
> code inside a "package NAME BLOCK" structure, which previously would have no
> particular problem, they now don't fully benefit from "use vX".
>
> All of this /makes sense/, but a large part of getting rid of the need for the
> "magic true value" is to avoid confusing programmers who don't want to think
> about the weird under-the-hood stuff here. I don't think we're avoiding enough
> confusion. The error "Foo.pm did not return a true value." could be worse, but
> it's not the best, either.
>
> Issuing a "use vX doesn't make sense at non-top-level" also seems unappealing.
>
> I don't have a great solution to offer. So far what I've got is:
>
> * if "require" errors because of a false value
> * and the file required did enable the feature
> * but did not /explicitly/ disable it, subsequently
> * /then/, a warning is issued "File.pm did not return a true value. The xyzzy
> feature, which would eliminate this error, was enabled at line 123 but only
> in a limited lexical scope, ending at line 321."
>
> I'm not in love with it.
>
> --
> rjbs
>
Thread Previous
|
Thread Next