Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

print/printf/say/sort (...) interpreted as function limited to " " as a whitespace in front of "(" #13949

Open
p5pRT opened this issue Jun 21, 2014 · 12 comments

Comments

@p5pRT
Copy link

p5pRT commented Jun 21, 2014

Migrated from rt.perl.org#122150 (status was 'open')

Searchable as RT122150$

@p5pRT
Copy link
Author

p5pRT commented Jun 21, 2014

From @avar

Created by @avar

This is a minor bug that's been present ever since the perl 4 era. We
have a warning that's supposed to warn about confusing use of
print/printf/say/sort as a function, i.e. this is OK​:

  $ ./perl -we 'print("")'

But this is warned about​:

  $ ./perl -we 'print ("")'
  print (...) interpreted as function at -e line 1.

However S_checkcomma() in toke.c that implements this just does​:

  if (*s == ' ' && s[1] == '(') { /* XXX gotta be a better way */

So we will only catch cases of /\b(?​:print|printf|say|sort) \(/, but
we should instead do the equivalent of matching any non-zero
whitespace, including newlines and tabs, i.e. something like
/\b(?​:print|printf|say|sort)\s+\(/s.

The function already uses the correct isSPACE() macro later on, the
code just needs to be re-arranged to use that to eat up space between
the function and "(", and warn if there's any.

Perl Info

Flags:
    category=core
    severity=low

Site configuration information for perl 5.21.2:

Configured by avar at Sat Jun 21 13:02:19 UTC 2014.

Summary of my perl5 (revision 5 version 21 subversion 2) configuration:
  Local Commit: 946bd120154b4b2b68a03ca473e15e5f03eb2ff6
  Ancestor: 04e0f0c28a521a290f29301e7b2abe43d65a5339
  Platform:
    osname=linux, osvers=3.2.0-4-amd64, archname=x86_64-linux-thread-multi
    uname='linux u.nix.is 3.2.0-4-amd64 #1 smp debian 3.2.35-2 x86_64 gnulinux '
    config_args='-DDEBUGGING=both -Doptimize=-ggdb3 -Dusethreads -Dprefix=/home/avar/perl5/installed -Dusedevel -des'
    hint=recommended, useposix=true, d_sigaction=define
    useithreads=define, usemultiplicity=define
    use64bitint=define, use64bitall=define, uselongdouble=undef
    usemymalloc=n, bincompat5005=undef
  Compiler:
    cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64',
    optimize='-ggdb3',
    cppflags='-D_REENTRANT -D_GNU_SOURCE -DDEBUGGING -fno-strict-aliasing -pipe -fstack-protector -I/usr/local/include'
    ccversion='', gccversion='4.2.1 Compatible Debian Clang 3.3 (branches/release_33)', gccosandvers=''
    intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
    d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=16
    ivtype='long', ivsize=8, nvtype='double', nvsize=8, Off_t='off_t', lseeksize=8
    alignbytes=8, prototype=define
  Linker and Libraries:
    ld='cc', ldflags =' -fstack-protector -L/usr/local/lib'
    libpth=/usr/local/lib /usr/include/x86_64-linux-gnu /usr/lib /lib/x86_64-linux-gnu /lib/../lib /usr/lib/x86_64-linux-gnu /usr/lib/../lib /lib
    libs=-lnsl -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
    perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
    libc=libc-2.18.so, so=so, useshrplib=false, libperl=libperl.a
    gnulibc_version='2.18'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
    cccdlflags='-fPIC', lddlflags='-shared -ggdb3 -L/usr/local/lib -fstack-protector'

Locally applied patches:
    d1e978ede81bb0602bdb1f26093a7b58d245bcec
    946bd120154b4b2b68a03ca473e15e5f03eb2ff6


@INC for perl 5.21.2:
    lib
    /home/avar/perl5/installed/lib/site_perl/5.21.2/x86_64-linux-thread-multi
    /home/avar/perl5/installed/lib/site_perl/5.21.2
    /home/avar/perl5/installed/lib/5.21.2/x86_64-linux-thread-multi
    /home/avar/perl5/installed/lib/5.21.2
    /home/avar/perl5/installed/lib/site_perl
    .


Environment for perl 5.21.2:
    HOME=/home/avar
    LANG=en_US.UTF-8
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/avar/local/bin:/home/avar/perl5/installed/bin:/home/v-perlbrew/perl5/perlbrew/perls/perl-5.19.6/bin:/home/v-perlbrew/perl5/perlbrew/bin:/home/v-perlbrew/perl5/perlbrew/perls/current/bin:/home/avar/local/bin:/home/avar/g/misc-scripts:/home/avar/bin:/usr/local/bin:/usr/bin:/bin:/usr/games
    PERLDOC=-MPod::Text::Ansi
    PERL_BADLANG (unset)
    SHELL=/bin/bash

@p5pRT
Copy link
Author

p5pRT commented Jun 29, 2014

From @jkeenan

On Sat Jun 21 06​:29​:01 2014, avar wrote​:

This is a bug report for perl from avar@​cpan.org,
generated with the help of perlbug 1.40 running under perl 5.21.2.

-----------------------------------------------------------------
[Please describe your issue here]

This is a minor bug that's been present ever since the perl 4 era. We
have a warning that's supposed to warn about confusing use of
print/printf/say/sort as a function, i.e. this is OK​:

$ ./perl -we 'print("")'

But this is warned about​:

$ ./perl -we 'print ("")'
print (...) interpreted as function at -e line 1.

However S_checkcomma() in toke.c that implements this just does​:

if (*s == ' ' && s[1] == '(') { /* XXX gotta be a better way */

So we will only catch cases of /\b(?​:print|printf|say|sort) \(/, but
we should instead do the equivalent of matching any non-zero
whitespace, including newlines and tabs, i.e. something like
/\b(?​:print|printf|say|sort)\s+\(/s.

The function already uses the correct isSPACE() macro later on, the
code just needs to be re-arranged to use that to eat up space between
the function and "(", and warn if there's any.

If we've lived with this bug for 20 years, I imagine some would say, "Why can't we live with it for another 20 years?"

More to the point, what might break if we fixed it?

Could you provide tests that would demonstrate that the bug is fixed if we do decide to fix it?

Thank you very much.
Jim Keenan

@p5pRT
Copy link
Author

p5pRT commented Jun 29, 2014

The RT System itself - Status changed from 'new' to 'open'

@p5pRT
Copy link
Author

p5pRT commented Jun 29, 2014

From @avar

On Sun, Jun 29, 2014 at 3​:11 AM, James E Keenan via RT
<perlbug-followup@​perl.org> wrote​:

On Sat Jun 21 06​:29​:01 2014, avar wrote​:

This is a bug report for perl from avar@​cpan.org,
generated with the help of perlbug 1.40 running under perl 5.21.2.

-----------------------------------------------------------------
[Please describe your issue here]

This is a minor bug that's been present ever since the perl 4 era. We
have a warning that's supposed to warn about confusing use of
print/printf/say/sort as a function, i.e. this is OK​:

$ ./perl -we 'print("")'

But this is warned about​:

$ ./perl -we 'print ("")'
print (...) interpreted as function at -e line 1.

However S_checkcomma() in toke.c that implements this just does​:

if (*s == ' ' && s[1] == '(') { /* XXX gotta be a better way */

So we will only catch cases of /\b(?​:print|printf|say|sort) \(/, but
we should instead do the equivalent of matching any non-zero
whitespace, including newlines and tabs, i.e. something like
/\b(?​:print|printf|say|sort)\s+\(/s.

The function already uses the correct isSPACE() macro later on, the
code just needs to be re-arranged to use that to eat up space between
the function and "(", and warn if there's any.

If we've lived with this bug for 20 years, I imagine some would say, "Why can't we live with it for another 20 years?"

It's certainly not very high priority, just something I noticed while
spelunking through the source and thought I'd report.

More to the point, what might break if we fixed it?

The behavior of the parser would still be the same, it would just warn
in more cases than it does now. So nothing would break, but the
warning would be corrected.

Could you provide tests that would demonstrate that the bug is fixed if we do decide to fix it?

Since the warning literally checks for " " followed by "(" but should
check for any non-zero amount of whitespace the test is just to test
that things like​: "print ('')" "print\n('')" etc. warn, with some
combinations of whitespace, i.e. [\n\t ] etc.

But as long is it's using the isSPACE() macro instead of the current
test it'll work as well as anything else that's eating up whitespace
in the parser.

@p5pRT
Copy link
Author

p5pRT commented Jun 29, 2014

From @Tux

On Sun, 29 Jun 2014 12​:58​:07 +0200, Ævar Arnfjörð Bjarmason
<avar@​cpan.org> wrote​:

This is a minor bug that's been present ever since the perl 4 era. We
have a warning that's supposed to warn about confusing use of
print/printf/say/sort as a function, i.e. this is OK​:

$ ./perl -we 'print("")'

But this is warned about​:

$ ./perl -we 'print ("")'
print (...) interpreted as function at -e line 1.

I agree with Abigail that this could be nominated to one of the worst
warnings ever added to perl.

In *my* perception the warning is the wrong way round.

Just remove the warning completely.

However S_checkcomma() in toke.c that implements this just does​:

if (*s == ' ' && s[1] == '(') { /* XXX gotta be a better way */

So we will only catch cases of /\b(?​:print|printf|say|sort) \(/, but
we should instead do the equivalent of matching any non-zero
whitespace, including newlines and tabs, i.e. something like
/\b(?​:print|printf|say|sort)\s+\(/s.

The function already uses the correct isSPACE() macro later on, the
code just needs to be re-arranged to use that to eat up space between
the function and "(", and warn if there's any.

If we've lived with this bug for 20 years, I imagine some would say,
"Why can't we live with it for another 20 years?"

It's certainly not very high priority, just something I noticed while
spelunking through the source and thought I'd report.

More to the point, what might break if we fixed it?

The behavior of the parser would still be the same, it would just warn
in more cases than it does now. So nothing would break, but the
warning would be corrected.

Could you provide tests that would demonstrate that the bug is fixed
if we do decide to fix it?

Fix it by removing the warning.

Since the warning literally checks for " " followed by "(" but should
check for any non-zero amount of whitespace the test is just to test
that things like​: "print ('')" "print\n('')" etc. warn, with some
combinations of whitespace, i.e. [\n\t ] etc.

But as long is it's using the isSPACE() macro instead of the current
test it'll work as well as anything else that's eating up whitespace
in the parser.

--
H.Merijn Brand http​://tux.nl Perl Monger http​://amsterdam.pm.org/
using perl5.00307 .. 5.19 porting perl5 on HP-UX, AIX, and openSUSE
http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org/
http​://qa.perl.org http​://www.goldmark.org/jeff/stupid-disclaimers/

@p5pRT
Copy link
Author

p5pRT commented Jun 29, 2014

From @ikegami

On Sun, Jun 29, 2014 at 8​:16 AM, H.Merijn Brand <h.m.brand@​xs4all.nl> wrote​:

I agree with Abigail that this could be nominated to one of the worst
warnings ever added to perl.

In *my* perception the warning is the wrong way round.

C<< print( ($x+2)*5 ); >> should warn???

You probably mean that C<< print ($x+2)*5; >> should mean C<< print
+($x+2)*5; >>, but removing the warning won't do that.

Just remove the warning completely.

We use to get lots of questions about print print the wrong stuff. We don't
anymore. The warning is doing its job, and removing it won't do anyone any
good.

@p5pRT
Copy link
Author

p5pRT commented Jun 29, 2014

From @Tux

On Sun, 29 Jun 2014 13​:28​:32 -0400, Eric Brine <ikegami@​adaelis.com>
wrote​:

On Sun, Jun 29, 2014 at 8​:16 AM, H.Merijn Brand <h.m.brand@​xs4all.nl> wrote​:

I agree with Abigail that this could be nominated to one of the worst
warnings ever added to perl.

In *my* perception the warning is the wrong way round.

C<< print( ($x+2)*5 ); >> should warn???

*my* preference for writing functions is to put a space between the
function name and the opening paren. Any other format is in *my*
perception ugly and not logical.

Good​: print (($x + 2) * 5);
Bad​: print( ( $x+2 )*5 );

Feel free to disagree.

That is part of the beauty of the language perl​: it allows us to
create art in the way the programmer thinks it is most logical and/or
beautiful.

$x++ if $a;
$a and $x++;

are exactly the same in the code, but part of us prefer the first in
reading, part of us prefer the second.

You probably mean that C<< print ($x+2)*5; >> should mean C<< print
+($x+2)*5; >>, but removing the warning won't do that.

Just remove the warning completely.

We use to get lots of questions about print print the wrong stuff. We don't
anymore. The warning is doing its job, and removing it won't do anyone any
good.

It *never* warned me about what its warning is written for.

--
H.Merijn Brand http​://tux.nl Perl Monger http​://amsterdam.pm.org/
using perl5.00307 .. 5.19 porting perl5 on HP-UX, AIX, and openSUSE
http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org/
http​://qa.perl.org http​://www.goldmark.org/jeff/stupid-disclaimers/

@p5pRT
Copy link
Author

p5pRT commented Jun 29, 2014

From @avar

It wasn't a useful warning for you. But I think it's useful to step back
and think about what's useful to the average user of Perl. None of us are
that guy, we all have a commit bit. These warnings aren't for us. We
already know the ins and outs of Perl.

I'm not saying we should keep this particular warning or any other warning.
I'm just saying that arguing that we should or should not keep a warning is
an inherent fallacy. We are not the users of these warning, less clueful
people are. How can we make Perl more useful for them?
On 29 Jun 2014 20​:02, "H.Merijn Brand" <h.m.brand@​xs4all.nl> wrote​:

On Sun, 29 Jun 2014 13​:28​:32 -0400, Eric Brine <ikegami@​adaelis.com>
wrote​:

On Sun, Jun 29, 2014 at 8​:16 AM, H.Merijn Brand <h.m.brand@​xs4all.nl>
wrote​:

I agree with Abigail that this could be nominated to one of the worst
warnings ever added to perl.

In *my* perception the warning is the wrong way round.

C<< print( ($x+2)*5 ); >> should warn???

*my* preference for writing functions is to put a space between the
function name and the opening paren. Any other format is in *my*
perception ugly and not logical.

Good​: print (($x + 2) * 5);
Bad​: print( ( $x+2 )*5 );

Feel free to disagree.

That is part of the beauty of the language perl​: it allows us to
create art in the way the programmer thinks it is most logical and/or
beautiful.

$x++ if $a;
$a and $x++;

are exactly the same in the code, but part of us prefer the first in
reading, part of us prefer the second.

You probably mean that C<< print ($x+2)*5; >> should mean C<< print
+($x+2)*5; >>, but removing the warning won't do that.

Just remove the warning completely.

We use to get lots of questions about print print the wrong stuff. We
don't
anymore. The warning is doing its job, and removing it won't do anyone
any
good.

It *never* warned me about what its warning is written for.

--
H.Merijn Brand http​://tux.nl Perl Monger http​://amsterdam.pm.org/
using perl5.00307 .. 5.19 porting perl5 on HP-UX, AIX, and openSUSE
http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org/
http​://qa.perl.org http​://www.goldmark.org/jeff/stupid-disclaimers/

@p5pRT
Copy link
Author

p5pRT commented Jun 29, 2014

From @avar

I meant that "arguing on the basis of our own personal preference is an
inherent fallacy". I.e. how can we find out what's useful for the greatest
number of Perl users.

Can't we all agree that that's what we're ultimately aiming for?
On 29 Jun 2014 22​:26, "Ævar Arnfjörð Bjarmason via RT" <
perlbug-followup@​perl.org> wrote​:

It wasn't a useful warning for you. But I think it's useful to step back
and think about what's useful to the average user of Perl. None of us are
that guy, we all have a commit bit. These warnings aren't for us. We
already know the ins and outs of Perl.

I'm not saying we should keep this particular warning or any other warning.
I'm just saying that arguing that we should or should not keep a warning is
an inherent fallacy. We are not the users of these warning, less clueful
people are. How can we make Perl more useful for them?
On 29 Jun 2014 20​:02, "H.Merijn Brand" <h.m.brand@​xs4all.nl> wrote​:

On Sun, 29 Jun 2014 13​:28​:32 -0400, Eric Brine <ikegami@​adaelis.com>
wrote​:

On Sun, Jun 29, 2014 at 8​:16 AM, H.Merijn Brand <h.m.brand@​xs4all.nl>
wrote​:

I agree with Abigail that this could be nominated to one of the worst
warnings ever added to perl.

In *my* perception the warning is the wrong way round.

C<< print( ($x+2)*5 ); >> should warn???

*my* preference for writing functions is to put a space between the
function name and the opening paren. Any other format is in *my*
perception ugly and not logical.

Good​: print (($x + 2) * 5);
Bad​: print( ( $x+2 )*5 );

Feel free to disagree.

That is part of the beauty of the language perl​: it allows us to
create art in the way the programmer thinks it is most logical and/or
beautiful.

$x++ if $a;
$a and $x++;

are exactly the same in the code, but part of us prefer the first in
reading, part of us prefer the second.

You probably mean that C<< print ($x+2)*5; >> should mean C<< print
+($x+2)*5; >>, but removing the warning won't do that.

Just remove the warning completely.

We use to get lots of questions about print print the wrong stuff. We
don't
anymore. The warning is doing its job, and removing it won't do anyone
any
good.

It *never* warned me about what its warning is written for.

--
H.Merijn Brand http​://tux.nl Perl Monger http​://amsterdam.pm.org/
using perl5.00307 .. 5.19 porting perl5 on HP-UX, AIX, and openSUSE
http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org/
http​://qa.perl.org http​://www.goldmark.org/jeff/stupid-disclaimers/

@p5pRT
Copy link
Author

p5pRT commented Jun 30, 2014

From @Tux

On Sun, 29 Jun 2014 22​:31​:04 +0200, Ævar Arnfjörð Bjarmason
<avar@​cpan.org> wrote​:

I meant that "arguing on the basis of our own personal preference is an
inherent fallacy".

That is why I gave a counter-example for each of my reasonings

I am well aware that Abigail and I are in the minority in this specific
case, but we probably represent quite a number of other perl users
(still a minority) that also write their code like this and are not
pleased with these useless (and wrong) warning.

Keep that in mind when we *extend* the scope of a warning.

I.e. how can we find out what's useful for the greatest
number of Perl users.

Wrong! That is where perl6 might have lost quite a number of good perl
programmers, amongst them Abigail and me.

This is not that I say perl6 is not a good language. I see more and
more proof that it is or will be very useful in the (near) future, but
the fact that they stole my space is *the* (single) reason that I will
not program in perl6. Do not underestimate the artistic feeling of perl
programmers.

Can't we all agree that that's what we're ultimately aiming for?

On 29 Jun 2014 22​:26, "Ævar Arnfjörð Bjarmason via RT" <perlbug-followup@​perl.org> wrote​:

It wasn't a useful warning for you. But I think it's useful to step back
and think about what's useful to the average user of Perl. None of us are
that guy, we all have a commit bit. These warnings aren't for us. We
already know the ins and outs of Perl.

I'm not saying we should keep this particular warning or any other warning.
I'm just saying that arguing that we should or should not keep a warning is
an inherent fallacy. We are not the users of these warning, less clueful
people are. How can we make Perl more useful for them?
On 29 Jun 2014 20​:02, "H.Merijn Brand" <h.m.brand@​xs4all.nl> wrote​:

On Sun, 29 Jun 2014 13​:28​:32 -0400, Eric Brine <ikegami@​adaelis.com> wrote​:

On Sun, Jun 29, 2014 at 8​:16 AM, H.Merijn Brand <h.m.brand@​xs4all.nl> wrote​:

I agree with Abigail that this could be nominated to one of the worst
warnings ever added to perl.

In *my* perception the warning is the wrong way round.

C<< print( ($x+2)*5 ); >> should warn???

*my* preference for writing functions is to put a space between the
function name and the opening paren. Any other format is in *my*
perception ugly and not logical.

Good​: print (($x + 2) * 5);
Bad​: print( ( $x+2 )*5 );

Feel free to disagree.

That is part of the beauty of the language perl​: it allows us to
create art in the way the programmer thinks it is most logical and/or
beautiful.

$x++ if $a;
$a and $x++;

are exactly the same in the code, but part of us prefer the first in
reading, part of us prefer the second.

You probably mean that C<< print ($x+2)*5; >> should mean C<< print
+($x+2)*5; >>, but removing the warning won't do that.

Just remove the warning completely.

We use to get lots of questions about print print the wrong stuff. We don't
anymore. The warning is doing its job, and removing it won't do anyone any
good.

It *never* warned me about what its warning is written for.

--
H.Merijn Brand http​://tux.nl Perl Monger http​://amsterdam.pm.org/
using perl5.00307 .. 5.19 porting perl5 on HP-UX, AIX, and openSUSE
http​://mirrors.develooper.com/hpux/ http​://www.test-smoke.org/
http​://qa.perl.org http​://www.goldmark.org/jeff/stupid-disclaimers/

@p5pRT
Copy link
Author

p5pRT commented Jun 30, 2014

From @demerphq

On 29 June 2014 22​:26, Ævar Arnfjörð Bjarmason <avarab@​gmail.com> wrote​:

It wasn't a useful warning for you. But I think it's useful to step back
and think about what's useful to the average user of Perl. None of us are
that guy, we all have a commit bit. These warnings aren't for us. We
already know the ins and outs of Perl.

I'm not saying we should keep this particular warning or any other
warning. I'm just saying that arguing that we should or should not keep a
warning is an inherent fallacy. We are not the users of these warning, less
clueful people are. How can we make Perl more useful for them?

Personally I think this is the wrong debate.

For me the way this warning is implemented is just wrong. As implemented I
would say we are better off without it than with it.

Were it to be implemented at a different level, when the user really did
something wrong, then I would be fine with it.

It reminds me of the old broken way we used to detect special cases in
split //. Eventually we started examining the regex optree and got rid of
the stupid heuristics.

Yves

@p5pRT
Copy link
Author

p5pRT commented Aug 10, 2014

From @cpansprout

On Mon Jun 30 00​:07​:08 2014, demerphq wrote​:

On 29 June 2014 22​:26, Ævar Arnfjörð Bjarmason <avarab@​gmail.com>
wrote​:

It wasn't a useful warning for you. But I think it's useful to step
back
and think about what's useful to the average user of Perl. None of us
are
that guy, we all have a commit bit. These warnings aren't for us. We
already know the ins and outs of Perl.

I'm not saying we should keep this particular warning or any other
warning. I'm just saying that arguing that we should or should not
keep a
warning is an inherent fallacy. We are not the users of these
warning, less
clueful people are. How can we make Perl more useful for them?

Personally I think this is the wrong debate.

For me the way this warning is implemented is just wrong. As
implemented I
would say we are better off without it than with it.

Were it to be implemented at a different level, when the user really
did
something wrong, then I would be fine with it.

Like OP_PRINT and a number being both children of a binop?

I wonder​: Why don’t void warnings already catch most of these cases? Or do they?

It reminds me of the old broken way we used to detect special cases in
split //. Eventually we started examining the regex optree and got rid
of
the stupid heuristics.

Yves

Heh. This reminds me of​:

$ perl -le 'my $a; sort @​t; $a + $cmp;'
Can't use "my $a" in sort comparison at -e line 1.

:-)

--

Father Chrysostomos

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants