develooper 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


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About