[% setvar title Yet another lexical variable proposal: lexical variables made defaultwithout requiring strict 'vars' %]

This file is part of the Perl 6 Archive

Note: these documents may be out of date. Do not use as reference!

To see what is currently happening visit http://www.perl6.org/

TITLE

Yet another lexical variable proposal: lexical variables made default without requiring strict 'vars'

VERSION

  Maintainer: J. David Blackstone <jdavidb@dfw.net>
  Date: 15 Aug 2000
  Last Modified: 26 Sep 2000
  Mailing List: perl6-language-strict@perl.org
  Number: 106
  Version: 2
  Status: Frozen

ABSTRACT

Perl was originally designed around dynamically-scoped variables. Many users would like to see this design flaw fixed, but are disagreed about how to go about it. This proposal suggests making undeclared variables be lexical by default in Perl6 and deals with the possible ambiguities this could bring about. An optional suggestion is made as to how one might go even further and eliminate dynamic variables entirely from the language.

CHANGES

Undeclared variables can be considered a part of the smallest enclosing scope under the "liberal" approach to resolving the "ambiguity" mentioned in the suggestion, but they could also be considered a part of the largest enclosing scope.

DESCRIPTION

Lexically-scoped variables are easy to use and intuitive, in that any lexical variable refers to a variable declared within the current scope or the enclosing scope. The variable can be located by lexically scanning the source code. Dynamic variables, on the other hand, refer to a variable from within the current scope or from within the current subroutines _caller_, which could be anywhere! It is impossible to tell exactly what else might be happening to a dynamic variable, resulting in various action at a distance problems, variable suicide problems, and other difficulties.

Under this proposal, lexical variables are considered to be the norm for Perl6. Any undeclared variable is considered to be a lexical variable.

Scopes

An undeclared variable is lexical and visible only within the scope where it is first used and any scopes contained within that one. The notion of "scope" is the same as Perl has had almost since the beginning: a block (including a subroutine block) begins a new scope; a file is also a scope.

Thus, in the following code segment,

	$x = 15;
	$y = $x;
	while ($y) {
	$z = $y;
	...
	$x += $z;
	}

$x and $y are lexicals contained in the outermost scope (probably a file), while $z is a lexical available only in the while loop. When used within the while loop, $x and $y refer to the same scalars referred to outside of the while loop.

Use of my

In all cases, the my operator behaves as it does in Perl5, allowing local variables that will not interfere with other variables, etc.

Dynamic Assignment

Dynamic assignment is the technical term given to the action performed by local in Perl5 and earlier versions. The value of a variable is saved upon execution of the operator and restored when the current scope ends.

There is no actual reason why dynamic assignment needs to be limited to dynamic variables. This RFC strongly suggests that dynamic assignment be enabled for lexical variables, as well. Programming with all lexicals and occasional use of dynamic assignment can cover many of the cases where dynamically-scoped variables are useful.

Note that local will probably be renamed in Perl6.

Tom Christiansen has mentioned once or twice that Chip Salzenburg seemed to be interested in this idea. It occurs in his (TC's) perl6storm document. It is a shame no one has undertaken to RFC it separately. (Hint, hint. :)

Ambiguity

Several people have raised issues about possible ambiguities with this idea, but they have all been instances of the same problem: the case where an undeclared variable is used first within a block, then within that block's containing scope. For example,

$cond = ...; if ($cond) { ... $color = "blue"; ... } print "The color is $color\n";

The programmer expects the value of $color to be "blue" for the print statement, but in fact $color is a brand-new, undefined, lexical variable.

Translating this block from Perl5 to get the same behavior in Perl6 if this RFC is adopted is straightforward and discussed in the IMPLEMENTATION section.

There are two options for dealing with this construct in new Perl6 code:

Variable declarations

This proposal does not require variable declarations, like the strict 'vars' pragma does, except if the conservative approach is taken to resolving the ambiguity noted above. Even then, declarations are only required in a very few cases.

Some programmers will want a mechanism to require declarations, similar to Perl5's strict 'vars' pragma. The suggestion of this RFC is a pragma called strict 'decs'.

Possible elimination of dynamic variables

This subsection suggests a radical change for Perl6. Everything else in this RFC can be implemented without implementing this idea, if desired. This subsection should be considered "optional."

In most languages, dynamic scoping of variables offers no advantages over lexical scoping, other than dynamic assignment. As noted above, dynamic assignment can be accomplished with the local operator, which can be extended to operate on lexical variables as well as (or even instead of) dynamic variables.

The chief instance where Perl5 requires dynamic variables is in the case of package globals. The package command was created in order to allow for different namespaces that would not conflict, when lexical variables were not available at all in Perl. Now it has been extended for O-O classes.

The following changes could be made involving lexical variables and packages in order to eliminate dynamic variables from the language entirely:

Under the proposal of this optional subsection, it might be desired to implement a pragma to allow the use of dynamic variables.

Also, if this proposal is really a good idea, and if it isn't put into Perl 6 by default (and I would presume it won't), it could at least be made available as a strict pragma to help out the programmers who want to code this way but are too Lazy to depend on their own human nature to not overlook mistakes.

IMPLEMENTATION

Very little will have to be done to translate Perl5 to Perl6 under this proposal. The ambiguous case mentioned above where a variable is used after a block, but not before it, can be disambiguated in all cases with a declaration before the block (100% translation). This works whether the "conservative" or "liberal" approach is adopted.

If you take nothing away from this RFC that you like, please consider carefully the following two paragraphs.

It is suggested that Perl6 be designed with lexicals in mind first, followed by dynamic variables, if appropriate.

If the optional subsection on eliminating dynamic variables entirely is adopted, Perl will completely shed the heritage of dynamic variables. Whatever the case, the language should be designed and implemented in such a way that lexical variables are in the design with dynamic assignment/dynamic variables added in later, rather than the other way around.

REFERENCES

There have been many alternative and conflicting proposals. This RFC does not necessarily attempt to be consistent with any of them, but they are listed here for convenience.

RFC 6: Lexical variables made default

RFC 16: Keep default Perl free of constraints such as warnings and strict

RFC 64: New pragma 'scope' to change Perl's default scoping