Re: RFC: lexical variables made default (revised)

2000-08-05 Thread Nick Ing-Simmons

Nathan Wiger [EMAIL PROTECTED] writes:
   I have retained the title of "Lexical variables made default,"
 because I still feel that that is the primary purpose of this change

First off, I think this is a great idea in principle. However, I don't
think it goes nearly far enough in the implementation. I'd like to
propose something radical.

Consider code like this, which is not uncommon:

   use strict;
   my $var1 = 'some val';
   my $var2 = 'some other val';
  
   sub mysub {
   my($arg1, $arg2) = @_;
   (my $result = $arg1) =~ s/some/every/g;
   return ($result, $arg2);
   }

   my @stuff = mysub($var1, $var2);

You get the idea. Dang there's a lot of my()'s in there! The only thing
I see this RFC changing is the need for the "use strict" statement.
However, the code is still littered with what I would argue are
"useless" my()'s that serve as workarounds for a fundamental flaw in the
langauge: all variables are global by default.

Go look at some Tcl/Tk code for what happens if you make everything 
innermost lexical by default.

You get liberal sprinkling of 

  upvar 2 foo 
  global fred harry

etc.

The problem is you quite often whant variables to cross {} boundaries,
if any mention of thing on left declares it in current scope you 
end up with "upvar" and "global" to say "no I don't mean that".

-- 
Nick Ing-Simmons




Re: RFC: lexical variables made default (revised)

2000-08-04 Thread Ariel Scolnicov

Nathan Wiger [EMAIL PROTECTED] writes:

  You've taken the wrong approach.  If you're writing a big program then
  there should be *no* default scope.  Any variable access is an error
  unless that variable was my()ed or our()ed.  That's basically what
  'strict' gives us.
 
 Fair enough. I've heard several good analyses against my idea, so I'll
 fold. Notice I never claimed it was a *good* idea (hence the lack of
 RFC), but just an idea worth pondering.
 
 However, I do think there's something to be said for a "quick-and-dirty"
 script out of the box that can distinguish between sub{} vars and other
 vars ala C:
 
$user = 'nwiger';
sub whois {
($user) = @_;# different var
# ...
}
print whois($user);

Uhmm, but now you've killed off *any* chance of whois (or any other
sub) *ever* setting $user -- the first time it tries to do that, it
gets a `different var' and the original remains unchanged.

In particular, one of Perl's greatest advantages over Python -- the
existence of real closures -- softly and silently vanishes away.
Consider this code (Perl/Tk code tends to be similar):

   sub make_summer {
 my $x = 0;
 sub { $x += shift }
  }

Then we can say:
  DB2 $a = make_summer

  DB3 $b = make_summer
 
   DB4 x $a-(2)
  2
  DB5 x $a-(3)
  5
  DB6 x $b-(11)
  11
  DB7 x $b-(-1)
  10

But it is impossible to write make_summer with your suggestions in
effect!  Suddenly, the `$x' in the anonymous sub make_summer is trying 
to create becomes a *new* variable, and all state goes away.

What you're proposing seems to be the abolition of *all* scopes from
Perl, except the innermost-sub scope.  This is worse than Pascal.

But here's an idea: suppose you spelt `my' V-A-R.  Then you could say
Perl is forcing you to declare all your variables (which I claim is
essential in a language with useful scopes).  Of course, it's one
character longer, so I suppose `var' is out of the question...

[...]

-- 
Ariel Scolnicov|"GCAAGAATTGAACTGTAG"| [EMAIL PROTECTED]
Compugen Ltd.  |Tel: +972-2-6795059 (Jerusalem) \ We recycle all our Hz
72 Pinhas Rosen St.|Tel: +972-3-7658514 (Main office)`-
Tel-Aviv 69512, ISRAEL |Fax: +972-3-7658555http://3w.compugen.co.il/~ariels



RFC: lexical variables made default (revised)

2000-08-03 Thread J. David Blackstone

  Thanks for the feedback, everyone.  I now believe that what we
really want is what so many have suggested, i.e., making strict 'vars'
the default (in essence, at least).

  I have retained the title of "Lexical variables made default,"
because I still feel that that is the primary purpose of this change,
meaning that in future Perl documentation (books, manpages, classes (I
hope)) new Perl users will first be presented with variables declared
as lexicals with my().

  I want to state up front that I'm not saying anything about the
other uses of use strict.  I think some people would probably want
those on by default, but I consider each piece of strictness to be a
separate issue.  I can also keep up with only so many discussions and
RFCs at once. :)

=head1 TITLE

Lexical variables made default

=head1 VERSION

 Maintainer: J. David Blackstone [EMAIL PROTECTED]
 Date: 1 August 2000
 Version: 2
 Mailing List: perl6-language
 Number: 6

=head1 ABSTRACT

Prior to version 5, all implementations of Perl were designed with
only dynamic (global) variables in mind.  Perl5 provided lexical
variables in a backward compatible way, along with a pragma to force
either declaration of variables or import of dynamic variables.  Perl6
should make lexical variables and required variable declarations the default.

=head1 DESCRIPTION

Dynamically-scoped variables can have many effects which are
counterintuitive and undesirable.  In Perl5, lexically-scoped
variables are available with the Cmy operator.  Without Cmy, a
variable is assumed to be dynamic.

Perl5 provides the Cstrict pragma, which forces the programmer to do
one of three things: 1) declare a variable to be lexical with Cmy;
2) declare a variable to be dynamic with Cour; 3) import a dynamic
variable from another namespace with Cvars or otherwise.  This
forced declaration of variables is generally desirable as good
programming practice, although the ability does exist to turn off the
pragma when necessary.

There are very few circumstances in which dynamic variables have a
distinct advantage over lexicals.  Most modules in the standard
library are deliberately written with Cstrict 'vars' to avoid
interfering with other modules or the application programmer's code. 
More recent and enlightened documentation and educational material
teaches the use of lexical variables as preferred.

In Perl6, the concept of Cstrict 'vars' should on by default.  Every
variable should be declared either as lexical with Cmy or dynamic
with Cour.  New Perl6 programmers should be immediately introduced
to lexical scoping and its benefits.  The ability to disable the
strictness should be retained through Cno strict 'vars'; or an
equivalent, for "quick-and-dirty" programs, backward compatibility,
and where otherwise necessary or desired by those who Know What They
Are Doing.

This RFC is not suggesting that any of the other features of the
Cstrict pragma be on by default (such as C'refs' or C'subs'). 
If that is desired, it should be submitted in a separate RFC.

The Clocal operator is misnamed, since it operates on dynamic
(global) variables.  This operator should be removed or renamed, but
this should be the subject of a separate RFC.

=head1 IMPLEMENTATION

I don't know enough about internals to say anything about
implementation from that standpoint.

The following program examples show how declarations would work.

 my $name = "J. David";   # lexical variable
 our($VERSION) = 5.31;# dynamic variable in current package
 $this *= 7;  # illegal; variables must be
  # declared lexical or dynamic
 my($arg1, $arg2) = @_;   # lexical (traditional for a subroutine)
 {
  no strict 'vars';   # or something new
  $quick = 7; # legal in this scope =
  # dynamic variable in current package  
  $quick *= $main::var;
  print "$quick\n";
 }
 $package::count++;   # always legal (I presume?)

=head2 Alternative

Although the implementation above is currently considered to be the
best, an alternative would allow undeclared lexical variables.  In
this approach, Cstrict 'vars' would become Cstrict 'decs',
requiring declaration of all variables.  Without Cstrict 'decs',
undeclared variables would be considered to be lexical, or variables
could be declared dynamic with Cour or some other syntax.

This approach would require more complexity in Perl5 - Perl6
translation and be a much larger step in a new direction for the
language.  Since the state-of-the-practice of Perl5 programming has
evolved to generally include Cstrict 'vars', it makes more sense to
simply make that the default than to modify the language any further.

=head1 REFERENCES

The section on "Private Variables via my()" in the perlsub manpage.

The Camel book.

=cut

  J. David Blackstone


-
In fact, I'd go as far as to say that it's imperative that you
overstuff your brain 

Re: RFC: lexical variables made default (revised)

2000-08-03 Thread Tom Christiansen

  I have retained the title of "Lexical variables made default,"
because I still feel that that is the primary purpose of this change,
meaning that in future Perl documentation (books, manpages, classes (I
hope)) new Perl users will first be presented with variables declared
as lexicals with my().

Illustrative snippets of tiny code should not confuse the reader
with gratuitous my/our declarations unless these are themselves
central to what is being illustrated.

--tom



Re: RFC: lexical variables made default (revised)

2000-08-03 Thread Nathan Wiger

   I have retained the title of "Lexical variables made default,"
 because I still feel that that is the primary purpose of this change

First off, I think this is a great idea in principle. However, I don't
think it goes nearly far enough in the implementation. I'd like to
propose something radical.

Consider code like this, which is not uncommon:

   use strict;
   my $var1 = 'some val';
   my $var2 = 'some other val';
  
   sub mysub {
   my($arg1, $arg2) = @_;
   (my $result = $arg1) =~ s/some/every/g;
   return ($result, $arg2);
   }

   my @stuff = mysub($var1, $var2);

You get the idea. Dang there's a lot of my()'s in there! The only thing
I see this RFC changing is the need for the "use strict" statement.
However, the code is still littered with what I would argue are
"useless" my()'s that serve as workarounds for a fundamental flaw in the
langauge: all variables are global by default.

Before you write me back and claim heresy, let me explain what I mean.
When the usage of Perl was basically only as "shell scripting on
steroids", all global variables worked fine. However, as Perl 5 became
more and more powerful and extensible, and classes and OOP became
mainstays, this no longer worked. So, my() is now used pervasively to
manually impose much needed compartmentalization of code.

I argue we should fundamentally shift this thinking in Perl 6. Let's
truly have "lexical variables made default". Let's change the above code
to:

   #use strict;  # unneeded, now implied
   $var1 = 'some val';   # my() now default
   $var2 = 'some other val';
  
   sub mysub {
   ($arg1, $arg2) = @_;
   ($result = $arg1) =~ s/some/every/g;
   return ($result, $arg2);
   }

   @stuff = mysub($var1, $var2);

One basic rule of user interface is that "if something's easy and
repetitive, have the computer do it". I would argue my() is such a
beast. I propose these changes:

   1. "use strict" as default
   2. my() the default scope of vars

If Perl 6 is going to be successful and hailed (as I'm sure we all hope
it is), I think it has to offer some clear advantages that make things
easier. Consider which of these sounds more like a benefit:

   1. setting "use strict" on by default, forcing
  users to formally declare all their variables
  as my()'s

   2. making it so that they don't have to anymore

I would argue that (1) is a burden, but (2) is a benefit. Doing it this
way doesn't break scripts either - in fact it makes it easier to avoid
accidental errors, even in "quick-and-dirty" scripting:

   sub square {
   ($x) = @_;
   $x *= $x;  
   }
   $x = 2;
   $ans = square($x);
   print "$x squared is: $ans\n";  # uh-oh

One could argue that "you shouldn't make this mistake", but c'mon. We're
human, and I'm sure everyone on this list has done this. Let's make Perl
6 do the hard work for us. :-) Moreover, we can leave my() just as-is,
so if someone wants to explicitly use it for clarity they're welcome to.

-Nate

P.S. I know that square() example is trite, but it's the best I could do
in 30 seconds. :-)



Re: RFC: lexical variables made default (revised)

2000-08-03 Thread Nathan Wiger

 What lexical scope should $x be _implicitly_ declared in?  Maybe, just
 maybe, we need a my $x at the top to tell us it is outside the scope of the
 first reference.  Otherwise we get three different lexical variables, and an
 undefined value warning at run time.

You're right, great point. There's a lot of details implicit in the
email I sent out, which would have to be worked out.

For example, one solution might be that the default lexical scope is
only delimited on function boundaries:

   # all these are in the same scope
   $x = 2;
   if ( $x ) {
  $y = $x;
   } else {
  $y = 5;
   } 
   print "y = $y\n";# 2

   sub compute {
   ($x, $y) = @_;   # but these aren't
   }

Remember, though, my() remains for use, so if you wanted to partition it
off, you could:

   # separate scopes via my()
   $x = 2;
   if ( $x ) {
  my $y = $x;
   } else {
  my $y = 5;
   } 
   print "y = $y\n";# compile error for $y


I don't intend this to be accepted without a knock-down, drag-out fight
(if at all). However, rather than just set pragmas to different values,
my point is that we shoule re-examine what the goal is, and our
assumptions.

-Nate



Re: RFC: lexical variables made default (revised)

2000-08-03 Thread Nathan Torkington

Nathan Wiger writes:
 I argue we should fundamentally shift this thinking in Perl 6. Let's
 truly have "lexical variables made default".

Ugh.  Baby, bathwater.

If I'm writing a big program, then I want to have to declare all
variables so that Perl can catch errors for me.  That's the big
benefit of strict.  Otherwise you're still going to make typos and
have a bugger of a time tracking them down, because the compiler won't
be helping you do it.

You've taken the wrong approach.  If you're writing a big program then
there should be *no* default scope.  Any variable access is an error
unless that variable was my()ed or our()ed.  That's basically what
'strict' gives us.

The only thing I think we should argue is whether strict should be
default or not.  I could fall both ways.  If there was a command-line
switch to turn it off, then I'd be happy with strict as the default.

Nat



Re: RFC: lexical variables made default (revised)

2000-08-03 Thread Damian Conway

However, I do think there's something to be said for a "quick-and-dirty"
script out of the box that can distinguish between sub{} vars and other
vars ala C:

   $user = 'nwiger';
   sub whois {
   ($user) = @_;# different var
   # ...
   }
   print whois($user);

Are two extra chars really so much to ask?...

   $user = 'nwiger';
   sub whois {
   my($user) = @_;# different var
   # ...
   }

Besides, named arguments will solve this (in fewer chars even :-)...

   $user = 'nwiger';
   sub whois ($user) {
   # ...
   }

Damian



Re: RFC: lexical variables made default (revised)

2000-08-03 Thread Nathan Wiger

 Besides, named arguments will solve this (in fewer chars even :-)...
 
$user = 'nwiger';
sub whois ($user) {
# ...
}
 
 Damian

Great point. I'll "settle" for that (it's what I'm looking for anyways).
:-)

So will these be "automatically-my()ed"? Or will you have to say:

   sub whois (my $user) {
   # ...
   }

This seems more consistent (but there's that dang my() again!) :-)

-Nate