Re: Perl5 Language Extension: Definedness-Triggered Shortcut Operators
by moritz (Cardinal) on Mar 17, 2012 at 12:09 UTC
|
I very much like the spirit behind this proposal, though I'm not sure if : is a good choice as "defined"-modifier. It doesn't have any definedness connotation for me.
Maybe just stick with d? There's no rule that says operators need to be either word or non-word character only: A d|| B etc.
And while you're at it, you can also introduce a prefix meta operator for exists instead of defined: e|| and e&&
FWIW I don't see any problems with having multiple names for the same operator; it's a good way to deal with language change and graceful deprecation.
Update: I should add that Perl 6 has long taken the road of having meta operators, and even type prefixed operators. For example bitwise AND behaves different from strings and numbers, which is there are two operators for them: +& and ~& (the ~ generally stands for strings in Perl 6, concatenation is infix ~, and string context is prefix ~).
Meta operators are more general than that. For example the Z meta op can be applied to infix operators, making them "zip" two lists together:
my @sums = 1, 2, 3 Z+ 30, 20, 10; # 31, 22, 13;
It's a case where an operator consists of both word and non-word characters, and it's not particularly hard to read.
| [reply] [d/l] [select] |
|
|
| [reply] |
Re: Perl5 Language Extension: Definedness-Triggered Shortcut Operators
by ikegami (Patriarch) on Mar 17, 2012 at 10:06 UTC
|
You're putting the horse before the cart. Before you start worrying about the exact implementation, one needs to show the reason and purpose for the feature in the first place. You didn't provide any justification whatsoever for these changes, or mentioned any thoughts on the effects of the changes.
You even pretend that // doesn't exist. Don't you think people will have a problem with two names for the same operator? The word "teachability" has come up in discussions about new features. Having two operators with the same name would detract from teachability, for one.
The low-precedence version (to be named dor or err) was intentionally rejected (for reasons unknown to me). Do you have any new arguments that was presented then?
| [reply] [d/l] [select] |
Re: Perl5 Language Extension: Definedness-Triggered Shortcut Operators
by tobyink (Canon) on Mar 17, 2012 at 13:04 UTC
|
For defined-or we already have //.
As far as the other two go, take a look at PerlX::Perform which I believe should allow you to do defined-and and defined-dereference, albeit with more verbose syntax.
For example, imagine that $bob->spouse might return a Person object, or might return undef if Bob isn't married. Then PerlX::Perform allows:
$bobs_wifes_name = perform { $_->name } wherever $bob->spouse;
If the wherever expression evaluates to undefined, then the perform keyword returns undef (or the empty list if called in list context). If the wherever expression evaluates to a defined value (even if that value is false) then that value is assigned to $_ and the perform block is triggered.
PerlX::Perform also offers an alternative syntax which works more or less the same way. Note that the alternative syntax uses a comma, whereas the syntax above does not.
$bobs_wifes_name = wherever $bob->spouse, perform { $_->name };
So your A :&& B can be written as:
wherever A, perform {B}
And your A:->B can be written as:
wherever A, perform {$_->B}
Do give PerlX::Perform a try. Patches for improved performance, or more sugary syntax are likely to be accepted.
perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
| [reply] [d/l] [select] |
Re: Perl5 Language Extension: Definedness-Triggered Shortcut Operators
by jwkrahn (Abbot) on Mar 17, 2012 at 10:17 UTC
|
The defined-or operator, available since perl5.10, is an example of shortcut behaviour triggered on definedness: If the left hand side is defined, leave it at that, otherwise evaluate the right hand side.
The defined-or operator, available since perl5.10, is an example of shortcut behaviour triggered on definedness and truth: If the left hand side is defined and true, leave it at that, otherwise evaluate the right hand side.
| [reply] |
|
|
>perl -E '$x=undef; $y=$x // warn "RHS evaluated"; say $y'
RHS evaluated at -e line 1.
1
>perl -E '$x=""; $y=$x // warn "RHS evaluated"; say $y'
>perl -E '$x=0; $y=$x // warn "RHS evaluated"; say $y'
0
>perl -E '$x="true"; $y=$x // warn "RHS evaluated"; say $y'
true
>perl -E '$x=42; $y=$x // warn "RHS evaluated"; say $y'
42
>perl -V
Summary of my perl5 (revision 5 version 12 subversion 3) configuration
+:
Platform:
osname=linux, osvers=2.6.35.10, archname=x86_64-linux-thread-multi
uname='linux midas64 2.6.35.10 #2 smp thu jan 6 19:06:19 cst 2011
+x86_64 amd athlon(tm) ii x2 235e processor authenticamd gnulinux '
config_args='-de -Dprefix=/usr -Dvendorprefix=/usr -Dcccdlflags=-f
+PIC -Dinstallprefix=/usr -Dlibpth=/usr/local/lib64 /usr/lib64 /lib64
+-Doptimize=-O2 -fPIC -Dusethreads -Duseithreads -Dpager=/usr/bin/less
+ -isr -Dinc_version_list=5.12.2 5.12.1 5.12.0 5.10.1 5.10.0 5.8.8 5.8
+.7 5.8.6 5.8.5 5.8.4 5.8.3 5.8.2 5.8.1 5.8.0 -Darchname=x86_64-linux'
hint=recommended, useposix=true, d_sigaction=define
useithreads=define, usemultiplicity=define
useperlio=define, d_sfio=undef, uselargefiles=define, usesocks=und
+ef
use64bitint=define, use64bitall=define, uselongdouble=undef
usemymalloc=n, bincompat5005=undef
Compiler:
cc='cc', ccflags ='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing
+ -pipe -fstack-protector -I/usr/local/include -D_LARGEFILE_SOURCE -D_
+FILE_OFFSET_BITS=64',
optimize='-O2 -fPIC',
cppflags='-D_REENTRANT -D_GNU_SOURCE -fno-strict-aliasing -pipe -f
+stack-protector -I/usr/local/include'
ccversion='', gccversion='4.5.2', gccosandvers=''
intsize=4, longsize=8, ptrsize=8, doublesize=8, byteorder=12345678
d_longlong=define, longlongsize=8, d_longdbl=define, longdblsize=1
+6
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'
libpth=/usr/local/lib64 /usr/lib64 /lib64
libs=-lnsl -lgdbm -ldb -ldl -lm -lcrypt -lutil -lpthread -lc
perllibs=-lnsl -ldl -lm -lcrypt -lutil -lpthread -lc
libc=/lib64/libc-2.12.2.so, so=so, useshrplib=false, libperl=libpe
+rl.a
gnulibc_version='2.12.2'
Dynamic Linking:
dlsrc=dl_dlopen.xs, dlext=so, d_dlsymun=undef, ccdlflags='-Wl,-E'
cccdlflags='-fPIC', lddlflags='-shared -O2 -fPIC -fstack-protector
+'
Characteristics of this binary (from libperl):
Compile-time options: MULTIPLICITY PERL_DONT_CREATE_GVSV
PERL_IMPLICIT_CONTEXT PERL_MALLOC_WRAP USE_64_
+BIT_ALL
USE_64_BIT_INT USE_ITHREADS USE_LARGE_FILES
USE_PERLIO USE_PERL_ATOF USE_REENTRANT_API
Built under linux
Compiled at Jan 26 2011 12:39:46
%ENV:
PERL_UNICODE="SDL"
@INC:
/usr/lib64/perl5/site_perl/5.12.3/x86_64-linux-thread-multi
/usr/lib64/perl5/site_perl/5.12.3
/usr/lib64/perl5/vendor_perl/5.12.3/x86_64-linux-thread-multi
/usr/lib64/perl5/vendor_perl/5.12.3
/usr/lib64/perl5/5.12.3/x86_64-linux-thread-multi
/usr/lib64/perl5/5.12.3
/usr/lib64/perl5/site_perl
/usr/lib64/perl5/vendor_perl
.
This is also consistent with the documentation of Perl 5.10.0:
Although it has no direct equivalent in C, Perl's // operator is related to its C-style or. In fact, it's exactly the same as ||, except that it tests the left hand side's definedness instead of its truth. Thus, $a // $b is similar to defined($a) || $b (except that it returns the value of $a rather than the value of defined($a)) and is exactly equivalent to defined($a) ? $a : $b.
Alexander
--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
| [reply] [d/l] [select] |
|
|
perl -E 'my $x = 0 ; say $x // "true" '
0
| [reply] [d/l] |
|
|
C:\>perl -E "my $x = 0 ; say $x // 'true'; my $y = 1; say $y // 'true'
+;$x = undef; my $a=$x // warn 'RHS evaluated'; say $a;"
0
1
RHS evaluated at -e line 1.
1
updated.
| [reply] [d/l] |
|
|
Re: Perl5 Language Extension: Definedness-Triggered Shortcut Operators
by JavaFan (Canon) on Mar 17, 2012 at 21:58 UTC
|
Fellow monks, what is your opinion on (a) the concept, (b) the proposed syntax?
None of your proposals hasn't been proposed on p5p one or more times the last 12 years (although, I grant you, you proposed syntax is new to me -- but that's probably because Larry gets the colon, and you ain't no Larry).
Why don't you start by digging into the p5p archives, and refute the reasons why of all the proposals, only // survived? And while you are at it, explain why we need a :|| identical to //.
| [reply] [d/l] [select] |
|
|
Why don't you start by digging into the p5p archives, and refute the reasons why of all the proposals, only // survived? And while you are at it, explain why we need a :|| identical to //.
Twelve years worth of p5p is a lot of ground to dig through, so I have only just begun. Here is a summary of what I have found so far.
- There has indeed been debate about quite a number of operators looking at definedness.
- Objections mostly address syntactical issues. Opinions stating that it was bad to have such operators at all seem to be very rare.
- The "safe arrow" operator in particular has got a lot of support, though its symbol is not quite settled yet. One of its benefits I did not mention in my first post is that it can disable auto-vivification.
- The double-slash symbol seems to have made it because of high demand for expressions with default values and it being the syntax proposed by Larry Wall for Perl 6.
- Low-precedence defined-or was initially called "err", but its naming was later challenged. Larry himself did not like "dor" either, and he pointed out that "orelse", which is what "err" evolved into in Perl 6, has different semantics now that would not easily fit into Perl 5.
- My primary concerns, i.e. the usefulness of short-cutting expression evaluation and the intent to provide more general solutions than an isolated exotic operator, don't seem to have played a major role in the discussion lately.
- Colons indeed seem to be some sort of holy ground nobody dares to touch.
- Points made in favour of a new syntax are often among these: (a) Has the new syntax been illegal before, so that old code is not likely to get hurt? (b) Do similar things look similar and dissimilar things look different? (c) Is the new syntax easy to use and remember? (d) Does it fit in the general look-and-feel of the language? (e) Are names free of different meanings or possible misunderstandings? (f) Is the impact on the existing language parser(s) limited?
As to the coexistence of different symbols, I have already tried to convey that one of them should be preferred but the other one cannot suddenly be made illegal. This has precedents, like tr versus y, or version objects versus v-strings.
| [reply] |
|
|
Opinions stating that it was bad to have such operators at all seem to be very rare.
There's always the fact that "adding features means more complexity of the implemenation, and hence more work on maintenance". Since this is an opinion carried forward by the handful of people that actually do significant maintenance work, this opinion carries a lot of weight.
The "safe arrow" operator in particular has got a lot of support, though its symbol is not quite settled yet.
But it wasn't hung just on syntax. And noone cared enough to restart the discussion. Which, to me, seems it's not an itch that bothers a lot of people.
The double-slash symbol seems to have made it because of high demand for expressions with default values and it being the syntax proposed by Larry Wall for Perl 6.
Right. So.... what's your argument to have an :|| as well?
Low-precedence defined-or was initially called "err", but its naming was later challenged. Larry himself did not like "dor" either, and he pointed out that "orelse", which is what "err" evolved into in Perl 6, has different semantics now that would not easily fit into Perl 5.
5.9.x had err for sometime (as the low priority version of //). It was decided it was better not to have it. What makes you think the time is right now, and what are your arguments that the concerns of a few years ago aren't concerns anymore?
My primary concerns, i.e. the usefulness of short-cutting expression evaluation and the intent to provide more general solutions than an isolated exotic operator, don't seem to have played a major role in the discussion lately.
I don't think there's much disagreement that having more features in the language has a value. But unless said value exceeds the costs it's not going to happen. And even if the value exceeds the costs, someone has to do the work first. Perlmonks is wrong forum to discuss this. Of course, 99.9% of the people here will say "Good idea. When can I have it"? Go pitch your idea on p5p.
Has the new syntax been illegal before, so that old code is not likely to get hurt?
That rules out any named operator like err, dor or dand -- unless you make them weak keywords or enable them using features.
| [reply] [d/l] [select] |
|
|
Re: Perl5 Language Extension: Definedness-Triggered Shortcut Operators
by martin (Friar) on Mar 18, 2012 at 11:57 UTC
|
A &&& B # defined-and
A ||| B # defined-or
A >>> B # safe arrow
This would be a systematic approach reminiscent of the role of undef in ternary logic -- triple sign, third kind of truth value involved.
I am not sure whether a whole lot of other similar symbols like ^^^ would make as much sense, though, which means we then had to explain why only those mentioned above were there.
| [reply] [d/l] |
|
|
A &&& B # defined-and
You're not the first. Here's the reason why it's a bad idea:
$ perl -ce 'A &&& B'
-e syntax OK
It's not worth breaking backwards compatability for this. | [reply] [d/l] [select] |
|
|
| [reply] |
|
|
Re: Perl5 Language Extension: Definedness-Triggered Shortcut Operators
by Anonymous Monk on Mar 17, 2012 at 13:30 UTC
|
You really can't change it now... it's already here once, and doesn't need to be here twice. Let a programming language get defined by a committee, and whaddaya get? Java, COBOL, or Ada. Pick your poison. | [reply] |