John Porter <[EMAIL PROTECTED]> writes:
> Ariel Scolnicov wrote:
> > John Porter <[EMAIL PROTECTED]> writes:
> > > foo = bar;
> > >
> > > foo could be just about anything: a string, a hashref, some other
> > > blessed ref (with op"=" possibly overloaded!), or even an lvalue sub.
> > > Do you know? Should you care?
> >
> > I don't know, but I think I should care. Suppose C<bar> holds a
> > reference to a list. What does C<foo = bar> do? Does it make C<foo>
> > another reference to the same list, or does it make C<foo> a reference
> > to a new copy of the same list, or does it make C<foo> a copy of the
> > same list?
>
> My point is that knowing the answer to these questions *already*
> depends on looking up what foo (or $foo, or @foo) is, and how it's
> implemented. By using a simple traditional scalar, $foo, you've
> simply selected one of many possible classes for the object, in which
> case you know what the assignment does. Ditto with @foo. And if you're
> just looking at the context of the assignment, you can't know whether
> $foo (or @foo) is tied, and if it is, what the "assignment" really does.
No, I'm not explaining myself properly. I've never said anything in
my program about C<foo> before this assignment. Maybe I said C<no
strict vars> or C<use vars qw/foo/>. But this is the first use of the
variable. Note that all variables in a program have a first use, so
this is a very real problem.
So how do I make C<foo> into an array in the first place? Well, I say
something like C<foo = (1,2,3)>. But wait -- that's ambiguous! Is
C<foo> now a copy of the list (1,2,3) (in which case it's an array),
or is it a reference to (1,2,3) (in which case it's a scalar)? In the
first case, C<foo = bar> (where C<bar> is an array, assuming I could
ever assign an array to a variable) would perform a copy, while in the
second it would make the two variables refer to the same thing.
Tying is a completely different issue. If I tie a variable, *I'm*
expected to use an extension with proper semantics. If the C<TIE>
method happens to delete all my files, it's not Perl's problem. It's
just like in C++ (or any other language that allows limited user
intervention in the internals): I can redefine operator=() to do
whatever I like, and then it's my problem that I did this. The fact
that the I<user> B<can> do illogical things doesn't mean I<Perl>
B<has> to do them!
There's another problem with saying "Oh, just carry on using the old
type of foo" that scares me even more. There's now no way of knowing
what the code C<foo = bar> does! It depends on what is currently
stored in C<foo>, that is on the I<dynamic> history of program
execution. This is much much worse than even C<local()> variables.
Also, note that C<tie()>ing takes place in a static context (at least
for tying C<my()> variables). But checking the assignments to a
variable is a dynamic check (it depends on the execution path). So
even without crazy C<tie()>s chaos will ensue.
And, of course, having once stored a scalar in C<foo>, I'm doomed to
keep storing scalars in it, as Perl will interpret any assignment to
foo that way.
The only reasonable solution I can see if this proposal is adopted is
to I<require> variable declarations on I<all> variables. These
declarations would need to be quite detailed. For instance, just
declaring scalar / array / hash is not enough:
array bar;
scalar (foo, baz, quux);
bar = get_an_array;
foo = bar; # formerly $foo = \@bar
baz = \foo; # formerly $baz = \$foo; like "baz = \bar"
quux = bar; # $quux = $bar or $quux = $$bar?
In other words, the degree of automatic dereferencing will need to be
addressed in these declarations. I don't know how this could work
(although my ignorance is greater than my authority); but I do know
this has to be made to work to get a coherent proposal.
--
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-7658555 http://3w.compugen.co.il/~ariels