Mailing List Archive

Maybe it's time to disallow two variables with the same name and different sigil?
This bit of horror is still allowed as of Perl 5.38:

    use v5.38;
    my $x = [(1..10)];
    my @x = (11..20);
    say $x->[0];
    say $x[0];

Perhaps it's time to disallow this?
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On Tue, 2 Jan 2024 at 14:15, Robert Rothenberg <rrwo@cpan.org> wrote:

> This bit of horror is still allowed as of Perl 5.38:
>
> use v5.38;
> my $x = [(1..10)];
> my @x = (11..20);
> say $x->[0];
> say $x[0];
>
> Perhaps it's time to disallow this?
>

I think it would break a lot of code, and IMO it's not really a problem.
Sure the example you give is a horror show, but IMO

for my $x (@x) { ... }

is a different story.

cheers,
Yves

--
perl -Mre=debug -e "/just|another|perl|hacker/"
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
Hi there,

On Tue, 2 Jan 2024, demerphq wrote:
> On Tue, 2 Jan 2024 at 14:15, Robert Rothenberg <rrwo@cpan.org> wrote:
>
>> This bit of horror is still allowed as of Perl 5.38:
>>
>> use v5.38;
>> my $x = [(1..10)];
>> my @x = (11..20);
>> say $x->[0];
>> say $x[0];
>>
>> Perhaps it's time to disallow this?
>
> I think it would break a lot of code, and IMO it's not really a problem.

Agreed. It would certainly break some of my code. I also don't see
it as a problem.

Perl has a history of providing enough rope for one to hang himself,
and surely it's possible to write impenetrable code in any language.

One way to do that is to give single-letter names to variables. :)

--

73,
Ged.
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On 2 Jan 2024, at 13:18, demerphq <demerphq@gmail.com> wrote:
> On Tue, 2 Jan 2024 at 14:15, Robert Rothenberg <rrwo@cpan.org> wrote:
>> This bit of horror is still allowed as of Perl 5.38:
>>
>> use v5.38;
>> my $x = [(1..10)];
>> my @x = (11..20);
>> say $x->[0];
>> say $x[0];
>>
>> Perhaps it's time to disallow this?
>
> I think it would break a lot of code, and IMO it's not really a problem. Sure the example you give is a horror show, but IMO
>
> for my $x (@x) { ... }
>
> is a different story.

At the very least it should only be a warning, similar to the variable redeclaration warning. (Which you could easily turn off if you decided that sigils mean something, and $foo is clearly different from @foo. Obviously if you’re using references all the time the sigils are less helpful, but that’s merely another reason to avoid using references if you don’t have to.)

As it happens, at $WORK recently, we decided to call a particular thing “justification” rather than “evidence” so we could say

for my $justification (@justifications) { … }

rather than

for my $evidence (@evidence) { … }

and I wouldn’t mind some tooling that flagged up potentially ambiguous variable names.

And it might catch code where there were two arguably unrelated blocks in the same context, e.g.

my $ok;
if (…) {

$ok = 1;
}
return if !$ok



my @ok;
for my $thing (@things) {
if (…) {
push @ok, $thing;
}
}

That’s probably a sign that you want to refactor this long bunch of code.

But I think it belongs better as a warning, or a PerlCritic plugin, rather than a compile-time error.

Sam
--
Website: http://www.illuminated.co.uk/
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On 02/01/2024 13:27, G.W. Haywood wrote:
> Hi there,
>
> On Tue, 2 Jan 2024, demerphq wrote:
>> On Tue, 2 Jan 2024 at 14:15, Robert Rothenberg <rrwo@cpan.org> wrote:
>>
>>> This bit of horror is still allowed as of Perl 5.38:
>>>
>>>      use v5.38;
>>>      my $x = [(1..10)];
>>>      my @x = (11..20);
>>>      say $x->[0];
>>>      say $x[0];
>>>
>>> Perhaps it's time to disallow this?
>>
>> I think it would break a lot of code, and IMO it's not really a problem.

A lack of strictness is not really a problem until somebody mistypes a
variable name. I recall people being concerned about making strict
enabled by default because it would break existing scripts.

Accidentally adding or omitting a dereference arrow will cause a bug.

>
> Agreed.  It would certainly break some of my code.

What if it can be enabled manually with the feature pragma, or perhaps
disabled with a no-feature pragma?

> Perl has a history of providing enough rope for one to hang himself,
> and surely it's possible to write impenetrable code in any language.

Perl provides the rope because you can use that rope for many things
besides hanging yourself.

What is the use case for giving a scalar and an array or hash the same
name, besides the convenience of not having to think of a different name?

>
> One way to do that is to give single-letter names to variables. :)

This has nothing to do with giving single-letter variable names.
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On Tue, 2 Jan 2024 13:58:49 +0000
Sam Kington <sam@illuminated.co.uk> wrote:

> But I think it belongs better as a warning, or a PerlCritic plugin,
> rather than a compile-time error.

Agree. Stuff like this is best done as a linter tool. I would imagine
PerlCritic can do it. I could also add one to my perl-distrolint if
people thought it interesting.

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS
http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On Tue, Jan 02, 2024 at 01:15:17PM +0000, Robert Rothenberg wrote:
> This bit of horror is still allowed as of Perl 5.38:
>
> ??? use v5.38;
> ? ? my $x = [(1..10)];
> ? ? my @x = (11..20);
> ? ? say $x->[0];
> ??? say $x[0];
>
> Perhaps it's time to disallow this?
>

I'm reminded of https://www.cpan.org/misc/perl.purity.test and the
questions in the "Variables" section.

Myself, I always giggle a little when I find myself using multiple
variables with the same name... And because of the Perl purity test, I
sometimes try to find a use for the hash (in addition to the scalar and
array), before usually switching to a plural name for the @ and a
singular one for the $ (to the relief of my coworkers).

(By the way, what is the custom for hashes? Plural or singular?)

At the package level, multiple variables with the same name are possible
because of typeglobs, and I assume this is where this all comes from.

--
Philippe Bruhat (BooK)

No one profits at the death of another (except for the mortician).
(Moral from Groo The Wanderer #7 (Epic))
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
Thinking about it, I think as a warning works best.

On 02/01/2024 14:25, Paul "LeoNerd" Evans wrote:
> On Tue, 2 Jan 2024 13:58:49 +0000
> Sam Kington <sam@illuminated.co.uk> wrote:
>
>> But I think it belongs better as a warning, or a PerlCritic plugin,
>> rather than a compile-time error.
> Agree. Stuff like this is best done as a linter tool. I would imagine
> PerlCritic can do it. I could also add one to my perl-distrolint if
> people thought it interesting.
>
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
Actually, looking around I think there is already a Perl::Critic rule
for this https://metacpan.org/pod/Perl::Critic::Policy::Variables::NameReuse

On 02/01/2024 14:25, Paul "LeoNerd" Evans wrote:
> On Tue, 2 Jan 2024 13:58:49 +0000
> Sam Kington <sam@illuminated.co.uk> wrote:
>
>> But I think it belongs better as a warning, or a PerlCritic plugin,
>> rather than a compile-time error.
> Agree. Stuff like this is best done as a linter tool. I would imagine
> PerlCritic can do it. I could also add one to my perl-distrolint if
> people thought it interesting.
>
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On Tue, 2 Jan 2024 at 16:53, Philippe Bruhat (BooK) <book@cpan.org> wrote:

> On Tue, Jan 02, 2024 at 01:15:17PM +0000, Robert Rothenberg wrote:
> > This bit of horror is still allowed as of Perl 5.38:
> >
> > use v5.38;
> > my $x = [(1..10)];
> > my @x = (11..20);
> > say $x->[0];
> > say $x[0];
> >
> > Perhaps it's time to disallow this?
> >
>
> I'm reminded of https://www.cpan.org/misc/perl.purity.test and the
> questions in the "Variables" section.
>
> Myself, I always giggle a little when I find myself using multiple
> variables with the same name... And because of the Perl purity test, I
> sometimes try to find a use for the hash (in addition to the scalar and
> array), before usually switching to a plural name for the @ and a
> singular one for the $ (to the relief of my coworkers).
>
> (By the way, what is the custom for hashes? Plural or singular?)
>
> At the package level, multiple variables with the same name are possible
> because of typeglobs, and I assume this is where this all comes from.
>

I think it is just a side-effect of the sigils being part of what makes a
variable unique and that we only consider it problematic because the sigil
used to access an element of an array is different from that of its base
name. If the rule was to write @foo[0] to access the zeroth element of @foo
then there would be less of an issue or concern with colliding with $foo.
It is only because we write $foo[0] that there is a possible collision with
$foo->[0]. Personally speaking, my brain parses the two var names very
differently based on the arrow, but i can understand that some folks
dislike it, and newbies especially will find it confusing. I have read and
written code that does stuff like:

our @array;
my $array = \@array;

for various reasons, and I dont think it is really a problem. Especially in
English where plurals sometimes look like singular names.

yves




--
perl -Mre=debug -e "/just|another|perl|hacker/"
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On 1/2/24 11:19, demerphq wrote:
> On Tue, 2 Jan 2024 at 16:53, Philippe Bruhat (BooK) <book@cpan.org> wrote:
>
> On Tue, Jan 02, 2024 at 01:15:17PM +0000, Robert Rothenberg wrote:
> > This bit of horror is still allowed as of Perl 5.38:
> >
> >     use v5.38;
> >     my $x = [(1..10)];
> >     my @x = (11..20);
> >     say $x->[0];
> >     say $x[0];
> >
> > Perhaps it's time to disallow this?
> >
>
> I'm reminded of https://www.cpan.org/misc/perl.purity.test and the
> questions in the "Variables" section.
>
> Myself, I always giggle a little when I find myself using multiple
> variables with the same name... And because of the Perl purity test, I
> sometimes try to find a use for the hash (in addition to the
> scalar and
> array), before usually switching to a plural name for the @ and a
> singular one for the $ (to the relief of my coworkers).
>
> (By the way, what is the custom for hashes? Plural or singular?)
>
> At the package level, multiple variables with the same name are
> possible
> because of typeglobs, and I assume this is where this all comes from.
>
>
> I think it is just a side-effect of the sigils being part of what
> makes a variable unique and that we only consider it problematic
> because the sigil used to access an element of an array is different
> from that of its base name. If the rule was to write @foo[0] to access
> the zeroth element of @foo then there would be less of an issue or
> concern with colliding with $foo. It is only because we write $foo[0]
> that there is a possible collision with $foo->[0]. Personally
> speaking, my brain parses the two var names very differently based on
> the arrow, but i can understand that some folks dislike it, and
> newbies especially will find it confusing. I have read and written
> code that does stuff like:
>
> our @array;
> my $array = \@array;
>
> for various reasons, and I dont think it is really a problem.
> Especially in English where plurals sometimes look like singular names.
>
> yves
>
>
I use this pattern frequently in the opposite direction to deal with
references to subs

sub foo ($array ) {
    my \@array = $array;
}

(at least until signatures allow ref aliasing).

In any case, I agree with others that the regulation of variable
homonyms is a policy decision best left to a linter, rather than made an
intrinsic part of the language.

Cheers,
Diab
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On Tue, Jan 2, 2024 at 2:15?PM Robert Rothenberg <rrwo@cpan.org> wrote:

> This bit of horror is still allowed as of Perl 5.38:
>
> use v5.38;
> my $x = [(1..10)];
> my @x = (11..20);
> say $x->[0];
> say $x[0];
>
> Perhaps it's time to disallow this?
>

I don't see why this would be a problem. Or better said the only cases that
I've seen where this becomes a problem are cases that don't use strict and
the solution for that is obvious.

Leon
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On 02.01.24 14:15, Robert Rothenberg wrote:
> This bit of horror is still allowed as of Perl 5.38:
>
>     use v5.38;
>     my $x = [(1..10)];
>     my @x = (11..20);
>     say $x->[0];
>     say $x[0];
>
> Perhaps it's time to disallow this?

Then you'll need to rename at least the following:

- $_ and @_
- $ARG and @ARG (from English.pm)
- $ARGV and @ARGV
- $INC, @INC, and %INC
- $+, @+, and %+
- $-, @-, and %-
- $! and %!
- $^H and %^H
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
It'll also break SQL::Translator, b/c the RecDescent parser it uses gives
you @item and %item, which are data structures containing the same data
with different access patterns. That's a use case where you actually WANT
to use the same name (although you could in theory have a reference with
the necessary overloads to give the same behavior)

On Tue, Jan 2, 2024 at 7:06?PM Lukas Mai <lukasmai.403+p5p@gmail.com> wrote:

> On 02.01.24 14:15, Robert Rothenberg wrote:
> > This bit of horror is still allowed as of Perl 5.38:
> >
> > use v5.38;
> > my $x = [(1..10)];
> > my @x = (11..20);
> > say $x->[0];
> > say $x[0];
> >
> > Perhaps it's time to disallow this?
>
> Then you'll need to rename at least the following:
>
> - $_ and @_
> - $ARG and @ARG (from English.pm)
> - $ARGV and @ARGV
> - $INC, @INC, and %INC
> - $+, @+, and %+
> - $-, @-, and %-
> - $! and %!
> - $^H and %^H
>
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On Tue, 2 Jan 2024 13:27:58 +0000 (GMT), "G.W. Haywood" <perl5porters@jubileegroup.co.uk> wrote:

> Hi there,
>
> On Tue, 2 Jan 2024, demerphq wrote:
> > On Tue, 2 Jan 2024 at 14:15, Robert Rothenberg <rrwo@cpan.org> wrote:
> >
> >> This bit of horror is still allowed as of Perl 5.38:
> >>
> >> use v5.38;
> >> my $x = [(1..10)];
> >> my @x = (11..20);
> >> say $x->[0];
> >> say $x[0];
> >>
> >> Perhaps it's time to disallow this?

NO!

> > I think it would break a lot of code, and IMO it's not really a problem.

AGREE!

> Agreed. It would certainly break some of my code. I also don't see
> it as a problem.

Neither do I.

Warnings in this can be done by Perl::Critic::*::*::*::ForbidMultiSigilVariableNames
or the like, which I would disable in my ~/.perlcriticrc immediately

> Perl has a history of providing enough rope for one to hang himself,
> and surely it's possible to write impenetrable code in any language.
>
> One way to do that is to give single-letter names to variables. :)

I fully subscribe to this opinion. I do not even want a warning.

--
H.Merijn Brand https://tux.nl Perl Monger http://amsterdam.pm.org/
using perl5.00307 .. 5.37 porting perl5 on HP-UX, AIX, and Linux
https://tux.nl/email.html http://qa.perl.org https://www.test-smoke.org
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
I've no problem with that.

I actually like the ability to name my different-kind-of variables the same
(which means I don't have to think about names that much).

On Tue, Jan 2, 2024 at 2:15?PM Robert Rothenberg <rrwo@cpan.org> wrote:

> This bit of horror is still allowed as of Perl 5.38:
>
> use v5.38;
> my $x = [(1..10)];
> my @x = (11..20);
> say $x->[0];
> say $x[0];
>
> Perhaps it's time to disallow this?
>
>
>
>
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
> Myself, I always giggle a little when I find myself using multiple
> variables with the same name... And because of the Perl purity test, I
> sometimes try to find a use for the hash (in addition to the scalar and
> array), before usually switching to a plural name for the @ and a
> singular one for the $ (to the relief of my coworkers).
>
> (By the way, what is the custom for hashes? Plural or singular?)
>
> At the package level, multiple variables with the same name are possible
> because of typeglobs, and I assume this is where this all comes from.
>
>
off-topic: :-)

This just reminds me one common SQL coding standard rules: use singular for
table name
When applied to perl, it's better en reading eg:

if ($person[0]{age} > $person[1]{age})

related to topic:
will OP also prohibit same name for:
- sub
- glob
- format
- package name snippet (how to call part separated by :: ?)
- attribute
- regex group (you can use variables there ...)
- contracts (in case perl will ever support it)
...
Re: Maybe it's time to disallow two variables with the same name and different sigil? [ In reply to ]
On 2024-01-03 1:02 a.m., Branislav Zahradník wrote:
> (By the way, what is the custom for hashes? Plural or singular?)
>
> This just reminds me one common SQL coding standard rules: use singular for
> table name
> When applied to perl, it's better en reading eg:
>
> if ($person[0]{age} > $person[1]{age})

I strongly argue against what you just said here.

Common SQL coding standard rules actually recommend PLURAL for the table name;
it is each INDIVIDUAL ROW that is named singular.

A SQL table can be characterized by a Perl array of hashes, and a single SQL row
as a perl hash, same as DBI typically spits out. Proper naming for the people
example is "people" for the whole table/array, and "person" for each individual
table row or array element.

This SQL and Perl respectively are equivalent as far as names and loose logic go:

select person.name, person.age
from people person

map { my $person = $_; [$person->{name}, $person->{age}] } @people

Some people misunderstand SQL and get the impression that the clause "from x y"
is declaring that y is an alias for the entire table x, but that is NOT what it
means, rather the y is a variable representing a SINGLE ROW of x at a time.

And similarly, if you just say "from x" then its meaning is implicitly "from x
x", and references to "x" in select/where/etc are STILL only referring to a
SINGLE ROW and not the entire table; it is best to declare it explicitly if you
want to refer to it so it reads properly.

I feel your example for what reads better is very contrived and doesn't reflect
most real-world usage.

Typical real world usage in both SQL and Perl is that you would be iterating
your table or array and you would be addressing each element in turn which would
have its own named variable, like this:

sort { $a->{age} <=> $b->{age} } @people

Or:

foreach my $person (@people) { ... $person->{age} ... }

Or if one is actually wanting to address 2 specific ordered elements outside of
a sorting operation, then each one probably has a specific meaning so you may
name the individuals, eg $person_a and $person_b.

-- Darren Duncan