FAQ

Yet another proposal for lexical variables

J. David Blackstone
Aug 13, 2000 at 9:10 pm
I've spent a good chunk of the weekend reviewing everything that's
been said on the issue, and at the risk of beating a dead horse, I'm
going to submit yet another RFC. This one stands somewhat in
opposition to RFC 6. It will not require strict 'vars.' It goes
along the lines of what Mark-Jason Dominus said some time ago about
requiring a few declarations in exchange for not requiring all of
them.

The proposal is this, in essence: make lexical variables the
default. The local operator or its equivalent will be kept for the
dynamic assignment ability and will become applicable to lexical
variables.

Variables not declared with my will be lexical variables. If a
variable exists in a higher scope (a containing block or file), then
an undeclared variable will be the same as the variable from the
higher scope. The my operator can of course be used to declare a new
lexical variable local to a block or file.

This behavior will, in almost all cases, work exactly the same as
dynamic variables. (The cases where it will not will probably be
variable suicide cases where that wasn't the intended behavior,
anyway.) Conversion will be quite straightforward. Except in cases
where a dynamic variable is accessed from outside of its package, most
"global" variables can become lexical variables declared at the
highest scope within a file.

The only issue that needs to be dealt with is the case where an
undeclared variable is used within a subblock of some sort before it
is used within the containing block, as in:

if ($cond) {
$switch = 1;
}
print "Message\n" if $switch;

There are multiple ways to reconcile this:

*) Before executing a block, detect all undeclared variables within it
and set them up as lexical variables right then an there. (Note that
"before executing a block" can mean immediately before or
compile-time, or whenever. It doesn't matter.) This will result in
the code example above having the intended behavior.

*) Require explicit declarations in such a case. Perl could print a
warning that a variable used within a subblock and a containing block
wasn't declared. This would require a change in programming style,
but is easily convertible.

*) Just let the user hang himself. (Okay, that's not an option, but I
put it in for completeness' sake. I think some people want the users
to hang themselves, but not me.)

I don't think anything I've said here is original, but I think I've
summarized just about everything anybody said we'd need to deal with
if this course of action where taken. I think this will appeal to
people a lot more than RFC 6.

My idea is not necessarily to come up with the "right" idea, but to
present as many good ideas as possible to Larry Wall for
consideration. This proposal is incompatible with others, including
the one I submitted before. What I'd like most to hear now is
comments from people who would like a scheme like this but see holes
in it of some sort. I realize no proposal will satisfy everyone (not
even keeping things exactly the same -- otherwise we wouldn't want
Perl6!), but I want to try to present a complete gamut of options so
that hopefully, somebody will be happy.

Our list's deadline is fast approaching, so I wanted to throw this
out there for discussion so people can begin pointing out holes while
I refine and formalize. RFC within another day, I hope, assuming all
goes well (and remember what Fred Brooks said about programmers
assuming all goes well :).
reply

Search Discussions

1 response

  • Nathan Wiger at Aug 13, 2000 at 9:38 pm

    along the lines of what Mark-Jason Dominus said some time ago about
    requiring a few declarations in exchange for not requiring all of
    them.
    I like it. I thought about this some more too, though, and I fear it
    doesn't have any benefits, beyond making things slower. After all, if
    you're just going to go outward until you find the outermost one, what
    advantage over no-scope dynamic globals does this have?

    I think lexical variables are cool. But I think the more correct method
    is to do the scoping in the reverse from what you mentioned. Declare
    them at the outermost block (whole script, for ex), unless there's a
    my(), in which case the method is the same as currently (explicitly
    scope them to nearest block).
    This behavior will, in almost all cases, work exactly the same as
    dynamic variables.
    Yeah, that's the conclusion I came too as well. One benefit is other
    people can't mess with your variables, though, and I think this is
    definitely worth noting.

    I'm not against this, I just think the scoping should be the reverse:

    1. Outermost block lexicals by default

    2. Explicitly scope to nearest block with my() or our()

    3. If want dynamic, use "global", "dynamic", or some
    other keyword explicitly. Hey, I kinda like "your()".

    If a person wanted different scoping rules beyond this, they could "use
    scope 'subs'" (RFC 64), for example. For backwards compat, we could add
    "use scope 'dynamic'" in which case it was Perl 5 all over again. :-)

    -Nate

Related Discussions

Discussion Navigation
viewthread | post