Re: shift doesn't DWIM
by davido (Cardinal) on Jul 12, 2005 at 05:37 UTC
|
Where would the line be drawn? Would using map in "void context" spew its return value into @_ ?
DWIMery shouldn't venture into the "Do What I Wish" if doing so creates serious language inconsistancies, IMHO.
My memory may be incomplete or in need of refreshing, but I can't think of any subs that populate $_ as a default lvalue. Yes, there is the diamond operator in the special case of a while() loop, there is foreach(), the m// and s/// operators, and there are subs that utilize $_ as a default parameter. But there aren't any subs I can think of that populate $_ as though it were an lvalue.
| [reply] [d/l] |
|
|
Yes, and Perl 6 even the special while loop exception is going away. Instead
you typically use topicalizers to set $_:
given shift {
do something with $_;
}
or
for @ARGS {
do something with $_;
}
And in particular, while on a filehandle turns into a (lazy) for:
for =$fh {
do something with $_;
}
In general, the only dwimming on void context in the standard Perl 6 dialect will be deciding whether to turn an unthrown exception (aka undef) into a thrown exception because someone forgot to check the return value. | [reply] [d/l] [select] |
|
|
| [reply] [d/l] [select] |
|
|
My memory may be incomplete or in need of refreshing, but I can't think of any subs that populate $_ as a default lvalue. Yes, there is the diamond operator in the special case of a while() loop, there is foreach(), the m// and s/// operators, and there are subs that utilize $_ as a default parameter. But there aren't any subs I can think of that populate $_ as though it were an lvalue.
Interesting question. I'm also having a hard time thinking of such functions...
map and grep assign to an implicitly localized $_ (as does foreach if no loop variable is given), but not their results.
The function readline clobbers $_ if it is in the test clause of a while loop:
% date|perl -le '$_="x";while(readline *STDIN){printf uc};print"<$_>"'
TUE JUL 12 01:56:04 EDT 2005
<>
It wouldn't surprise me if there are more examples, but I can't think of any ATM.
| [reply] [d/l] |
Re: shift doesn't DWIM
by anonymized user 468275 (Curate) on Jul 12, 2005 at 07:00 UTC
|
I would say it's because of three things:
1) $_ is often treated as a default argument to a function, for example for chop and as a default second argument for split. This in no way implies it should be a default LHS to an omitted assignment, just because shift takes an array argument rather than a scalar.
2) shift does have a default argument, @_, because it takes an array argument rather than a scalar.
3) using $_ as a default argument is a reasonably safe implementation, because it is applied only when the relevant argument is explicitly omitted from an actual function call; in other words is free from ambiguous meaning (including in a DWIM sense). But the intended meaning for an omitted assignment to a function call is that its return value is available for direct evaluation (e.g. MyFunc(shift())), which may be delayed to the next statement for some cases, but either way is never assigned to $_. So the precedent is in fact never to do what is suggested in the OP. 3) (conclusion) the proposed implementation is unsafe because $_ is intended to preserve its contents across scope and context boundaries, unless explicity assigned otherwise (omission of required arguments being deemed explicit enough), including for functions. The implementation proposed in the OP would therefore destroy the main purpose of $_.
| [reply] |
Re: shift doesn't DWIM
by tlm (Prior) on Jul 12, 2005 at 09:45 UTC
|
There are enough times when one just wants to get rid of the first element in an array, via:
shift @array;
It would be a nuisance to have to create a spitoon-like variable just to catch the shift'ed element (thereby preserving $_). And it would be easy to forget to do this, leading to many chomped butts.
| [reply] [d/l] |
|
|
I agree entirely. From a Huffman-encoding viewpoint, I'd say doing shift @a to discard the first element of the array and doing $_ = shift @a to put that discarded element in $_ is a far better allocation of characters than () = shift @a for discarding and shift @a for storing in $_. Not to mention those empty LHS parens look odd to some folks.
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
| [reply] [d/l] |
Re: shift doesn't DWIM
by GrandFather (Saint) on Jul 12, 2005 at 20:31 UTC
|
Thank you all. The original post was a bit low grade, but there has been some rather enlightening discussion.
Knowing a reason for a design decision often helps me remember how things hang together.
Perl is Huffman encoded by design.
| [reply] |