my SLICE = VALUE;
to work, e.g.
my @hash{@_} = ();
to create a "set" of the sub arguments. In other words
my @hash{@_} = ();
would be identical to
my %hash; @hash{@_} = ();
Are there good reasons why this would/could/should not work?
This feature would be more likely to be useful for hash slices
than for array slices, at least based on my limited imagination.
The syntax
my SLICE;
would be kind of pointless.
--
Jarkko Hietaniemi <j...@iki.fi> http://www.iki.fi/jhi/ "There is this special
biologist word we use for 'stable'. It is 'dead'." -- Jack Cohen
No.
The patch below allows my(HASHSLICE) (with parens). Allowing the
non-parenthesized form necessitates a change to perly.y. I can
investigate it when I'm convinced it's a good idea :-)
So the script
#!perl
use strict;
my ( @h{qw/aa bb/} ) = 11;
print "$_ => $h{$_}\n" for keys %h;
__END__
outputs :
aa => 11
bb =>
(hash key order is random, of course)
> This feature would be more likely to be useful for hash slices
> than for array slices, at least based on my limited imagination.
Yes. But why forbid it if my'ed hash slices are OK ?
> The syntax
>
> my SLICE;
>
> would be kind of pointless.
equivalent to my SLICE = ().
Index: op.c
===================================================================
--- op.c (revision 1615)
+++ op.c (working copy)
@@ -1608,6 +1608,7 @@
else if (type != OP_PADSV &&
type != OP_PADAV &&
type != OP_PADHV &&
+ type != OP_HSLICE &&
type != OP_PUSHMARK)
{
yyerror(Perl_form(aTHX_ "Can't declare %s in \"%s\"",
End.
I think a better question is -- why *should* it work?
my(@HASH{A,B,C}) = ();
=
my($HASH{A}, $HASH{B}, $HASH{C}) = ();
Which, to my expectations, should not work. The arguments to my() are
variables that need to be made allocated with lexical scope. A slice
doesn't refer to the hash, therefore it should not have the definition
you are trying to ascribe to it.
Cheers,
mark
--
ma...@mielke.cc/ma...@ncf.ca/ma...@nortelnetworks.com __________________________
. . _ ._ . . .__ . . ._. .__ . . . .__ | Neighbourhood Coder
|\/| |_| |_| |/ |_ |\/| | |_ | |/ |_ |
| | | | | \ | \ |__ . | | .|. |__ |__ | \ |__ | Ottawa, Ontario, Canada
One ring to rule them all, one ring to find them, one ring to bring them all
and in the darkness bind them...
Ive wanted the same thing a few times. Seems like a good idea to me.
Yves
> On Thu, Jun 26, 2003 at 01:49:20PM +0200, Rafael Garcia-Suarez wrote:
> > Jarkko Hietaniemi wrote:
> > > Are there good reasons why this would/could/should not work?
> > No.
> > The patch below allows my(HASHSLICE) (with parens). Allowing the
> > non-parenthesized form necessitates a change to perly.y. I can
> > investigate it when I'm convinced it's a good idea :-)
>
> I think a better question is -- why *should* it work?
>
> my(@HASH{A,B,C}) = ();
> =
> my($HASH{A}, $HASH{B}, $HASH{C}) = ();
>
> Which, to my expectations, should not work. The arguments to my() are
> variables that need to be made allocated with lexical scope. A slice
> doesn't refer to the hash, therefore it should not have the definition
> you are trying to ascribe to it.
Oh, please, not the consistency argument here! First of all, convenience
should have higher priority (Perl programmers are amongst the laziest
people in the world) and secondly, I don't even think it counts here. I
have more than once tried to declare a hash-slice that way by accident
and was always slightly disappointed that it doesn't work. If that was
added to Perl it would go along with many other syntactic shortcuts that
Perl has to offer. Remember, you can't find an explanation why these are
all equivalent either:
while (<HANDLE>) {
while ($_ = <HANDLE>) {
while (defined($_ = <HANDLE>)) {
They just are because everyone likes shortcuts.
Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
Why pointless?
my @hash{qw(a b c)}
would set C<exists $hash{a}> !?
Robin
-------------------------------------------------------------------
This e-mail and any attachments may contain confidential and/or
privileged material; it is for the intended addressee(s) only.
If you are not a named addressee, you must not use, retain or
disclose such information.
NPL Management Ltd cannot guarantee that the e-mail or any
attachments are free from viruses.
NPL Management Ltd. Registered in England and Wales. No: 2937881
Registered Office: Teddington, Middlesex, United Kingdom TW11 0LW.
-------------------------------------------------------------------
I've wanted that too.
But that makes this legal:
my(@h{k}) = v;
when this is not:
my($h{k}) = v;
and, according to Rafael's patch, this isn't either:
my(@a[n]) = v;
which seems at least as peculiar, and maybe more so.
I wonder if this needs a little more thought?
*yuck*
my() defines lexicals. Abuse it all you want to create lexical hash entry
overrides or something like that. Please, please, please don't make it mean
something nothing to do with lexicals....
Perl has evolved with the expectations of the people - of this, there is
no doubt. However, the evolution of Perl has been controlled. Certain invalid
decisions have made their way into Perl in the form of patches, but several
of these features have also made their way *out* of Perl as a result of
people concluding that the idea was not very good in the first place.
Is the above a good idea? I don't think so. Is it intuitive? Well,
just like every suggestion ever made here, sure, to a few people (or
so they say). Is it intuitive to most? Is it intuitive in general? I
doubt it. As you have admitted above, the syntax is inconsistent with
Perl, therefore, except for the few that thrive on Perl's more arcane
inconsistencies, people will *not* find the behaviour intuitive.
> I
> have more than once tried to declare a hash-slice that way by accident
> and was always slightly disappointed that it doesn't work.
This, in and of itself, is not a reason to add it. Read comp.lang.perl.misc
for a quick reference to many invalid expectations.
> If that was
> added to Perl it would go along with many other syntactic shortcuts that
> Perl has to offer. Remember, you can't find an explanation why these are
> all equivalent either:
> ...
> while (<HANDLE>) {
> while ($_ = <HANDLE>) {
> while (defined($_ = <HANDLE>)) {
> ...
> They just are because everyone likes shortcuts.
Not only this -- everybody likes unambiguous shortcuts. Since it is
*extremely* rare that anybody would actually want to a read a file
until they received the record "0" (no newline terminator), and since
$_ is well known to be the default variable, the above makes *perfect*
sense. Your above example does not prove that 'my SLICE = VALUE'
should be taken seriously.
metoo for all
my @hash{qw( sec min hour mday mon year wday yday isdst )} = localtime;
my @hash{qw( key1 key2 key3 )} = (0) x 3;
my @hash{qw( only these keys )} = map { "_$_" } qw( 1 2 3 );
my @set = grep m/expr/ => @list;
my @hash{@set} = (1) x @set;
# OK, that is easier to write as
my %hash = map { $_ => 1 } grep m/expr/ => @list;
> to create a "set" of the sub arguments. In other words
>
> my @hash{@_} = ();
>
> would be identical to
>
> my %hash; @hash{@_} = ();
>
> Are there good reasons why this would/could/should not work?
Probably many, but since it is a syntax error now, we can assign this very
DWIM functionality.
> This feature would be more likely to be useful for hash slices
> than for array slices, at least based on my limited imagination.
Yep.
> The syntax
>
> my SLICE;
>
> would be kind of pointless.
unless you can find usefull use of the exists example of Robin.
--
H.Merijn Brand Amsterdam Perl Mongers (http://amsterdam.pm.org/)
using perl-5.6.1, 5.8.0 & 633 on HP-UX 10.20 & 11.00, AIX 4.2, AIX 4.3,
WinNT 4, Win2K pro & WinCE 2.11. Smoking perl CORE: smo...@perl.org
http://archives.develooper.com/daily...@perl.org/ per...@perl.org
send smoke reports to: smokers...@perl.org, QA: http://qa.perl.org
Other suggestion : make it equivalent to
my %hash;
Hash::Util::lock_keys(%hash,@_); # or the internal equivalent
@hash{@_} = (values...);
I begin to feel more comfortable with something like the above... at least
now it saves more than a couple of characters for perhaps a commonly used
(or commonly should be used?) set of operations. (Keep going, Rafael...)
It really should work for the non-parenthized version too I think. The need
of parenthesis should only come purely from knowing the precedence rules
(ok, so here you could say it's () at the left of = so it's one of
the few list-context giving ()'s in perl. But the @ already says that, and
it doesn't HAVE to have an assignment too)
Yes, my opinion is that, if "my SLICE" is to be added to Perl, then
it should work without parens. But I'm just not going to regenerate
perly.c for a one-line proof-of-concept patch.
Now for the usual question : is there something in the Apocalypses about
my and slices ?
Once we allow more complex my delcarations, people are going to expect
(rightly or wrongly) for it to be analogous to local() in what you can
declare.
Should we allow aribrary expressions like
my $h{k1}[k2]{k3} = ...
for example, and if not, are we clear where we are drawing the line?
--
In my day, we used to edit the inodes by hand. With magnets.
That's not a slice, that's a hash element lookup.
Possibilities so far:
- don't change anything
- allow only hash slices, restrict the hash (my favourite)
(so I'd draw the line here ----->8--)
- allow only hash slices
- allow array and hash slices
- allow array and hash slices, and hash and array elements
Other point to be considered : allowing new my() syntax implies
equivalent our() syntax, unless specified otherwise. Currently
I'm assuming that our(SLICE) will also be allowed, if my(SLICE) is.
my line would be here -->8--- (no restricted hashes)
> - allow array and hash slices
> - allow array and hash slices, and hash and array elements
--
I fail to see whty this behaviour should be restricted to my. Why shouldnt
it work equally as well with our?
AFAICT this is just a matter of offering an alternative way of initializing
a hash or array.
my @foo[1,2,3]=(1,2,3);
should be the same as
my @foo=(undef,1,2,3);
and
my @foo{qw(x y z)}=(qw(x y z));
should be the same as
my %foo=(x=>x=>y=>y=>z=>'z');
So I dont see the cause of the fuss.
yves
As MJD pointed out recently intuitiveness is a poor yardstick by which to
judge technical issues.
And personally I agree with those that say that consistancy is a convenience
that can be done away with when more pressing matters are at hand. Like DWIM
and lazyness.
>
> > I
> > have more than once tried to declare a hash-slice that way
> by accident
> > and was always slightly disappointed that it doesn't work.
>
> This, in and of itself, is not a reason to add it. Read
> comp.lang.perl.misc
> for a quick reference to many invalid expectations.
Surely there is a difference between invalid expectations that cannot be
reasonably implemented (and most likely could not be implemented by the
person discussing them) versus ones proposed by a Pumpking that apparently
can be implemented?
yves
I quite like this.
>>
>> to create a "set" of the sub arguments. In other words
>>
>> my @hash{@_} = ();
>>
>> would be identical to
>>
>> my %hash; @hash{@_} = ();
>
>Other suggestion : make it equivalent to
>
> my %hash;
> Hash::Util::lock_keys(%hash,@_); # or the internal equivalent
> @hash{@_} = (values...);
And I like that even more - this gives a sense of "declaring" the
valid keys.
However my pragmatic enthusiasm should be tempered by possible confusion
and whether this is in sprit of perl6?
--
Nick Ing-Simmons
http://www.ni-s.u-net.com/
We're definitely killing Perl 5's slice syntax, at least as far as
relying on the initial character to determine the context of the
subscript. There are many ways we could reintroduce a slicing syntax,
some of which are mentioned in this RFC, but we'll defer the decision on
that till Apocalypse 9 on Data Structures, since the interesting parts
of designing slice syntax will be driven by the need to slice
multidimensional arrays.
-- http://dev.perl.org/perl6/apocalypse/2
But my point is that joe public may not see what the distinction is.
From joe's viewpoint, if you can do some funny things with my's, why can't
you do anything you like with them?
--
Nothing ventured, nothing lost.
But there's a technical problem with it :
$ perl -MO=Concise -we 'my@k;my(@h{@k})'
"my" variable @k masks earlier declaration in same scope at -e line 1.
Can't declare hash slice in "my" at -e line 1, at EOF
-e had compilation errors.
9 <@> leave[@k:1,3] KP/REFC ->(end)
1 <0> enter ->2
2 <;> nextstate(main 1 -e:1) ->3
3 <0> padav[@k:1,3] M/LVINTRO ->4
4 <;> nextstate(main 2 -e:1) ->5
8 <@> hslice lKP ->9
5 <0> pushmark s ->6
6 <0> padav[@k:2,3] l ->7
7 <0> padhv[%h:2,3] sR ->8
As you see, the second @k, since it's in a my(), _is_ a declaration of a
new lexical, that masks the first @k. That's probably not What Was Meant.
That means that some more hackery is needed for this syntax to work.
Isn't that solved by the restriction of allowing lexical hash slices *only*
without parens?
valid:
my @time{qw( sec min hour mday mon year wday yday isdst )} = localtime;
invalid:
my ($x, @hash{qw( bar foo )}) = (1, 2, 3);
Ha, that depends how that would be implemented, of course !
Offhand I don't see any reason why
my @h{@k} = (1, 2);
should be legal, and
my ($x,@h{@k}) = (0, 1, 2);
shouldn't be. That's should be feasible, by unsetting PL_in_my at
the appropriate places.
Beyond the various points for and against raised by others, I have
one other concern: once this is allowed there is a danger of the
reversed expectation that local() should work analagously, ie that:
local @hash{@_} = ();
should be identical to:
local %hash; @hash{@_} = ();
.. and such an expectation could lead to confusion and subtle bugs.
Taking into account this and the other pitfalls pointed out so far,
I'm inclined to suggest that the minor saving this change would
permit isn't worth the cost.
Hugo
local() is, syntactically, quite a different beast than my().
On the other hand, our() is quite similar to my(), and is currently
parsed identically.
I feel that bad expectations about
our @hash{@_} = (values...)
are likely to lead to confusion as well.
At the parse level. But conceptually "our" is very different from "my".
"our" makes a lexically scoped alias for a global available, "my" creates
a new variable. I think it's perfectly ok for this proposed new syntax to
work for "my" and not for "our"
You had parens, I had not.
--
Jarkko Hietaniemi <j...@iki.fi> http://www.iki.fi/jhi/ "There is this special
biologist word we use for 'stable'. It is 'dead'." -- Jack Cohen
Hmmm. I don't see the need to lock the keys. If I create a "set",
that doesn't mean I wouldn't maybe want to modify it later in the
sub or scope.
> @hash{@_} = (values...);
I would expect
my @hash{1,2,3} = qw/a b c/;
to set up some immediate-enclosing-scope-only members
within the preexisting %hash. Just like C<local> does,
according to the local section in perlsub. (why isn't there
a perlscope perldoc to move all the scoping considerations from
perlsub to? never mind.) The C<my> hash elements would
not be visible in called subroutines that know about %hash.
Since C<my>, in my mental concept of it at least, works by mapping
names to offsets into an array, at compile time, what exactly
Jarkko's proposed syntax should do (to make sense to me) could
possibly be, hmm, think, think, =ping!=, what if
my SLICE
creates a lexically scoped fixed-key hash, so all use of %hash after
that line in the current scope get translated (at compile time!) to
offsets into the array, which I believe is called "the lexical pad.".
I think that the syntax (not the semantics) of all scope modifiers
should be identical. I am not sure if it is now or not. The subset of
it that I use is.
I think that a syntax for declaring a C<my> hash in the same
expression where you use it -- which I agree would be
a cool thing, since hash use is one of the places where you can't
throw a C<my> in front of some valid global expression and instantly
lexicalize it -- would be to hang the parsing complexities and put the
C<my> between the sigill and the variable name, giving us
@{my hash}{1,2,3} = qw/a b c/;
or possibly even
@my hash{1,2,3} = qw/a b c/;
which implies extending C<my> to work btn the sigill and
the name instead of before the sigill in all the other cases.
That is a syntax which would give something that would mean to
me what JHI appeared to be wishing for in the original my NAME = VALUE
list post. Which as I said above looks to me like it should create
a lexically scoped fixed-key hash which can be resolved at compile time.
And the other scope modifiers too:
# localize three elements of %hash
local @hash{1,2,3} = qw/a b c/;
# localize %hash and fill a slice of it
@local hash{1,2,3} = qw/a b c/;
--
David Nicol, independent consultant, contractor, and food service worker
> What a curious discussion.
>
> I would expect
>
> my @hash{1,2,3} = qw/a b c/;
>
> to set up some immediate-enclosing-scope-only members
> within the preexisting %hash. Just like C<local> does,
> according to the local section in perlsub. (why isn't there
> a perlscope perldoc to move all the scoping considerations from
> perlsub to? never mind.) The C<my> hash elements would
> not be visible in called subroutines that know about %hash.
I think allowing parts of a data-structure to be lexically scoped while
the rest isn't can turn any program into a mess. Also, I can't remember
ever having missed such a feature in Perl.
I wouldn't go for restricted hashes either. What I'd like to see is
something quite plain. Whenver you have
my @hash{ qw/a b c/ } = LIST;
it should be equivalent to the more wordy
my %hash;
@hash{ qw/a b c/ } = LIST;
If LIST is not given, () should be assumed which essentially sets each
element to undef. The advantage of that is that it is a) pretty easy to
understand and b) can be applied literally to local() and our() (just by
replacing 'my' in the above with these two respective keywords). The
semantics of my(), our() and local() would remain the same.
The above could also be used for non-slices:
my $hash{ key } = "value";
in the very same way:
my %hash;
$hash{ key } = "value";
It stays orthogonal for arrays and references, too:
my @{$ref}{ qw/a b c/ } = (1, 2, 3);
would declare a lexical variable $ref that gets initialized as a
reference to a hash with initially three keys.
In this discussion I sense the tendency to make the whole slice-thing
too sophisticated by mentioning restricted hashes (which renders the
thing useless if the users wants to add elements to the structure later)
or partly lexicalized variables. I am not sure that Jarkko had this in
mind when he asked about it.
Tassilo
--
$_=q#",}])!JAPH!qq(tsuJ[{@"tnirp}3..0}_$;//::niam/s~=)]3[))_$-3(rellac(=_$({
pam{rekcahbus})(rekcah{lrePbus})(lreP{rehtonabus})!JAPH!qq(rehtona{tsuJbus#;
$_=reverse,s+(?<=sub).+q#q!'"qq.\t$&."'!#+sexisexiixesixeseg;y~\n~~dddd;eval
No, I didn't.
I think your take on this makes a lot of sense-- make my HASH work
like my SCALAR/HASH/ARRAY or our/local, the only difference being the
scoping. For example that my HASH; would initialize the hash elements
to undef, that makes perfect sense if compared e.g. with my SCALAR;
or my ARRAY/HASH;
(Note my cunning use of "making perfect sense" instead of "intuitive" :-)
Potential difficulty : if we allow complex expressions to be my()-ed,
define accurately which variables that appear in this expression
are actually declared. For example :
my @h{@k};
is intended to declare %h, but not @k. The 1-line patch I posted earlier
provoked the declaration of both variables. Carefulness is unavoidable.
(and BTW Hugo said he didn't like that feature very much.)
Yes, care must be taken here to define that properly. In my imagination
only one variable can actually be my()ed, and that is the variable that
is sliced (or subscripted). The slice/subscript itself must not be made
a lexical. Your example wouldn't work anyway because when my()ing @k in
the below example
my @k = qw/a b c/;
my @h{ @k };
it would be empty and thus the slice would be empty (also, it would
trigger a "masks earlier declaration" warning).
> (and BTW Hugo said he didn't like that feature very much.)
Yeah, well. Perhaps he likes it a little better once the group sorted
out the exact semantics (and possible implications from that). If this
feature makes it eventually into Perl, it really should be clear and
easy to understand. Once it starts having side-effects or whatever, the
idea should be dropped IMHO.
This was my immediate reaction as well.
my @hash {qw /a b c/};
would mean:
my %hash;
@hash {qw /a b c/} = ();
Just like 'my $x;' sets '$x' to be undefined.
Abigail