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

chained comparison #16317

Closed
p5pRT opened this issue Dec 19, 2017 · 6 comments
Closed

chained comparison #16317

p5pRT opened this issue Dec 19, 2017 · 6 comments

Comments

@p5pRT
Copy link

p5pRT commented Dec 19, 2017

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

Searchable as RT132607$

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2017

From zefram@fysh.org

Created by zefram@fysh.org

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.

Perl Info

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

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2017

From @demerphq

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​:

# 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-archive.perl.org/perl5/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

@p5pRT
Copy link
Author

p5pRT commented Dec 19, 2017

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

@p5pRT
Copy link
Author

p5pRT commented Dec 20, 2017

From @leonerd

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/

@p5pRT
Copy link
Author

p5pRT commented Dec 20, 2017

From @davidnicol

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​:

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)

@xenu
Copy link
Member

xenu commented Aug 15, 2020

This feature was implemented in perl 5.32, see 02b85d3 and the corresponding perldelta entry.

@xenu xenu closed this as completed Aug 15, 2020
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