Skip Menu |
Report information
Id: 132607
Status: open
Priority: 0/
Queue: perl5

Owner: Nobody
Requestors: zefram [at] fysh.org
Cc:
AdminCc:

Operating System: (no value)
PatchStatus: (no value)
Severity: Wishlist
Type: core
Perl Version: 5.27.6
Fixed In: (no value)



CC: zefram [...] fysh.org
To: perlbug [...] perl.org
Date: Tue, 19 Dec 2017 06:38:07 +0000
Subject: chained comparison
From: zefram [...] fysh.org
Download (untitled) / with headers
text/plain 4.2k
This is a bug report for perl from zefram@fysh.org, generated with the help of perlbug 1.41 running under perl 5.27.6. ----------------------------------------------------------------- [Please describe your issue here] It would be nice for Perl to understand chained comparisons such as "$a le $b lt $c", which would mean "$a le $b && $b lt $c" but with only a single evaluation of the middle comparand. The comparison operators are currently non-associative, so most of what ought to be chained comparisons are currently syntax errors. Introducing chained comparisons would not change the meaning of any currently-legal expression. One wrinkle: we currently have two levels of precedence for comparison operators, one for "lt" et al, and a looser one for "eq" et al. So "$a lt $b eq $c" is currently legal. This is imitating the C precedence levels, I think mainly so that "!=" can be used to mean "xor". It's already a bit of a gotcha, and we'd have to warn that things like that don't make chained comparisons. [Please do not change anything below this line] ----------------------------------------------------------------- --- Flags: category=core severity=wishlist --- Site configuration information for perl 5.27.6: Configured by zefram at Tue Nov 21 05:42:59 GMT 2017. Summary of my perl5 (revision 5 version 27 subversion 6) configuration: Platform: osname=linux osvers=3.16.0-4-amd64 archname=x86_64-linux-thread-multi uname='linux barba.rous.org 3.16.0-4-amd64 #1 smp debian 3.16.43-2+deb8u2 (2017-06-26) x86_64 gnulinux ' config_args='-des -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52 -Duselargefiles -Dusethreads -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dusedevel -Uversiononly -Ui_db' hint=recommended useposix=true d_sigaction=define useithreads=define usemultiplicity=define use64bitint=define use64bitall=define uselongdouble=undef usemymalloc=n default_inc_excludes_dot=define bincompat5005=undef Compiler: cc='cc' ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2' optimize='-O2' cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include' ccversion='' gccversion='4.9.2' gccosandvers='' intsize=4 longsize=8 ptrsize=8 doublesize=8 byteorder=12345678 doublekind=3 d_longlong=define longlongsize=8 d_longdbl=define longdblsize=16 longdblkind=3 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-strong -L/usr/local/lib' libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed /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=-lpthread -lnsl -ldb -ldl -lm -lcrypt -lutil -lc perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc libc=libc-2.19.so so=so useshrplib=true libperl=libperl.so gnulibc_version='2.19' Dynamic Linking: dlsrc=dl_dlopen.xs dlext=so d_dlsymun=undef ccdlflags='-Wl,-E -Wl,-rpath,/home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/5.27.6/x86_64-linux-thread-multi/CORE' cccdlflags='-fPIC' lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong' --- @INC for perl 5.27.6: /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/site_perl/5.27.6/x86_64-linux-thread-multi /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/site_perl/5.27.6 /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/5.27.6/x86_64-linux-thread-multi /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/5.27.6 --- Environment for perl 5.27.6: HOME=/home/zefram LANG (unset) LANGUAGE (unset) LD_LIBRARY_PATH (unset) LOGDIR (unset) PATH=/home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/bin:/home/zefram/usr/perl/util:/home/zefram/pub/x86_64-unknown-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/bin:/usr/local/bin:/usr/games PERL_BADLANG (unset) SHELL=/usr/bin/zsh
Subject: Re: [perl #132607] chained comparison
To: Perl5 Porteros <perl5-porters [...] perl.org>
Date: Tue, 19 Dec 2017 09:10:57 +0100
From: demerphq <demerphq [...] gmail.com>
Download (untitled) / with headers
text/plain 4.8k
I so look forward to this, both as a patch i can learn from and as a feature I would enjoy. ++Zefram.

Yves

On 19 Dec 2017 7:38 am, "Zefram" <perlbug-followup@perl.org> wrote:
Show quoted text
# New Ticket Created by  Zefram
# Please include the string:  [perl #132607]
# in the subject line of all future correspondence about this issue.
# <URL: https://rt.perl.org/Ticket/Display.html?id=132607 >



This is a bug report for perl from zefram@fysh.org,
generated with the help of perlbug 1.41 running under perl 5.27.6.


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

It would be nice for Perl to understand chained comparisons such as "$a
le $b lt $c", which would mean "$a le $b && $b lt $c" but with only a
single evaluation of the middle comparand.  The comparison operators are
currently non-associative, so most of what ought to be chained comparisons
are currently syntax errors.  Introducing chained comparisons would not
change the meaning of any currently-legal expression.

One wrinkle: we currently have two levels of precedence for comparison
operators, one for "lt" et al, and a looser one for "eq" et al.  So "$a lt
$b eq $c" is currently legal.  This is imitating the C precedence levels,
I think mainly so that "!=" can be used to mean "xor".  It's already a
bit of a gotcha, and we'd have to warn that things like that don't make
chained comparisons.

[Please do not change anything below this line]
-----------------------------------------------------------------
---
Flags:
    category=core
    severity=wishlist
---
Site configuration information for perl 5.27.6:

Configured by zefram at Tue Nov 21 05:42:59 GMT 2017.

Summary of my perl5 (revision 5 version 27 subversion 6) configuration:

  Platform:
    osname=linux
    osvers=3.16.0-4-amd64
    archname=x86_64-linux-thread-multi
    uname='linux barba.rous.org 3.16.0-4-amd64 #1 smp debian 3.16.43-2+deb8u2 (2017-06-26) x86_64 gnulinux '
    config_args='-des -Dprefix=/home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52 -Duselargefiles -Dusethreads -Uafs -Ud_csh -Uusesfio -Uusenm -Duseshrplib -Dusedevel -Uversiononly -Ui_db'
    hint=recommended
    useposix=true
    d_sigaction=define
    useithreads=define
    usemultiplicity=define
    use64bitint=define
    use64bitall=define
    uselongdouble=undef
    usemymalloc=n
    default_inc_excludes_dot=define
    bincompat5005=undef
  Compiler:
    cc='cc'
    ccflags ='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_FORTIFY_SOURCE=2'
    optimize='-O2'
    cppflags='-D_REENTRANT -D_GNU_SOURCE -fwrapv -fno-strict-aliasing -pipe -fstack-protector-strong -I/usr/local/include'
    ccversion=''
    gccversion='4.9.2'
    gccosandvers=''
    intsize=4
    longsize=8
    ptrsize=8
    doublesize=8
    byteorder=12345678
    doublekind=3
    d_longlong=define
    longlongsize=8
    d_longdbl=define
    longdblsize=16
    longdblkind=3
    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-strong -L/usr/local/lib'
    libpth=/usr/local/lib /usr/lib/gcc/x86_64-linux-gnu/4.9/include-fixed /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=-lpthread -lnsl -ldb -ldl -lm -lcrypt -lutil -lc
    perllibs=-lpthread -lnsl -ldl -lm -lcrypt -lutil -lc
    libc=libc-2.19.so
    so=so
    useshrplib=true
    libperl=libperl.so
    gnulibc_version='2.19'
  Dynamic Linking:
    dlsrc=dl_dlopen.xs
    dlext=so
    d_dlsymun=undef
    ccdlflags='-Wl,-E -Wl,-rpath,/home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/5.27.6/x86_64-linux-thread-multi/CORE'
    cccdlflags='-fPIC'
    lddlflags='-shared -O2 -L/usr/local/lib -fstack-protector-strong'


---
@INC for perl 5.27.6:
    /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/site_perl/5.27.6/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/site_perl/5.27.6
    /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/5.27.6/x86_64-linux-thread-multi
    /home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/lib/5.27.6

---
Environment for perl 5.27.6:
    HOME=/home/zefram
    LANG (unset)
    LANGUAGE (unset)
    LD_LIBRARY_PATH (unset)
    LOGDIR (unset)
    PATH=/home/zefram/usr/perl/perl_install/perl-5.27.6-i64-f52/bin:/home/zefram/usr/perl/util:/home/zefram/pub/x86_64-unknown-linux-gnu/bin:/home/zefram/pub/common/bin:/usr/bin:/bin:/usr/local/bin:/usr/games
    PERL_BADLANG (unset)
    SHELL=/usr/bin/zsh

Subject: Re: [perl #132607] chained comparison
From: "Paul \"LeoNerd\" Evans" <leonerd [...] leonerd.org.uk>
Date: Wed, 20 Dec 2017 16:39:15 +0000
To: perl5-porters [...] perl.org
Download (untitled) / with headers
text/plain 465b
On Tue, 19 Dec 2017 09:10:57 +0100 demerphq <demerphq@gmail.com> wrote: Show quoted text
> I so look forward to this, both as a patch i can learn from and as a > feature I would enjoy. ++Zefram.
+1 I'd be happy to accept some new warnings, in exchange for being able to e.g.: grep { $min <= $_ <= $max } @numbers -- Paul "LeoNerd" Evans leonerd@leonerd.org.uk | https://metacpan.org/author/PEVANS http://www.leonerd.org.uk/ | https://www.tindie.com/stores/leonerd/
Download (untitled)
application/pgp-signature 195b

Message body not shown because it is not plain text.

From: David Nicol <davidnicol [...] gmail.com>
Subject: Re: [perl #132607] chained comparison
Date: Wed, 20 Dec 2017 13:49:46 -0600
CC: Perl 5 Porters <perl5-porters [...] perl.org>
Download (untitled) / with headers
text/plain 1.5k
how would this be done without looking ahead more than one parse-time element?

Perhaps a "Comparison Expression" type would be introduced to the grammar.  Except the fact of the current syntax error implies there is already a place the new thing could go.

Expressions in the middle should only get evaluated once, and later ones should short-circuit out:

        $min <= &lookup1 < &lookup2 <= $max 

should be equivalent to

        do {  my $tmp1 = &lookup1;  $min <= $tmp1 and do {  my $tmp2 = &lookup2; $tmp1 < $tmp2 and $tmp2 <= $max  }   }

rather than the double-calling

        ( $min <= &lookup1 and &lookup1 < &lookup2 and  &lookup2 <= $max )

for any expression &lookupN more complicated than an unblessed scalar.


I think I'm willing to write a test case for this if it would help.



On Wed, Dec 20, 2017 at 10:39 AM, Paul "LeoNerd" Evans <leonerd@leonerd.org.uk> wrote:
Show quoted text
On Tue, 19 Dec 2017 09:10:57 +0100
demerphq <demerphq@gmail.com> wrote:

> I so look forward to this, both as a patch i can learn from and as a
> feature I would enjoy. ++Zefram.

+1

I'd be happy to accept some new warnings, in exchange for being able to
e.g.:

  grep { $min <= $_ <= $max } @numbers

--
Paul "LeoNerd" Evans

leonerd@leonerd.org.uk      |  https://metacpan.org/author/PEVANS

http://www.leonerd.org.uk/  |  https://www.tindie.com/stores/leonerd/



--
“no man should be compelled to do what the laws do not require; nor to refrain from acts which the laws permit.” Calder v. Bull (U.S. 1798)


This service is sponsored and maintained by Best Practical Solutions and runs on Perl.org infrastructure.

For issues related to this RT instance (aka "perlbug"), please contact perlbug-admin at perl.org